hrithik18k/punck-tscircuit-recreation
A four-layer Eurorack drum/sampler controller PCB built around an STM32H743, dual QSPI flash, PCM5100 stereo DAC, TL074 analog audio circuitry, input clamps, 12V-to-3.3V power regulation, MIDI/USB/SWD connectors, controls, LEDs, and trigger/audio I/O.
- Version
- 1.0.3
- License
- unset
- Stars
- 0
dist/index.cjs
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var __create = Object.create;
var __getProtoOf = Object.getPrototypeOf;
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
function __accessProp(key) {
return this[key];
}
var __toESMCache_node;
var __toESM = (mod, isNodeMode, target) => {
var canCache = mod != null && typeof mod === "object";
if (canCache) {
var cache = __toESMCache_node ??= new WeakMap ;
var cached = cache.get(mod);
if (cached)
return cached;
}
target = mod != null ? __create(__getProtoOf(mod)) : {};
const to = __defProp(target, "default", { value: mod, enumerable: true }) ;
for (let key of __getOwnPropNames(mod))
if (!__hasOwnProp.call(to, key))
__defProp(to, key, {
get: __accessProp.bind(mod, key),
enumerable: true
});
if (canCache)
cache.set(mod, to);
return to;
};
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
// node_modules/object-hash/dist/object_hash.js
var require_object_hash = __commonJS((exports, module) => {
(function(e) {
var t;
typeof exports == "object" ? module.exports = e() : typeof define == "function" && define.amd ? define(e) : (typeof window != "undefined" ? t = window : typeof global != "undefined" ? t = global : typeof self != "undefined" && (t = self), t.objectHash = e());
})(function() {
return function r(o, i, u) {
function s(n, e2) {
if (!i[n]) {
if (!o[n]) {
var t = __require;
if (!e2 && t)
return t(n, true);
if (a)
return a(n, true);
throw new Error("Cannot find module '" + n + "'");
}
e2 = i[n] = { exports: {} };
o[n][0].call(e2.exports, function(e3) {
var t2 = o[n][1][e3];
return s(t2 || e3);
}, e2, e2.exports, r, o, i, u);
}
return i[n].exports;
}
for (var a = __require, e = 0;e < u.length; e++)
s(u[e]);
return s;
}({ 1: [function(w, b, m) {
(function(e, n, s, c, d, h, p, g, y) {
var r = w("crypto");
function t(e2, t2) {
t2 = u(e2, t2);
var n2;
return (n2 = t2.algorithm !== "passthrough" ? r.createHash(t2.algorithm) : new l).write === undefined && (n2.write = n2.update, n2.end = n2.update), f(t2, n2).dispatch(e2), n2.update || n2.end(""), n2.digest ? n2.digest(t2.encoding === "buffer" ? undefined : t2.encoding) : (e2 = n2.read(), t2.encoding !== "buffer" ? e2.toString(t2.encoding) : e2);
}
(m = b.exports = t).sha1 = function(e2) {
return t(e2);
}, m.keys = function(e2) {
return t(e2, { excludeValues: true, algorithm: "sha1", encoding: "hex" });
}, m.MD5 = function(e2) {
return t(e2, { algorithm: "md5", encoding: "hex" });
}, m.keysMD5 = function(e2) {
return t(e2, { algorithm: "md5", encoding: "hex", excludeValues: true });
};
var o = r.getHashes ? r.getHashes().slice() : ["sha1", "md5"], i = (o.push("passthrough"), ["buffer", "hex", "binary", "base64"]);
function u(e2, t2) {
var n2 = {};
if (n2.algorithm = (t2 = t2 || {}).algorithm || "sha1", n2.encoding = t2.encoding || "hex", n2.excludeValues = !!t2.excludeValues, n2.algorithm = n2.algorithm.toLowerCase(), n2.encoding = n2.encoding.toLowerCase(), n2.ignoreUnknown = t2.ignoreUnknown === true, n2.respectType = t2.respectType !== false, n2.respectFunctionNames = t2.respectFunctionNames !== false, n2.respectFunctionProperties = t2.respectFunctionProperties !== false, n2.unorderedArrays = t2.unorderedArrays === true, n2.unorderedSets = t2.unorderedSets !== false, n2.unorderedObjects = t2.unorderedObjects !== false, n2.replacer = t2.replacer || undefined, n2.excludeKeys = t2.excludeKeys || undefined, e2 === undefined)
throw new Error("Object argument required.");
for (var r2 = 0;r2 < o.length; ++r2)
o[r2].toLowerCase() === n2.algorithm.toLowerCase() && (n2.algorithm = o[r2]);
if (o.indexOf(n2.algorithm) === -1)
throw new Error('Algorithm "' + n2.algorithm + '" not supported. supported values: ' + o.join(", "));
if (i.indexOf(n2.encoding) === -1 && n2.algorithm !== "passthrough")
throw new Error('Encoding "' + n2.encoding + '" not supported. supported values: ' + i.join(", "));
return n2;
}
function a(e2) {
if (typeof e2 == "function")
return /^function\s+\w*\s*\(\s*\)\s*{\s+\[native code\]\s+}$/i.exec(Function.prototype.toString.call(e2)) != null;
}
function f(o2, t2, i2) {
i2 = i2 || [];
function u2(e2) {
return t2.update ? t2.update(e2, "utf8") : t2.write(e2, "utf8");
}
return { dispatch: function(e2) {
return this["_" + ((e2 = o2.replacer ? o2.replacer(e2) : e2) === null ? "null" : typeof e2)](e2);
}, _object: function(t3) {
var n2, e2 = Object.prototype.toString.call(t3), r2 = /\[object (.*)\]/i.exec(e2);
r2 = (r2 = r2 ? r2[1] : "unknown:[" + e2 + "]").toLowerCase();
if (0 <= (e2 = i2.indexOf(t3)))
return this.dispatch("[CIRCULAR:" + e2 + "]");
if (i2.push(t3), s !== undefined && s.isBuffer && s.isBuffer(t3))
return u2("buffer:"), u2(t3);
if (r2 === "object" || r2 === "function" || r2 === "asyncfunction")
return e2 = Object.keys(t3), o2.unorderedObjects && (e2 = e2.sort()), o2.respectType === false || a(t3) || e2.splice(0, 0, "prototype", "__proto__", "constructor"), o2.excludeKeys && (e2 = e2.filter(function(e3) {
return !o2.excludeKeys(e3);
})), u2("object:" + e2.length + ":"), n2 = this, e2.forEach(function(e3) {
n2.dispatch(e3), u2(":"), o2.excludeValues || n2.dispatch(t3[e3]), u2(",");
});
if (!this["_" + r2]) {
if (o2.ignoreUnknown)
return u2("[" + r2 + "]");
throw new Error('Unknown object type "' + r2 + '"');
}
this["_" + r2](t3);
}, _array: function(e2, t3) {
t3 = t3 !== undefined ? t3 : o2.unorderedArrays !== false;
var n2 = this;
if (u2("array:" + e2.length + ":"), !t3 || e2.length <= 1)
return e2.forEach(function(e3) {
return n2.dispatch(e3);
});
var r2 = [], t3 = e2.map(function(e3) {
var t4 = new l, n3 = i2.slice();
return f(o2, t4, n3).dispatch(e3), r2 = r2.concat(n3.slice(i2.length)), t4.read().toString();
});
return i2 = i2.concat(r2), t3.sort(), this._array(t3, false);
}, _date: function(e2) {
return u2("date:" + e2.toJSON());
}, _symbol: function(e2) {
return u2("symbol:" + e2.toString());
}, _error: function(e2) {
return u2("error:" + e2.toString());
}, _boolean: function(e2) {
return u2("bool:" + e2.toString());
}, _string: function(e2) {
u2("string:" + e2.length + ":"), u2(e2.toString());
}, _function: function(e2) {
u2("fn:"), a(e2) ? this.dispatch("[native]") : this.dispatch(e2.toString()), o2.respectFunctionNames !== false && this.dispatch("function-name:" + String(e2.name)), o2.respectFunctionProperties && this._object(e2);
}, _number: function(e2) {
return u2("number:" + e2.toString());
}, _xml: function(e2) {
return u2("xml:" + e2.toString());
}, _null: function() {
return u2("Null");
}, _undefined: function() {
return u2("Undefined");
}, _regexp: function(e2) {
return u2("regex:" + e2.toString());
}, _uint8array: function(e2) {
return u2("uint8array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _uint8clampedarray: function(e2) {
return u2("uint8clampedarray:"), this.dispatch(Array.prototype.slice.call(e2));
}, _int8array: function(e2) {
return u2("int8array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _uint16array: function(e2) {
return u2("uint16array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _int16array: function(e2) {
return u2("int16array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _uint32array: function(e2) {
return u2("uint32array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _int32array: function(e2) {
return u2("int32array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _float32array: function(e2) {
return u2("float32array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _float64array: function(e2) {
return u2("float64array:"), this.dispatch(Array.prototype.slice.call(e2));
}, _arraybuffer: function(e2) {
return u2("arraybuffer:"), this.dispatch(new Uint8Array(e2));
}, _url: function(e2) {
return u2("url:" + e2.toString());
}, _map: function(e2) {
u2("map:");
e2 = Array.from(e2);
return this._array(e2, o2.unorderedSets !== false);
}, _set: function(e2) {
u2("set:");
e2 = Array.from(e2);
return this._array(e2, o2.unorderedSets !== false);
}, _file: function(e2) {
return u2("file:"), this.dispatch([e2.name, e2.size, e2.type, e2.lastModfied]);
}, _blob: function() {
if (o2.ignoreUnknown)
return u2("[blob]");
throw Error(`Hashing Blob objects is currently not supported
(see https://github.com/puleos/object-hash/issues/26)
Use "options.replacer" or "options.ignoreUnknown"
`);
}, _domwindow: function() {
return u2("domwindow");
}, _bigint: function(e2) {
return u2("bigint:" + e2.toString());
}, _process: function() {
return u2("process");
}, _timer: function() {
return u2("timer");
}, _pipe: function() {
return u2("pipe");
}, _tcp: function() {
return u2("tcp");
}, _udp: function() {
return u2("udp");
}, _tty: function() {
return u2("tty");
}, _statwatcher: function() {
return u2("statwatcher");
}, _securecontext: function() {
return u2("securecontext");
}, _connection: function() {
return u2("connection");
}, _zlib: function() {
return u2("zlib");
}, _context: function() {
return u2("context");
}, _nodescript: function() {
return u2("nodescript");
}, _httpparser: function() {
return u2("httpparser");
}, _dataview: function() {
return u2("dataview");
}, _signal: function() {
return u2("signal");
}, _fsevent: function() {
return u2("fsevent");
}, _tlswrap: function() {
return u2("tlswrap");
} };
}
function l() {
return { buf: "", write: function(e2) {
this.buf += e2;
}, end: function(e2) {
this.buf += e2;
}, read: function() {
return this.buf;
} };
}
m.writeToStream = function(e2, t2, n2) {
return n2 === undefined && (n2 = t2, t2 = {}), f(t2 = u(e2, t2), n2).dispatch(e2);
};
}).call(this, w("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, w("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/fake_9a5aa49d.js", "/");
}, { buffer: 3, crypto: 5, lYpoI2: 11 }], 2: [function(e, t, f) {
(function(e2, t2, n, r, o, i, u, s, a) {
(function(e3) {
var a2 = typeof Uint8Array != "undefined" ? Uint8Array : Array, t3 = 43, n2 = 47, r2 = 48, o2 = 97, i2 = 65, u2 = 45, s2 = 95;
function f2(e4) {
e4 = e4.charCodeAt(0);
return e4 === t3 || e4 === u2 ? 62 : e4 === n2 || e4 === s2 ? 63 : e4 < r2 ? -1 : e4 < r2 + 10 ? e4 - r2 + 26 + 26 : e4 < i2 + 26 ? e4 - i2 : e4 < o2 + 26 ? e4 - o2 + 26 : undefined;
}
e3.toByteArray = function(e4) {
var t4, n3;
if (0 < e4.length % 4)
throw new Error("Invalid string. Length must be a multiple of 4");
var r3 = e4.length, r3 = e4.charAt(r3 - 2) === "=" ? 2 : e4.charAt(r3 - 1) === "=" ? 1 : 0, o3 = new a2(3 * e4.length / 4 - r3), i3 = 0 < r3 ? e4.length - 4 : e4.length, u3 = 0;
function s3(e5) {
o3[u3++] = e5;
}
for (t4 = 0;t4 < i3; t4 += 4, 0)
s3((16711680 & (n3 = f2(e4.charAt(t4)) << 18 | f2(e4.charAt(t4 + 1)) << 12 | f2(e4.charAt(t4 + 2)) << 6 | f2(e4.charAt(t4 + 3)))) >> 16), s3((65280 & n3) >> 8), s3(255 & n3);
return r3 == 2 ? s3(255 & (n3 = f2(e4.charAt(t4)) << 2 | f2(e4.charAt(t4 + 1)) >> 4)) : r3 == 1 && (s3((n3 = f2(e4.charAt(t4)) << 10 | f2(e4.charAt(t4 + 1)) << 4 | f2(e4.charAt(t4 + 2)) >> 2) >> 8 & 255), s3(255 & n3)), o3;
}, e3.fromByteArray = function(e4) {
var t4, n3, r3, o3, i3 = e4.length % 3, u3 = "";
function s3(e5) {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(e5);
}
for (t4 = 0, r3 = e4.length - i3;t4 < r3; t4 += 3)
n3 = (e4[t4] << 16) + (e4[t4 + 1] << 8) + e4[t4 + 2], u3 += s3((o3 = n3) >> 18 & 63) + s3(o3 >> 12 & 63) + s3(o3 >> 6 & 63) + s3(63 & o3);
switch (i3) {
case 1:
u3 = (u3 += s3((n3 = e4[e4.length - 1]) >> 2)) + s3(n3 << 4 & 63) + "==";
break;
case 2:
u3 = (u3 = (u3 += s3((n3 = (e4[e4.length - 2] << 8) + e4[e4.length - 1]) >> 10)) + s3(n3 >> 4 & 63)) + s3(n3 << 2 & 63) + "=";
}
return u3;
};
})(f === undefined ? this.base64js = {} : f);
}).call(this, e("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, e("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/base64-js/lib/b64.js", "/node_modules/gulp-browserify/node_modules/base64-js/lib");
}, { buffer: 3, lYpoI2: 11 }], 3: [function(O, e, H) {
(function(e2, n, f, r, h, p, g, y, w) {
var a = O("base64-js"), i = O("ieee754");
function f(e3, t2, n2) {
if (!(this instanceof f))
return new f(e3, t2, n2);
var r2, o2, i2, u2, s2 = typeof e3;
if (t2 === "base64" && s2 == "string")
for (e3 = (u2 = e3).trim ? u2.trim() : u2.replace(/^\s+|\s+$/g, "");e3.length % 4 != 0; )
e3 += "=";
if (s2 == "number")
r2 = j(e3);
else if (s2 == "string")
r2 = f.byteLength(e3, t2);
else {
if (s2 != "object")
throw new Error("First argument needs to be a number, array or string.");
r2 = j(e3.length);
}
if (f._useTypedArrays ? o2 = f._augment(new Uint8Array(r2)) : ((o2 = this).length = r2, o2._isBuffer = true), f._useTypedArrays && typeof e3.byteLength == "number")
o2._set(e3);
else if (C(u2 = e3) || f.isBuffer(u2) || u2 && typeof u2 == "object" && typeof u2.length == "number")
for (i2 = 0;i2 < r2; i2++)
f.isBuffer(e3) ? o2[i2] = e3.readUInt8(i2) : o2[i2] = e3[i2];
else if (s2 == "string")
o2.write(e3, 0, t2);
else if (s2 == "number" && !f._useTypedArrays && !n2)
for (i2 = 0;i2 < r2; i2++)
o2[i2] = 0;
return o2;
}
function b(e3, t2, n2, r2) {
return f._charsWritten = c(function(e4) {
for (var t3 = [], n3 = 0;n3 < e4.length; n3++)
t3.push(255 & e4.charCodeAt(n3));
return t3;
}(t2), e3, n2, r2);
}
function m(e3, t2, n2, r2) {
return f._charsWritten = c(function(e4) {
for (var t3, n3, r3 = [], o2 = 0;o2 < e4.length; o2++)
n3 = e4.charCodeAt(o2), t3 = n3 >> 8, n3 = n3 % 256, r3.push(n3), r3.push(t3);
return r3;
}(t2), e3, n2, r2);
}
function v(e3, t2, n2) {
var r2 = "";
n2 = Math.min(e3.length, n2);
for (var o2 = t2;o2 < n2; o2++)
r2 += String.fromCharCode(e3[o2]);
return r2;
}
function o(e3, t2, n2, r2) {
r2 || (d(typeof n2 == "boolean", "missing or invalid endian"), d(t2 != null, "missing offset"), d(t2 + 1 < e3.length, "Trying to read beyond buffer length"));
var o2, r2 = e3.length;
if (!(r2 <= t2))
return n2 ? (o2 = e3[t2], t2 + 1 < r2 && (o2 |= e3[t2 + 1] << 8)) : (o2 = e3[t2] << 8, t2 + 1 < r2 && (o2 |= e3[t2 + 1])), o2;
}
function u(e3, t2, n2, r2) {
r2 || (d(typeof n2 == "boolean", "missing or invalid endian"), d(t2 != null, "missing offset"), d(t2 + 3 < e3.length, "Trying to read beyond buffer length"));
var o2, r2 = e3.length;
if (!(r2 <= t2))
return n2 ? (t2 + 2 < r2 && (o2 = e3[t2 + 2] << 16), t2 + 1 < r2 && (o2 |= e3[t2 + 1] << 8), o2 |= e3[t2], t2 + 3 < r2 && (o2 += e3[t2 + 3] << 24 >>> 0)) : (t2 + 1 < r2 && (o2 = e3[t2 + 1] << 16), t2 + 2 < r2 && (o2 |= e3[t2 + 2] << 8), t2 + 3 < r2 && (o2 |= e3[t2 + 3]), o2 += e3[t2] << 24 >>> 0), o2;
}
function _(e3, t2, n2, r2) {
if (r2 || (d(typeof n2 == "boolean", "missing or invalid endian"), d(t2 != null, "missing offset"), d(t2 + 1 < e3.length, "Trying to read beyond buffer length")), !(e3.length <= t2))
return r2 = o(e3, t2, n2, true), 32768 & r2 ? -1 * (65535 - r2 + 1) : r2;
}
function E(e3, t2, n2, r2) {
if (r2 || (d(typeof n2 == "boolean", "missing or invalid endian"), d(t2 != null, "missing offset"), d(t2 + 3 < e3.length, "Trying to read beyond buffer length")), !(e3.length <= t2))
return r2 = u(e3, t2, n2, true), 2147483648 & r2 ? -1 * (4294967295 - r2 + 1) : r2;
}
function I(e3, t2, n2, r2) {
return r2 || (d(typeof n2 == "boolean", "missing or invalid endian"), d(t2 + 3 < e3.length, "Trying to read beyond buffer length")), i.read(e3, t2, n2, 23, 4);
}
function A(e3, t2, n2, r2) {
return r2 || (d(typeof n2 == "boolean", "missing or invalid endian"), d(t2 + 7 < e3.length, "Trying to read beyond buffer length")), i.read(e3, t2, n2, 52, 8);
}
function s(e3, t2, n2, r2, o2) {
o2 || (d(t2 != null, "missing value"), d(typeof r2 == "boolean", "missing or invalid endian"), d(n2 != null, "missing offset"), d(n2 + 1 < e3.length, "trying to write beyond buffer length"), Y(t2, 65535));
o2 = e3.length;
if (!(o2 <= n2))
for (var i2 = 0, u2 = Math.min(o2 - n2, 2);i2 < u2; i2++)
e3[n2 + i2] = (t2 & 255 << 8 * (r2 ? i2 : 1 - i2)) >>> 8 * (r2 ? i2 : 1 - i2);
}
function l(e3, t2, n2, r2, o2) {
o2 || (d(t2 != null, "missing value"), d(typeof r2 == "boolean", "missing or invalid endian"), d(n2 != null, "missing offset"), d(n2 + 3 < e3.length, "trying to write beyond buffer length"), Y(t2, 4294967295));
o2 = e3.length;
if (!(o2 <= n2))
for (var i2 = 0, u2 = Math.min(o2 - n2, 4);i2 < u2; i2++)
e3[n2 + i2] = t2 >>> 8 * (r2 ? i2 : 3 - i2) & 255;
}
function B(e3, t2, n2, r2, o2) {
o2 || (d(t2 != null, "missing value"), d(typeof r2 == "boolean", "missing or invalid endian"), d(n2 != null, "missing offset"), d(n2 + 1 < e3.length, "Trying to write beyond buffer length"), F(t2, 32767, -32768)), e3.length <= n2 || s(e3, 0 <= t2 ? t2 : 65535 + t2 + 1, n2, r2, o2);
}
function L(e3, t2, n2, r2, o2) {
o2 || (d(t2 != null, "missing value"), d(typeof r2 == "boolean", "missing or invalid endian"), d(n2 != null, "missing offset"), d(n2 + 3 < e3.length, "Trying to write beyond buffer length"), F(t2, 2147483647, -2147483648)), e3.length <= n2 || l(e3, 0 <= t2 ? t2 : 4294967295 + t2 + 1, n2, r2, o2);
}
function U(e3, t2, n2, r2, o2) {
o2 || (d(t2 != null, "missing value"), d(typeof r2 == "boolean", "missing or invalid endian"), d(n2 != null, "missing offset"), d(n2 + 3 < e3.length, "Trying to write beyond buffer length"), D(t2, 340282346638528860000000000000000000000, -34028234663852886e22)), e3.length <= n2 || i.write(e3, t2, n2, r2, 23, 4);
}
function x(e3, t2, n2, r2, o2) {
o2 || (d(t2 != null, "missing value"), d(typeof r2 == "boolean", "missing or invalid endian"), d(n2 != null, "missing offset"), d(n2 + 7 < e3.length, "Trying to write beyond buffer length"), D(t2, 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, -17976931348623157e292)), e3.length <= n2 || i.write(e3, t2, n2, r2, 52, 8);
}
H.Buffer = f, H.SlowBuffer = f, H.INSPECT_MAX_BYTES = 50, f.poolSize = 8192, f._useTypedArrays = function() {
try {
var e3 = new ArrayBuffer(0), t2 = new Uint8Array(e3);
return t2.foo = function() {
return 42;
}, t2.foo() === 42 && typeof t2.subarray == "function";
} catch (e4) {
return false;
}
}(), f.isEncoding = function(e3) {
switch (String(e3).toLowerCase()) {
case "hex":
case "utf8":
case "utf-8":
case "ascii":
case "binary":
case "base64":
case "raw":
case "ucs2":
case "ucs-2":
case "utf16le":
case "utf-16le":
return true;
default:
return false;
}
}, f.isBuffer = function(e3) {
return !(e3 == null || !e3._isBuffer);
}, f.byteLength = function(e3, t2) {
var n2;
switch (e3 += "", t2 || "utf8") {
case "hex":
n2 = e3.length / 2;
break;
case "utf8":
case "utf-8":
n2 = T(e3).length;
break;
case "ascii":
case "binary":
case "raw":
n2 = e3.length;
break;
case "base64":
n2 = M(e3).length;
break;
case "ucs2":
case "ucs-2":
case "utf16le":
case "utf-16le":
n2 = 2 * e3.length;
break;
default:
throw new Error("Unknown encoding");
}
return n2;
}, f.concat = function(e3, t2) {
if (d(C(e3), `Usage: Buffer.concat(list, [totalLength])
list should be an Array.`), e3.length === 0)
return new f(0);
if (e3.length === 1)
return e3[0];
if (typeof t2 != "number")
for (o2 = t2 = 0;o2 < e3.length; o2++)
t2 += e3[o2].length;
for (var n2 = new f(t2), r2 = 0, o2 = 0;o2 < e3.length; o2++) {
var i2 = e3[o2];
i2.copy(n2, r2), r2 += i2.length;
}
return n2;
}, f.prototype.write = function(e3, t2, n2, r2) {
isFinite(t2) ? isFinite(n2) || (r2 = n2, n2 = undefined) : (a2 = r2, r2 = t2, t2 = n2, n2 = a2), t2 = Number(t2) || 0;
var o2, i2, u2, s2, a2 = this.length - t2;
switch ((!n2 || a2 < (n2 = Number(n2))) && (n2 = a2), r2 = String(r2 || "utf8").toLowerCase()) {
case "hex":
o2 = function(e4, t3, n3, r3) {
n3 = Number(n3) || 0;
var o3 = e4.length - n3;
(!r3 || o3 < (r3 = Number(r3))) && (r3 = o3), d((o3 = t3.length) % 2 == 0, "Invalid hex string"), o3 / 2 < r3 && (r3 = o3 / 2);
for (var i3 = 0;i3 < r3; i3++) {
var u3 = parseInt(t3.substr(2 * i3, 2), 16);
d(!isNaN(u3), "Invalid hex string"), e4[n3 + i3] = u3;
}
return f._charsWritten = 2 * i3, i3;
}(this, e3, t2, n2);
break;
case "utf8":
case "utf-8":
i2 = this, u2 = t2, s2 = n2, o2 = f._charsWritten = c(T(e3), i2, u2, s2);
break;
case "ascii":
case "binary":
o2 = b(this, e3, t2, n2);
break;
case "base64":
i2 = this, u2 = t2, s2 = n2, o2 = f._charsWritten = c(M(e3), i2, u2, s2);
break;
case "ucs2":
case "ucs-2":
case "utf16le":
case "utf-16le":
o2 = m(this, e3, t2, n2);
break;
default:
throw new Error("Unknown encoding");
}
return o2;
}, f.prototype.toString = function(e3, t2, n2) {
var r2, o2, i2, u2, s2 = this;
if (e3 = String(e3 || "utf8").toLowerCase(), t2 = Number(t2) || 0, (n2 = n2 !== undefined ? Number(n2) : s2.length) === t2)
return "";
switch (e3) {
case "hex":
r2 = function(e4, t3, n3) {
var r3 = e4.length;
(!t3 || t3 < 0) && (t3 = 0);
(!n3 || n3 < 0 || r3 < n3) && (n3 = r3);
for (var o3 = "", i3 = t3;i3 < n3; i3++)
o3 += k(e4[i3]);
return o3;
}(s2, t2, n2);
break;
case "utf8":
case "utf-8":
r2 = function(e4, t3, n3) {
var r3 = "", o3 = "";
n3 = Math.min(e4.length, n3);
for (var i3 = t3;i3 < n3; i3++)
e4[i3] <= 127 ? (r3 += N(o3) + String.fromCharCode(e4[i3]), o3 = "") : o3 += "%" + e4[i3].toString(16);
return r3 + N(o3);
}(s2, t2, n2);
break;
case "ascii":
case "binary":
r2 = v(s2, t2, n2);
break;
case "base64":
o2 = s2, u2 = n2, r2 = (i2 = t2) === 0 && u2 === o2.length ? a.fromByteArray(o2) : a.fromByteArray(o2.slice(i2, u2));
break;
case "ucs2":
case "ucs-2":
case "utf16le":
case "utf-16le":
r2 = function(e4, t3, n3) {
for (var r3 = e4.slice(t3, n3), o3 = "", i3 = 0;i3 < r3.length; i3 += 2)
o3 += String.fromCharCode(r3[i3] + 256 * r3[i3 + 1]);
return o3;
}(s2, t2, n2);
break;
default:
throw new Error("Unknown encoding");
}
return r2;
}, f.prototype.toJSON = function() {
return { type: "Buffer", data: Array.prototype.slice.call(this._arr || this, 0) };
}, f.prototype.copy = function(e3, t2, n2, r2) {
if (t2 = t2 || 0, (r2 = r2 || r2 === 0 ? r2 : this.length) !== (n2 = n2 || 0) && e3.length !== 0 && this.length !== 0) {
d(n2 <= r2, "sourceEnd < sourceStart"), d(0 <= t2 && t2 < e3.length, "targetStart out of bounds"), d(0 <= n2 && n2 < this.length, "sourceStart out of bounds"), d(0 <= r2 && r2 <= this.length, "sourceEnd out of bounds"), r2 > this.length && (r2 = this.length);
var o2 = (r2 = e3.length - t2 < r2 - n2 ? e3.length - t2 + n2 : r2) - n2;
if (o2 < 100 || !f._useTypedArrays)
for (var i2 = 0;i2 < o2; i2++)
e3[i2 + t2] = this[i2 + n2];
else
e3._set(this.subarray(n2, n2 + o2), t2);
}
}, f.prototype.slice = function(e3, t2) {
var n2 = this.length;
if (e3 = S(e3, n2, 0), t2 = S(t2, n2, n2), f._useTypedArrays)
return f._augment(this.subarray(e3, t2));
for (var r2 = t2 - e3, o2 = new f(r2, undefined, true), i2 = 0;i2 < r2; i2++)
o2[i2] = this[i2 + e3];
return o2;
}, f.prototype.get = function(e3) {
return console.log(".get() is deprecated. Access using array indexes instead."), this.readUInt8(e3);
}, f.prototype.set = function(e3, t2) {
return console.log(".set() is deprecated. Access using array indexes instead."), this.writeUInt8(e3, t2);
}, f.prototype.readUInt8 = function(e3, t2) {
if (t2 || (d(e3 != null, "missing offset"), d(e3 < this.length, "Trying to read beyond buffer length")), !(e3 >= this.length))
return this[e3];
}, f.prototype.readUInt16LE = function(e3, t2) {
return o(this, e3, true, t2);
}, f.prototype.readUInt16BE = function(e3, t2) {
return o(this, e3, false, t2);
}, f.prototype.readUInt32LE = function(e3, t2) {
return u(this, e3, true, t2);
}, f.prototype.readUInt32BE = function(e3, t2) {
return u(this, e3, false, t2);
}, f.prototype.readInt8 = function(e3, t2) {
if (t2 || (d(e3 != null, "missing offset"), d(e3 < this.length, "Trying to read beyond buffer length")), !(e3 >= this.length))
return 128 & this[e3] ? -1 * (255 - this[e3] + 1) : this[e3];
}, f.prototype.readInt16LE = function(e3, t2) {
return _(this, e3, true, t2);
}, f.prototype.readInt16BE = function(e3, t2) {
return _(this, e3, false, t2);
}, f.prototype.readInt32LE = function(e3, t2) {
return E(this, e3, true, t2);
}, f.prototype.readInt32BE = function(e3, t2) {
return E(this, e3, false, t2);
}, f.prototype.readFloatLE = function(e3, t2) {
return I(this, e3, true, t2);
}, f.prototype.readFloatBE = function(e3, t2) {
return I(this, e3, false, t2);
}, f.prototype.readDoubleLE = function(e3, t2) {
return A(this, e3, true, t2);
}, f.prototype.readDoubleBE = function(e3, t2) {
return A(this, e3, false, t2);
}, f.prototype.writeUInt8 = function(e3, t2, n2) {
n2 || (d(e3 != null, "missing value"), d(t2 != null, "missing offset"), d(t2 < this.length, "trying to write beyond buffer length"), Y(e3, 255)), t2 >= this.length || (this[t2] = e3);
}, f.prototype.writeUInt16LE = function(e3, t2, n2) {
s(this, e3, t2, true, n2);
}, f.prototype.writeUInt16BE = function(e3, t2, n2) {
s(this, e3, t2, false, n2);
}, f.prototype.writeUInt32LE = function(e3, t2, n2) {
l(this, e3, t2, true, n2);
}, f.prototype.writeUInt32BE = function(e3, t2, n2) {
l(this, e3, t2, false, n2);
}, f.prototype.writeInt8 = function(e3, t2, n2) {
n2 || (d(e3 != null, "missing value"), d(t2 != null, "missing offset"), d(t2 < this.length, "Trying to write beyond buffer length"), F(e3, 127, -128)), t2 >= this.length || (0 <= e3 ? this.writeUInt8(e3, t2, n2) : this.writeUInt8(255 + e3 + 1, t2, n2));
}, f.prototype.writeInt16LE = function(e3, t2, n2) {
B(this, e3, t2, true, n2);
}, f.prototype.writeInt16BE = function(e3, t2, n2) {
B(this, e3, t2, false, n2);
}, f.prototype.writeInt32LE = function(e3, t2, n2) {
L(this, e3, t2, true, n2);
}, f.prototype.writeInt32BE = function(e3, t2, n2) {
L(this, e3, t2, false, n2);
}, f.prototype.writeFloatLE = function(e3, t2, n2) {
U(this, e3, t2, true, n2);
}, f.prototype.writeFloatBE = function(e3, t2, n2) {
U(this, e3, t2, false, n2);
}, f.prototype.writeDoubleLE = function(e3, t2, n2) {
x(this, e3, t2, true, n2);
}, f.prototype.writeDoubleBE = function(e3, t2, n2) {
x(this, e3, t2, false, n2);
}, f.prototype.fill = function(e3, t2, n2) {
if (t2 = t2 || 0, n2 = n2 || this.length, d(typeof (e3 = typeof (e3 = e3 || 0) == "string" ? e3.charCodeAt(0) : e3) == "number" && !isNaN(e3), "value is not a number"), d(t2 <= n2, "end < start"), n2 !== t2 && this.length !== 0) {
d(0 <= t2 && t2 < this.length, "start out of bounds"), d(0 <= n2 && n2 <= this.length, "end out of bounds");
for (var r2 = t2;r2 < n2; r2++)
this[r2] = e3;
}
}, f.prototype.inspect = function() {
for (var e3 = [], t2 = this.length, n2 = 0;n2 < t2; n2++)
if (e3[n2] = k(this[n2]), n2 === H.INSPECT_MAX_BYTES) {
e3[n2 + 1] = "...";
break;
}
return "<Buffer " + e3.join(" ") + ">";
}, f.prototype.toArrayBuffer = function() {
if (typeof Uint8Array == "undefined")
throw new Error("Buffer.toArrayBuffer not supported in this browser");
if (f._useTypedArrays)
return new f(this).buffer;
for (var e3 = new Uint8Array(this.length), t2 = 0, n2 = e3.length;t2 < n2; t2 += 1)
e3[t2] = this[t2];
return e3.buffer;
};
var t = f.prototype;
function S(e3, t2, n2) {
return typeof e3 != "number" ? n2 : t2 <= (e3 = ~~e3) ? t2 : 0 <= e3 || 0 <= (e3 += t2) ? e3 : 0;
}
function j(e3) {
return (e3 = ~~Math.ceil(+e3)) < 0 ? 0 : e3;
}
function C(e3) {
return (Array.isArray || function(e4) {
return Object.prototype.toString.call(e4) === "[object Array]";
})(e3);
}
function k(e3) {
return e3 < 16 ? "0" + e3.toString(16) : e3.toString(16);
}
function T(e3) {
for (var t2 = [], n2 = 0;n2 < e3.length; n2++) {
var r2 = e3.charCodeAt(n2);
if (r2 <= 127)
t2.push(e3.charCodeAt(n2));
else
for (var o2 = n2, i2 = (55296 <= r2 && r2 <= 57343 && n2++, encodeURIComponent(e3.slice(o2, n2 + 1)).substr(1).split("%")), u2 = 0;u2 < i2.length; u2++)
t2.push(parseInt(i2[u2], 16));
}
return t2;
}
function M(e3) {
return a.toByteArray(e3);
}
function c(e3, t2, n2, r2) {
for (var o2 = 0;o2 < r2 && !(o2 + n2 >= t2.length || o2 >= e3.length); o2++)
t2[o2 + n2] = e3[o2];
return o2;
}
function N(e3) {
try {
return decodeURIComponent(e3);
} catch (e4) {
return String.fromCharCode(65533);
}
}
function Y(e3, t2) {
d(typeof e3 == "number", "cannot write a non-number as a number"), d(0 <= e3, "specified a negative value for writing an unsigned value"), d(e3 <= t2, "value is larger than maximum value for type"), d(Math.floor(e3) === e3, "value has a fractional component");
}
function F(e3, t2, n2) {
d(typeof e3 == "number", "cannot write a non-number as a number"), d(e3 <= t2, "value larger than maximum allowed value"), d(n2 <= e3, "value smaller than minimum allowed value"), d(Math.floor(e3) === e3, "value has a fractional component");
}
function D(e3, t2, n2) {
d(typeof e3 == "number", "cannot write a non-number as a number"), d(e3 <= t2, "value larger than maximum allowed value"), d(n2 <= e3, "value smaller than minimum allowed value");
}
function d(e3, t2) {
if (!e3)
throw new Error(t2 || "Failed assertion");
}
f._augment = function(e3) {
return e3._isBuffer = true, e3._get = e3.get, e3._set = e3.set, e3.get = t.get, e3.set = t.set, e3.write = t.write, e3.toString = t.toString, e3.toLocaleString = t.toString, e3.toJSON = t.toJSON, e3.copy = t.copy, e3.slice = t.slice, e3.readUInt8 = t.readUInt8, e3.readUInt16LE = t.readUInt16LE, e3.readUInt16BE = t.readUInt16BE, e3.readUInt32LE = t.readUInt32LE, e3.readUInt32BE = t.readUInt32BE, e3.readInt8 = t.readInt8, e3.readInt16LE = t.readInt16LE, e3.readInt16BE = t.readInt16BE, e3.readInt32LE = t.readInt32LE, e3.readInt32BE = t.readInt32BE, e3.readFloatLE = t.readFloatLE, e3.readFloatBE = t.readFloatBE, e3.readDoubleLE = t.readDoubleLE, e3.readDoubleBE = t.readDoubleBE, e3.writeUInt8 = t.writeUInt8, e3.writeUInt16LE = t.writeUInt16LE, e3.writeUInt16BE = t.writeUInt16BE, e3.writeUInt32LE = t.writeUInt32LE, e3.writeUInt32BE = t.writeUInt32BE, e3.writeInt8 = t.writeInt8, e3.writeInt16LE = t.writeInt16LE, e3.writeInt16BE = t.writeInt16BE, e3.writeInt32LE = t.writeInt32LE, e3.writeInt32BE = t.writeInt32BE, e3.writeFloatLE = t.writeFloatLE, e3.writeFloatBE = t.writeFloatBE, e3.writeDoubleLE = t.writeDoubleLE, e3.writeDoubleBE = t.writeDoubleBE, e3.fill = t.fill, e3.inspect = t.inspect, e3.toArrayBuffer = t.toArrayBuffer, e3;
};
}).call(this, O("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, O("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/buffer/index.js", "/node_modules/gulp-browserify/node_modules/buffer");
}, { "base64-js": 2, buffer: 3, ieee754: 10, lYpoI2: 11 }], 4: [function(c, d, e) {
(function(e2, t, a, n, r, o, i, u, s) {
var a = c("buffer").Buffer, f = 4, l = new a(f);
l.fill(0);
d.exports = { hash: function(e3, t2, n2, r2) {
for (var o2 = t2(function(e4, t3) {
e4.length % f != 0 && (n3 = e4.length + (f - e4.length % f), e4 = a.concat([e4, l], n3));
for (var n3, r3 = [], o3 = t3 ? e4.readInt32BE : e4.readInt32LE, i3 = 0;i3 < e4.length; i3 += f)
r3.push(o3.call(e4, i3));
return r3;
}(e3 = a.isBuffer(e3) ? e3 : new a(e3), r2), 8 * e3.length), t2 = r2, i2 = new a(n2), u2 = t2 ? i2.writeInt32BE : i2.writeInt32LE, s2 = 0;s2 < o2.length; s2++)
u2.call(i2, o2[s2], 4 * s2, true);
return i2;
} };
}).call(this, c("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, c("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/crypto-browserify/helpers.js", "/node_modules/gulp-browserify/node_modules/crypto-browserify");
}, { buffer: 3, lYpoI2: 11 }], 5: [function(v, e, _) {
(function(l, c, u, d, h, p, g, y, w) {
var u = v("buffer").Buffer, e2 = v("./sha"), t = v("./sha256"), n = v("./rng"), b = { sha1: e2, sha256: t, md5: v("./md5") }, s = 64, a = new u(s);
function r(e3, n2) {
var r2 = b[e3 = e3 || "sha1"], o2 = [];
return r2 || i("algorithm:", e3, "is not yet supported"), { update: function(e4) {
return u.isBuffer(e4) || (e4 = new u(e4)), o2.push(e4), e4.length, this;
}, digest: function(e4) {
var t2 = u.concat(o2), t2 = n2 ? function(e5, t3, n3) {
u.isBuffer(t3) || (t3 = new u(t3)), u.isBuffer(n3) || (n3 = new u(n3)), t3.length > s ? t3 = e5(t3) : t3.length < s && (t3 = u.concat([t3, a], s));
for (var r3 = new u(s), o3 = new u(s), i2 = 0;i2 < s; i2++)
r3[i2] = 54 ^ t3[i2], o3[i2] = 92 ^ t3[i2];
return n3 = e5(u.concat([r3, n3])), e5(u.concat([o3, n3]));
}(r2, n2, t2) : r2(t2);
return o2 = null, e4 ? t2.toString(e4) : t2;
} };
}
function i() {
var e3 = [].slice.call(arguments).join(" ");
throw new Error([e3, "we accept pull requests", "http://github.com/dominictarr/crypto-browserify"].join(`
`));
}
a.fill(0), _.createHash = function(e3) {
return r(e3);
}, _.createHmac = r, _.randomBytes = function(e3, t2) {
if (!t2 || !t2.call)
return new u(n(e3));
try {
t2.call(this, undefined, new u(n(e3)));
} catch (e4) {
t2(e4);
}
};
var o, f = ["createCredentials", "createCipher", "createCipheriv", "createDecipher", "createDecipheriv", "createSign", "createVerify", "createDiffieHellman", "pbkdf2"], m = function(e3) {
_[e3] = function() {
i("sorry,", e3, "is not implemented yet");
};
};
for (o in f)
m(f[o]);
}).call(this, v("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, v("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/crypto-browserify/index.js", "/node_modules/gulp-browserify/node_modules/crypto-browserify");
}, { "./md5": 6, "./rng": 7, "./sha": 8, "./sha256": 9, buffer: 3, lYpoI2: 11 }], 6: [function(w, b, e) {
(function(e2, r, o, i, u, a, f, l, y) {
var t = w("./helpers");
function n(e3, t2) {
e3[t2 >> 5] |= 128 << t2 % 32, e3[14 + (t2 + 64 >>> 9 << 4)] = t2;
for (var n2 = 1732584193, r2 = -271733879, o2 = -1732584194, i2 = 271733878, u2 = 0;u2 < e3.length; u2 += 16) {
var s2 = n2, a2 = r2, f2 = o2, l2 = i2, n2 = c(n2, r2, o2, i2, e3[u2 + 0], 7, -680876936), i2 = c(i2, n2, r2, o2, e3[u2 + 1], 12, -389564586), o2 = c(o2, i2, n2, r2, e3[u2 + 2], 17, 606105819), r2 = c(r2, o2, i2, n2, e3[u2 + 3], 22, -1044525330);
n2 = c(n2, r2, o2, i2, e3[u2 + 4], 7, -176418897), i2 = c(i2, n2, r2, o2, e3[u2 + 5], 12, 1200080426), o2 = c(o2, i2, n2, r2, e3[u2 + 6], 17, -1473231341), r2 = c(r2, o2, i2, n2, e3[u2 + 7], 22, -45705983), n2 = c(n2, r2, o2, i2, e3[u2 + 8], 7, 1770035416), i2 = c(i2, n2, r2, o2, e3[u2 + 9], 12, -1958414417), o2 = c(o2, i2, n2, r2, e3[u2 + 10], 17, -42063), r2 = c(r2, o2, i2, n2, e3[u2 + 11], 22, -1990404162), n2 = c(n2, r2, o2, i2, e3[u2 + 12], 7, 1804603682), i2 = c(i2, n2, r2, o2, e3[u2 + 13], 12, -40341101), o2 = c(o2, i2, n2, r2, e3[u2 + 14], 17, -1502002290), n2 = d(n2, r2 = c(r2, o2, i2, n2, e3[u2 + 15], 22, 1236535329), o2, i2, e3[u2 + 1], 5, -165796510), i2 = d(i2, n2, r2, o2, e3[u2 + 6], 9, -1069501632), o2 = d(o2, i2, n2, r2, e3[u2 + 11], 14, 643717713), r2 = d(r2, o2, i2, n2, e3[u2 + 0], 20, -373897302), n2 = d(n2, r2, o2, i2, e3[u2 + 5], 5, -701558691), i2 = d(i2, n2, r2, o2, e3[u2 + 10], 9, 38016083), o2 = d(o2, i2, n2, r2, e3[u2 + 15], 14, -660478335), r2 = d(r2, o2, i2, n2, e3[u2 + 4], 20, -405537848), n2 = d(n2, r2, o2, i2, e3[u2 + 9], 5, 568446438), i2 = d(i2, n2, r2, o2, e3[u2 + 14], 9, -1019803690), o2 = d(o2, i2, n2, r2, e3[u2 + 3], 14, -187363961), r2 = d(r2, o2, i2, n2, e3[u2 + 8], 20, 1163531501), n2 = d(n2, r2, o2, i2, e3[u2 + 13], 5, -1444681467), i2 = d(i2, n2, r2, o2, e3[u2 + 2], 9, -51403784), o2 = d(o2, i2, n2, r2, e3[u2 + 7], 14, 1735328473), n2 = h(n2, r2 = d(r2, o2, i2, n2, e3[u2 + 12], 20, -1926607734), o2, i2, e3[u2 + 5], 4, -378558), i2 = h(i2, n2, r2, o2, e3[u2 + 8], 11, -2022574463), o2 = h(o2, i2, n2, r2, e3[u2 + 11], 16, 1839030562), r2 = h(r2, o2, i2, n2, e3[u2 + 14], 23, -35309556), n2 = h(n2, r2, o2, i2, e3[u2 + 1], 4, -1530992060), i2 = h(i2, n2, r2, o2, e3[u2 + 4], 11, 1272893353), o2 = h(o2, i2, n2, r2, e3[u2 + 7], 16, -155497632), r2 = h(r2, o2, i2, n2, e3[u2 + 10], 23, -1094730640), n2 = h(n2, r2, o2, i2, e3[u2 + 13], 4, 681279174), i2 = h(i2, n2, r2, o2, e3[u2 + 0], 11, -358537222), o2 = h(o2, i2, n2, r2, e3[u2 + 3], 16, -722521979), r2 = h(r2, o2, i2, n2, e3[u2 + 6], 23, 76029189), n2 = h(n2, r2, o2, i2, e3[u2 + 9], 4, -640364487), i2 = h(i2, n2, r2, o2, e3[u2 + 12], 11, -421815835), o2 = h(o2, i2, n2, r2, e3[u2 + 15], 16, 530742520), n2 = p(n2, r2 = h(r2, o2, i2, n2, e3[u2 + 2], 23, -995338651), o2, i2, e3[u2 + 0], 6, -198630844), i2 = p(i2, n2, r2, o2, e3[u2 + 7], 10, 1126891415), o2 = p(o2, i2, n2, r2, e3[u2 + 14], 15, -1416354905), r2 = p(r2, o2, i2, n2, e3[u2 + 5], 21, -57434055), n2 = p(n2, r2, o2, i2, e3[u2 + 12], 6, 1700485571), i2 = p(i2, n2, r2, o2, e3[u2 + 3], 10, -1894986606), o2 = p(o2, i2, n2, r2, e3[u2 + 10], 15, -1051523), r2 = p(r2, o2, i2, n2, e3[u2 + 1], 21, -2054922799), n2 = p(n2, r2, o2, i2, e3[u2 + 8], 6, 1873313359), i2 = p(i2, n2, r2, o2, e3[u2 + 15], 10, -30611744), o2 = p(o2, i2, n2, r2, e3[u2 + 6], 15, -1560198380), r2 = p(r2, o2, i2, n2, e3[u2 + 13], 21, 1309151649), n2 = p(n2, r2, o2, i2, e3[u2 + 4], 6, -145523070), i2 = p(i2, n2, r2, o2, e3[u2 + 11], 10, -1120210379), o2 = p(o2, i2, n2, r2, e3[u2 + 2], 15, 718787259), r2 = p(r2, o2, i2, n2, e3[u2 + 9], 21, -343485551), n2 = g(n2, s2), r2 = g(r2, a2), o2 = g(o2, f2), i2 = g(i2, l2);
}
return Array(n2, r2, o2, i2);
}
function s(e3, t2, n2, r2, o2, i2) {
return g((t2 = g(g(t2, e3), g(r2, i2))) << o2 | t2 >>> 32 - o2, n2);
}
function c(e3, t2, n2, r2, o2, i2, u2) {
return s(t2 & n2 | ~t2 & r2, e3, t2, o2, i2, u2);
}
function d(e3, t2, n2, r2, o2, i2, u2) {
return s(t2 & r2 | n2 & ~r2, e3, t2, o2, i2, u2);
}
function h(e3, t2, n2, r2, o2, i2, u2) {
return s(t2 ^ n2 ^ r2, e3, t2, o2, i2, u2);
}
function p(e3, t2, n2, r2, o2, i2, u2) {
return s(n2 ^ (t2 | ~r2), e3, t2, o2, i2, u2);
}
function g(e3, t2) {
var n2 = (65535 & e3) + (65535 & t2);
return (e3 >> 16) + (t2 >> 16) + (n2 >> 16) << 16 | 65535 & n2;
}
b.exports = function(e3) {
return t.hash(e3, n, 16);
};
}).call(this, w("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, w("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/crypto-browserify/md5.js", "/node_modules/gulp-browserify/node_modules/crypto-browserify");
}, { "./helpers": 4, buffer: 3, lYpoI2: 11 }], 7: [function(e, l, t) {
(function(e2, t2, n, r, o, i, u, s, f) {
l.exports = function(e3) {
for (var t3, n2 = new Array(e3), r2 = 0;r2 < e3; r2++)
(3 & r2) == 0 && (t3 = 4294967296 * Math.random()), n2[r2] = t3 >>> ((3 & r2) << 3) & 255;
return n2;
};
}).call(this, e("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, e("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/crypto-browserify/rng.js", "/node_modules/gulp-browserify/node_modules/crypto-browserify");
}, { buffer: 3, lYpoI2: 11 }], 8: [function(c, d, e) {
(function(e2, t, n, r, o, s, a, f, l) {
var i = c("./helpers");
function u(l2, c2) {
l2[c2 >> 5] |= 128 << 24 - c2 % 32, l2[15 + (c2 + 64 >> 9 << 4)] = c2;
for (var e3, t2, n2, r2 = Array(80), o2 = 1732584193, i2 = -271733879, u2 = -1732584194, s2 = 271733878, d2 = -1009589776, h = 0;h < l2.length; h += 16) {
for (var p = o2, g = i2, y = u2, w = s2, b = d2, a2 = 0;a2 < 80; a2++) {
r2[a2] = a2 < 16 ? l2[h + a2] : v(r2[a2 - 3] ^ r2[a2 - 8] ^ r2[a2 - 14] ^ r2[a2 - 16], 1);
var f2 = m(m(v(o2, 5), (f2 = i2, t2 = u2, n2 = s2, (e3 = a2) < 20 ? f2 & t2 | ~f2 & n2 : !(e3 < 40) && e3 < 60 ? f2 & t2 | f2 & n2 | t2 & n2 : f2 ^ t2 ^ n2)), m(m(d2, r2[a2]), (e3 = a2) < 20 ? 1518500249 : e3 < 40 ? 1859775393 : e3 < 60 ? -1894007588 : -899497514)), d2 = s2, s2 = u2, u2 = v(i2, 30), i2 = o2, o2 = f2;
}
o2 = m(o2, p), i2 = m(i2, g), u2 = m(u2, y), s2 = m(s2, w), d2 = m(d2, b);
}
return Array(o2, i2, u2, s2, d2);
}
function m(e3, t2) {
var n2 = (65535 & e3) + (65535 & t2);
return (e3 >> 16) + (t2 >> 16) + (n2 >> 16) << 16 | 65535 & n2;
}
function v(e3, t2) {
return e3 << t2 | e3 >>> 32 - t2;
}
d.exports = function(e3) {
return i.hash(e3, u, 20, true);
};
}).call(this, c("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, c("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/crypto-browserify/sha.js", "/node_modules/gulp-browserify/node_modules/crypto-browserify");
}, { "./helpers": 4, buffer: 3, lYpoI2: 11 }], 9: [function(c, d, e) {
(function(e2, t, n, r, u, s, a, f, l) {
function b(e3, t2) {
var n2 = (65535 & e3) + (65535 & t2);
return (e3 >> 16) + (t2 >> 16) + (n2 >> 16) << 16 | 65535 & n2;
}
function o(e3, l2) {
var c2, d2 = new Array(1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298), t2 = new Array(1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225), n2 = new Array(64);
e3[l2 >> 5] |= 128 << 24 - l2 % 32, e3[15 + (l2 + 64 >> 9 << 4)] = l2;
for (var r2, o2, h = 0;h < e3.length; h += 16) {
for (var i2 = t2[0], u2 = t2[1], s2 = t2[2], p = t2[3], a2 = t2[4], g = t2[5], y = t2[6], w = t2[7], f2 = 0;f2 < 64; f2++)
n2[f2] = f2 < 16 ? e3[f2 + h] : b(b(b((o2 = n2[f2 - 2], m(o2, 17) ^ m(o2, 19) ^ v(o2, 10)), n2[f2 - 7]), (o2 = n2[f2 - 15], m(o2, 7) ^ m(o2, 18) ^ v(o2, 3))), n2[f2 - 16]), c2 = b(b(b(b(w, m(o2 = a2, 6) ^ m(o2, 11) ^ m(o2, 25)), a2 & g ^ ~a2 & y), d2[f2]), n2[f2]), r2 = b(m(r2 = i2, 2) ^ m(r2, 13) ^ m(r2, 22), i2 & u2 ^ i2 & s2 ^ u2 & s2), w = y, y = g, g = a2, a2 = b(p, c2), p = s2, s2 = u2, u2 = i2, i2 = b(c2, r2);
t2[0] = b(i2, t2[0]), t2[1] = b(u2, t2[1]), t2[2] = b(s2, t2[2]), t2[3] = b(p, t2[3]), t2[4] = b(a2, t2[4]), t2[5] = b(g, t2[5]), t2[6] = b(y, t2[6]), t2[7] = b(w, t2[7]);
}
return t2;
}
var i = c("./helpers"), m = function(e3, t2) {
return e3 >>> t2 | e3 << 32 - t2;
}, v = function(e3, t2) {
return e3 >>> t2;
};
d.exports = function(e3) {
return i.hash(e3, o, 32, true);
};
}).call(this, c("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, c("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/crypto-browserify/sha256.js", "/node_modules/gulp-browserify/node_modules/crypto-browserify");
}, { "./helpers": 4, buffer: 3, lYpoI2: 11 }], 10: [function(e, t, f) {
(function(e2, t2, n, r, o, i, u, s, a) {
f.read = function(e3, t3, n2, r2, o2) {
var i2, u2, l = 8 * o2 - r2 - 1, c = (1 << l) - 1, d = c >> 1, s2 = -7, a2 = n2 ? o2 - 1 : 0, f2 = n2 ? -1 : 1, o2 = e3[t3 + a2];
for (a2 += f2, i2 = o2 & (1 << -s2) - 1, o2 >>= -s2, s2 += l;0 < s2; i2 = 256 * i2 + e3[t3 + a2], a2 += f2, s2 -= 8)
;
for (u2 = i2 & (1 << -s2) - 1, i2 >>= -s2, s2 += r2;0 < s2; u2 = 256 * u2 + e3[t3 + a2], a2 += f2, s2 -= 8)
;
if (i2 === 0)
i2 = 1 - d;
else {
if (i2 === c)
return u2 ? NaN : 1 / 0 * (o2 ? -1 : 1);
u2 += Math.pow(2, r2), i2 -= d;
}
return (o2 ? -1 : 1) * u2 * Math.pow(2, i2 - r2);
}, f.write = function(e3, t3, l, n2, r2, c) {
var o2, i2, u2 = 8 * c - r2 - 1, s2 = (1 << u2) - 1, a2 = s2 >> 1, d = r2 === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0, f2 = n2 ? 0 : c - 1, h = n2 ? 1 : -1, c = t3 < 0 || t3 === 0 && 1 / t3 < 0 ? 1 : 0;
for (t3 = Math.abs(t3), isNaN(t3) || t3 === 1 / 0 ? (i2 = isNaN(t3) ? 1 : 0, o2 = s2) : (o2 = Math.floor(Math.log(t3) / Math.LN2), t3 * (n2 = Math.pow(2, -o2)) < 1 && (o2--, n2 *= 2), 2 <= (t3 += 1 <= o2 + a2 ? d / n2 : d * Math.pow(2, 1 - a2)) * n2 && (o2++, n2 /= 2), s2 <= o2 + a2 ? (i2 = 0, o2 = s2) : 1 <= o2 + a2 ? (i2 = (t3 * n2 - 1) * Math.pow(2, r2), o2 += a2) : (i2 = t3 * Math.pow(2, a2 - 1) * Math.pow(2, r2), o2 = 0));8 <= r2; e3[l + f2] = 255 & i2, f2 += h, i2 /= 256, r2 -= 8)
;
for (o2 = o2 << r2 | i2, u2 += r2;0 < u2; e3[l + f2] = 255 & o2, f2 += h, o2 /= 256, u2 -= 8)
;
e3[l + f2 - h] |= 128 * c;
};
}).call(this, e("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, e("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/ieee754/index.js", "/node_modules/gulp-browserify/node_modules/ieee754");
}, { buffer: 3, lYpoI2: 11 }], 11: [function(e, h, t) {
(function(e2, t2, n, r, o, f, l, c, d) {
var i, u, s;
function a() {}
(e2 = h.exports = {}).nextTick = (u = typeof window != "undefined" && window.setImmediate, s = typeof window != "undefined" && window.postMessage && window.addEventListener, u ? function(e3) {
return window.setImmediate(e3);
} : s ? (i = [], window.addEventListener("message", function(e3) {
var t3 = e3.source;
t3 !== window && t3 !== null || e3.data !== "process-tick" || (e3.stopPropagation(), 0 < i.length && i.shift()());
}, true), function(e3) {
i.push(e3), window.postMessage("process-tick", "*");
}) : function(e3) {
setTimeout(e3, 0);
}), e2.title = "browser", e2.browser = true, e2.env = {}, e2.argv = [], e2.on = a, e2.addListener = a, e2.once = a, e2.off = a, e2.removeListener = a, e2.removeAllListeners = a, e2.emit = a, e2.binding = function(e3) {
throw new Error("process.binding is not supported");
}, e2.cwd = function() {
return "/";
}, e2.chdir = function(e3) {
throw new Error("process.chdir is not supported");
};
}).call(this, e("lYpoI2"), typeof self != "undefined" ? self : typeof window != "undefined" ? window : {}, e("buffer").Buffer, arguments[3], arguments[4], arguments[5], arguments[6], "/node_modules/gulp-browserify/node_modules/process/browser.js", "/node_modules/gulp-browserify/node_modules/process");
}, { buffer: 3, lYpoI2: 11 }] }, {}, [1])(1);
});
});
// node_modules/@tscircuit/capacity-autorouter/dist/index.js
var import_object_hash = __toESM(require_object_hash());
__toESM(require_object_hash());
__toESM(require_object_hash());
var e = Object.create;
var t = Object.defineProperty;
var n = Object.getOwnPropertyDescriptor;
var o = Object.getOwnPropertyNames;
var i = Object.getPrototypeOf;
var r = Object.prototype.hasOwnProperty;
var s = (e2, t2) => function() {
return t2 || (0, e2[o(e2)[0]])((t2 = { exports: {} }).exports, t2), t2.exports;
};
var a = (e2, n2) => {
for (var o2 in n2)
t(e2, o2, { get: n2[o2], enumerable: true });
};
var c = (s2, a2, c2) => (c2 = s2 != null ? e(i(s2)) : {}, ((e2, i2, s3, a3) => {
if (i2 && typeof i2 == "object" || typeof i2 == "function")
for (let c3 of o(i2))
r.call(e2, c3) || c3 === s3 || t(e2, c3, { get: () => i2[c3], enumerable: !(a3 = n(i2, c3)) || a3.enumerable });
return e2;
})(!a2 && s2 && s2.__esModule ? c2 : t(c2, "default", { value: s2, enumerable: true }), s2));
var l = s({ "node_modules/is-buffer/index.js"(e2, t2) {
function n2(e3) {
return !!e3.constructor && typeof e3.constructor.isBuffer == "function" && e3.constructor.isBuffer(e3);
}
t2.exports = function(e3) {
return e3 != null && (n2(e3) || function(e4) {
return typeof e4.readFloatLE == "function" && typeof e4.slice == "function" && n2(e4.slice(0, 0));
}(e3) || !!e3._isBuffer);
};
} });
var h = s({ "node_modules/kind-of/index.js"(e2, t2) {
var n2 = l(), o2 = Object.prototype.toString;
t2.exports = function(e3) {
if (e3 === undefined)
return "undefined";
if (e3 === null)
return "null";
if (e3 === true || e3 === false || e3 instanceof Boolean)
return "boolean";
if (typeof e3 == "string" || e3 instanceof String)
return "string";
if (typeof e3 == "number" || e3 instanceof Number)
return "number";
if (typeof e3 == "function" || e3 instanceof Function)
return "function";
if (Array.isArray !== undefined && Array.isArray(e3))
return "array";
if (e3 instanceof RegExp)
return "regexp";
if (e3 instanceof Date)
return "date";
var t3 = o2.call(e3);
return t3 === "[object RegExp]" ? "regexp" : t3 === "[object Date]" ? "date" : t3 === "[object Arguments]" ? "arguments" : t3 === "[object Error]" ? "error" : n2(e3) ? "buffer" : t3 === "[object Set]" ? "set" : t3 === "[object WeakSet]" ? "weakset" : t3 === "[object Map]" ? "map" : t3 === "[object WeakMap]" ? "weakmap" : t3 === "[object Symbol]" ? "symbol" : t3 === "[object Int8Array]" ? "int8array" : t3 === "[object Uint8Array]" ? "uint8array" : t3 === "[object Uint8ClampedArray]" ? "uint8clampedarray" : t3 === "[object Int16Array]" ? "int16array" : t3 === "[object Uint16Array]" ? "uint16array" : t3 === "[object Int32Array]" ? "int32array" : t3 === "[object Uint32Array]" ? "uint32array" : t3 === "[object Float32Array]" ? "float32array" : t3 === "[object Float64Array]" ? "float64array" : "object";
};
} });
var d = s({ "node_modules/rename-keys/index.js"(e2, t2) {
(function() {
function e3(e4, t3) {
if (typeof t3 != "function")
return e4;
var n2 = {};
for (var o2 in e4)
Object.prototype.hasOwnProperty.call(e4, o2) && (n2[t3(o2, e4[o2]) || o2] = e4[o2]);
return n2;
}
t2 !== undefined && t2.exports ? t2.exports = e3 : typeof define == "function" && define.amd ? define([], function() {
return e3;
}) : window.rename = e3;
})();
} });
var u = s({ "node_modules/deep-rename-keys/index.js"(e2, t2) {
var n2 = h(), o2 = d();
t2.exports = function e3(t3, i2) {
var r2 = n2(t3);
if (r2 !== "object" && r2 !== "array")
throw new Error("expected an object");
var s2 = [];
for (var a2 in r2 === "object" && (t3 = o2(t3, i2), s2 = {}), t3)
if (t3.hasOwnProperty(a2)) {
var c2 = t3[a2];
n2(c2) === "object" || n2(c2) === "array" ? s2[a2] = e3(c2, i2) : s2[a2] = c2;
}
return s2;
};
} });
var p = s({ "node_modules/xml-reader/node_modules/eventemitter3/index.js"(e2, t2) {
var n2 = Object.prototype.hasOwnProperty, o2 = "~";
function i2() {}
function r2(e3, t3, n3) {
this.fn = e3, this.context = t3, this.once = n3 || false;
}
function s2() {
this._events = new i2, this._eventsCount = 0;
}
Object.create && (i2.prototype = Object.create(null), new i2().__proto__ || (o2 = false)), s2.prototype.eventNames = function() {
var e3, t3, i3 = [];
if (this._eventsCount === 0)
return i3;
for (t3 in e3 = this._events)
n2.call(e3, t3) && i3.push(o2 ? t3.slice(1) : t3);
return Object.getOwnPropertySymbols ? i3.concat(Object.getOwnPropertySymbols(e3)) : i3;
}, s2.prototype.listeners = function(e3, t3) {
var n3 = o2 ? o2 + e3 : e3, i3 = this._events[n3];
if (t3)
return !!i3;
if (!i3)
return [];
if (i3.fn)
return [i3.fn];
for (var r3 = 0, s3 = i3.length, a2 = new Array(s3);r3 < s3; r3++)
a2[r3] = i3[r3].fn;
return a2;
}, s2.prototype.emit = function(e3, t3, n3, i3, r3, s3) {
var a2 = o2 ? o2 + e3 : e3;
if (!this._events[a2])
return false;
var c2, l2, h2 = this._events[a2], d2 = arguments.length;
if (h2.fn) {
switch (h2.once && this.removeListener(e3, h2.fn, undefined, true), d2) {
case 1:
return h2.fn.call(h2.context), true;
case 2:
return h2.fn.call(h2.context, t3), true;
case 3:
return h2.fn.call(h2.context, t3, n3), true;
case 4:
return h2.fn.call(h2.context, t3, n3, i3), true;
case 5:
return h2.fn.call(h2.context, t3, n3, i3, r3), true;
case 6:
return h2.fn.call(h2.context, t3, n3, i3, r3, s3), true;
}
for (l2 = 1, c2 = new Array(d2 - 1);l2 < d2; l2++)
c2[l2 - 1] = arguments[l2];
h2.fn.apply(h2.context, c2);
} else {
var u2, p2 = h2.length;
for (l2 = 0;l2 < p2; l2++)
switch (h2[l2].once && this.removeListener(e3, h2[l2].fn, undefined, true), d2) {
case 1:
h2[l2].fn.call(h2[l2].context);
break;
case 2:
h2[l2].fn.call(h2[l2].context, t3);
break;
case 3:
h2[l2].fn.call(h2[l2].context, t3, n3);
break;
case 4:
h2[l2].fn.call(h2[l2].context, t3, n3, i3);
break;
default:
if (!c2)
for (u2 = 1, c2 = new Array(d2 - 1);u2 < d2; u2++)
c2[u2 - 1] = arguments[u2];
h2[l2].fn.apply(h2[l2].context, c2);
}
}
return true;
}, s2.prototype.on = function(e3, t3, n3) {
var i3 = new r2(t3, n3 || this), s3 = o2 ? o2 + e3 : e3;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.once = function(e3, t3, n3) {
var i3 = new r2(t3, n3 || this, true), s3 = o2 ? o2 + e3 : e3;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.removeListener = function(e3, t3, n3, r3) {
var s3 = o2 ? o2 + e3 : e3;
if (!this._events[s3])
return this;
if (!t3)
return --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3], this;
var a2 = this._events[s3];
if (a2.fn)
a2.fn !== t3 || r3 && !a2.once || n3 && a2.context !== n3 || (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3]);
else {
for (var c2 = 0, l2 = [], h2 = a2.length;c2 < h2; c2++)
(a2[c2].fn !== t3 || r3 && !a2[c2].once || n3 && a2[c2].context !== n3) && l2.push(a2[c2]);
l2.length ? this._events[s3] = l2.length === 1 ? l2[0] : l2 : --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3];
}
return this;
}, s2.prototype.removeAllListeners = function(e3) {
var t3;
return e3 ? (t3 = o2 ? o2 + e3 : e3, this._events[t3] && (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[t3])) : (this._events = new i2, this._eventsCount = 0), this;
}, s2.prototype.off = s2.prototype.removeListener, s2.prototype.addListener = s2.prototype.on, s2.prototype.setMaxListeners = function() {
return this;
}, s2.prefixed = o2, s2.EventEmitter = s2, t2 !== undefined && (t2.exports = s2);
} });
var m = s({ "node_modules/xml-lexer/node_modules/eventemitter3/index.js"(e2, t2) {
var n2 = Object.prototype.hasOwnProperty, o2 = "~";
function i2() {}
function r2(e3, t3, n3) {
this.fn = e3, this.context = t3, this.once = n3 || false;
}
function s2() {
this._events = new i2, this._eventsCount = 0;
}
Object.create && (i2.prototype = Object.create(null), new i2().__proto__ || (o2 = false)), s2.prototype.eventNames = function() {
var e3, t3, i3 = [];
if (this._eventsCount === 0)
return i3;
for (t3 in e3 = this._events)
n2.call(e3, t3) && i3.push(o2 ? t3.slice(1) : t3);
return Object.getOwnPropertySymbols ? i3.concat(Object.getOwnPropertySymbols(e3)) : i3;
}, s2.prototype.listeners = function(e3, t3) {
var n3 = o2 ? o2 + e3 : e3, i3 = this._events[n3];
if (t3)
return !!i3;
if (!i3)
return [];
if (i3.fn)
return [i3.fn];
for (var r3 = 0, s3 = i3.length, a2 = new Array(s3);r3 < s3; r3++)
a2[r3] = i3[r3].fn;
return a2;
}, s2.prototype.emit = function(e3, t3, n3, i3, r3, s3) {
var a2 = o2 ? o2 + e3 : e3;
if (!this._events[a2])
return false;
var c2, l2, h2 = this._events[a2], d2 = arguments.length;
if (h2.fn) {
switch (h2.once && this.removeListener(e3, h2.fn, undefined, true), d2) {
case 1:
return h2.fn.call(h2.context), true;
case 2:
return h2.fn.call(h2.context, t3), true;
case 3:
return h2.fn.call(h2.context, t3, n3), true;
case 4:
return h2.fn.call(h2.context, t3, n3, i3), true;
case 5:
return h2.fn.call(h2.context, t3, n3, i3, r3), true;
case 6:
return h2.fn.call(h2.context, t3, n3, i3, r3, s3), true;
}
for (l2 = 1, c2 = new Array(d2 - 1);l2 < d2; l2++)
c2[l2 - 1] = arguments[l2];
h2.fn.apply(h2.context, c2);
} else {
var u2, p2 = h2.length;
for (l2 = 0;l2 < p2; l2++)
switch (h2[l2].once && this.removeListener(e3, h2[l2].fn, undefined, true), d2) {
case 1:
h2[l2].fn.call(h2[l2].context);
break;
case 2:
h2[l2].fn.call(h2[l2].context, t3);
break;
case 3:
h2[l2].fn.call(h2[l2].context, t3, n3);
break;
case 4:
h2[l2].fn.call(h2[l2].context, t3, n3, i3);
break;
default:
if (!c2)
for (u2 = 1, c2 = new Array(d2 - 1);u2 < d2; u2++)
c2[u2 - 1] = arguments[u2];
h2[l2].fn.apply(h2[l2].context, c2);
}
}
return true;
}, s2.prototype.on = function(e3, t3, n3) {
var i3 = new r2(t3, n3 || this), s3 = o2 ? o2 + e3 : e3;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.once = function(e3, t3, n3) {
var i3 = new r2(t3, n3 || this, true), s3 = o2 ? o2 + e3 : e3;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.removeListener = function(e3, t3, n3, r3) {
var s3 = o2 ? o2 + e3 : e3;
if (!this._events[s3])
return this;
if (!t3)
return --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3], this;
var a2 = this._events[s3];
if (a2.fn)
a2.fn !== t3 || r3 && !a2.once || n3 && a2.context !== n3 || (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3]);
else {
for (var c2 = 0, l2 = [], h2 = a2.length;c2 < h2; c2++)
(a2[c2].fn !== t3 || r3 && !a2[c2].once || n3 && a2[c2].context !== n3) && l2.push(a2[c2]);
l2.length ? this._events[s3] = l2.length === 1 ? l2[0] : l2 : --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3];
}
return this;
}, s2.prototype.removeAllListeners = function(e3) {
var t3;
return e3 ? (t3 = o2 ? o2 + e3 : e3, this._events[t3] && (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[t3])) : (this._events = new i2, this._eventsCount = 0), this;
}, s2.prototype.off = s2.prototype.removeListener, s2.prototype.addListener = s2.prototype.on, s2.prototype.setMaxListeners = function() {
return this;
}, s2.prefixed = o2, s2.EventEmitter = s2, t2 !== undefined && (t2.exports = s2);
} });
var g = s({ "node_modules/xml-lexer/dist/lexer.js"(e2, t2) {
function n2(e3, t3, n3) {
return t3 in e3 ? Object.defineProperty(e3, t3, { value: n3, enumerable: true, configurable: true, writable: true }) : e3[t3] = n3, e3;
}
var o2 = m(), i2 = function() {}, r2 = { 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" }, s2 = { lt: "action-lt", gt: "action-gt", space: "action-space", equal: "action-equal", quote: "action-quote", slash: "action-slash", char: "action-char", error: "action-error" }, a2 = { text: "text", openTag: "open-tag", closeTag: "close-tag", attributeName: "attribute-name", attributeValue: "attribute-value" }, c2 = { " ": s2.space, "\t": s2.space, "\n": s2.space, "\r": s2.space, "<": s2.lt, ">": s2.gt, '"': s2.quote, "'": s2.quote, "=": s2.equal, "/": s2.slash };
t2.exports = { State: r2, Action: s2, Type: a2, create: function(e3) {
var t3, l2, h2, d2, u2, p2, m2, g2, f, _;
e3 = Object.assign({ debug: false }, e3);
var y = new o2, b = r2.data, x = "", v = "", I = "", S = "", C = "", P = "", M = function(t4, n3) {
if (v[0] !== "?" && v[0] !== "!") {
var o3 = { type: t4, value: n3 };
e3.debug && console.log("emit:", o3), y.emit("data", o3);
}
};
y.stateMachine = (n2(_ = {}, r2.data, (n2(t3 = {}, s2.lt, function() {
x.trim() && M(a2.text, x), v = "", C = false, b = r2.tagBegin;
}), n2(t3, s2.char, function(e4) {
x += e4;
}), t3)), n2(_, r2.cdata, n2({}, s2.char, function(e4) {
(x += e4).substr(-3) === "]]>" && (M(a2.text, x.slice(0, -3)), x = "", b = r2.data);
})), n2(_, r2.tagBegin, (n2(l2 = {}, s2.space, i2), n2(l2, s2.char, function(e4) {
v = e4, b = r2.tagName;
}), n2(l2, s2.slash, function() {
v = "", C = true;
}), l2)), n2(_, r2.tagName, (n2(h2 = {}, s2.space, function() {
C ? b = r2.tagEnd : (b = r2.attributeNameStart, M(a2.openTag, v));
}), n2(h2, s2.gt, function() {
M(C ? a2.closeTag : a2.openTag, v), x = "", b = r2.data;
}), n2(h2, s2.slash, function() {
b = r2.tagEnd, M(a2.openTag, v);
}), n2(h2, s2.char, function(e4) {
(v += e4) === "![CDATA[" && (b = r2.cdata, x = "", v = "");
}), h2)), n2(_, r2.tagEnd, (n2(d2 = {}, s2.gt, function() {
M(a2.closeTag, v), x = "", b = r2.data;
}), n2(d2, s2.char, i2), d2)), n2(_, r2.attributeNameStart, (n2(u2 = {}, s2.char, function(e4) {
I = e4, b = r2.attributeName;
}), n2(u2, s2.gt, function() {
x = "", b = r2.data;
}), n2(u2, s2.space, i2), n2(u2, s2.slash, function() {
C = true, b = r2.tagEnd;
}), u2)), n2(_, r2.attributeName, (n2(p2 = {}, s2.space, function() {
b = r2.attributeNameEnd;
}), n2(p2, s2.equal, function() {
M(a2.attributeName, I), b = r2.attributeValueBegin;
}), n2(p2, s2.gt, function() {
S = "", M(a2.attributeName, I), M(a2.attributeValue, S), x = "", b = r2.data;
}), n2(p2, s2.slash, function() {
C = true, S = "", M(a2.attributeName, I), M(a2.attributeValue, S), b = r2.tagEnd;
}), n2(p2, s2.char, function(e4) {
I += e4;
}), p2)), n2(_, r2.attributeNameEnd, (n2(m2 = {}, s2.space, i2), n2(m2, s2.equal, function() {
M(a2.attributeName, I), b = r2.attributeValueBegin;
}), n2(m2, s2.gt, function() {
S = "", M(a2.attributeName, I), M(a2.attributeValue, S), x = "", b = r2.data;
}), n2(m2, s2.char, function(e4) {
S = "", M(a2.attributeName, I), M(a2.attributeValue, S), I = e4, b = r2.attributeName;
}), m2)), n2(_, r2.attributeValueBegin, (n2(g2 = {}, s2.space, i2), n2(g2, s2.quote, function(e4) {
P = e4, S = "", b = r2.attributeValue;
}), n2(g2, s2.gt, function() {
M(a2.attributeValue, S = ""), x = "", b = r2.data;
}), n2(g2, s2.char, function(e4) {
P = "", S = e4, b = r2.attributeValue;
}), g2)), n2(_, r2.attributeValue, (n2(f = {}, s2.space, function(e4) {
P ? S += e4 : (M(a2.attributeValue, S), b = r2.attributeNameStart);
}), n2(f, s2.quote, function(e4) {
P === e4 ? (M(a2.attributeValue, S), b = r2.attributeNameStart) : S += e4;
}), n2(f, s2.gt, function(e4) {
P ? S += e4 : (M(a2.attributeValue, S), x = "", b = r2.data);
}), n2(f, s2.slash, function(e4) {
P ? S += e4 : (M(a2.attributeValue, S), C = true, b = r2.tagEnd);
}), n2(f, s2.char, function(e4) {
S += e4;
}), f)), _);
var w = function(t4) {
e3.debug && console.log(b, t4);
var n3 = y.stateMachine[b], o3 = n3[function(e4) {
return c2[e4] || s2.char;
}(t4)] || n3[s2.error] || n3[s2.char];
o3(t4);
};
return y.write = function(e4) {
for (var t4 = e4.length, n3 = 0;n3 < t4; n3++)
w(e4[n3]);
}, y;
} };
} });
var f = s({ "node_modules/xml-reader/dist/reader.js"(e2, t2) {
var n2 = p(), o2 = g(), i2 = o2.Type, r2 = { element: "element", text: "text" }, s2 = function(e3) {
return Object.assign({ name: "", type: r2.element, value: "", parent: null, attributes: {}, children: [] }, e3);
}, a2 = function(e3) {
e3 = Object.assign({ stream: false, parentNodes: true, doneEvent: "done", tagPrefix: "tag:", emitTopLevelOnly: false, debug: false }, e3);
var t3 = undefined, a3 = undefined, c2 = undefined, l2 = undefined, h2 = new n2, d2 = function(n3) {
switch (n3.type) {
case i2.openTag:
if (c2 === null)
(c2 = a3).name = n3.value;
else {
var o3 = s2({ name: n3.value, parent: c2 });
c2.children.push(o3), c2 = o3;
}
break;
case i2.closeTag:
var d3 = c2.parent;
if (e3.parentNodes || (c2.parent = null), c2.name !== n3.value)
break;
e3.stream && d3 === a3 && (a3.children = [], c2.parent = null), e3.emitTopLevelOnly && d3 !== a3 || (h2.emit(e3.tagPrefix + c2.name, c2), h2.emit("tag", c2.name, c2)), c2 === a3 && (t3.removeAllListeners("data"), h2.emit(e3.doneEvent, c2), a3 = null), c2 = d3;
break;
case i2.text:
c2 && c2.children.push(s2({ type: r2.text, value: n3.value, parent: e3.parentNodes ? c2 : null }));
break;
case i2.attributeName:
l2 = n3.value, c2.attributes[l2] = "";
break;
case i2.attributeValue:
c2.attributes[l2] = n3.value;
}
};
return h2.reset = function() {
(t3 = o2.create({ debug: e3.debug })).on("data", d2), a3 = s2(), c2 = null, l2 = "", h2.parse = t3.write;
}, h2.reset(), h2;
};
t2.exports = { parseSync: function(e3, t3) {
t3 = Object.assign({}, t3, { stream: false, tagPrefix: ":" });
var n3 = a2(t3), o3 = undefined;
return n3.on("done", function(e4) {
o3 = e4;
}), n3.parse(e3), o3;
}, create: a2, NodeType: r2 };
} });
var _ = s({ "node_modules/binary-search-bounds/search-bounds.js"(e2, t2) {
function n2(e3, t3, n3, o3, i3) {
for (var r3 = i3 + 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e3[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) >= 0 ? (r3 = s3, i3 = s3 - 1) : o3 = s3 + 1;
}
return r3;
}
function o2(e3, t3, n3, o3, i3) {
for (var r3 = i3 + 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e3[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) > 0 ? (r3 = s3, i3 = s3 - 1) : o3 = s3 + 1;
}
return r3;
}
function i2(e3, t3, n3, o3, i3) {
for (var r3 = o3 - 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e3[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) < 0 ? (r3 = s3, o3 = s3 + 1) : i3 = s3 - 1;
}
return r3;
}
function r2(e3, t3, n3, o3, i3) {
for (var r3 = o3 - 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e3[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) <= 0 ? (r3 = s3, o3 = s3 + 1) : i3 = s3 - 1;
}
return r3;
}
function s2(e3, t3, n3, o3, i3) {
for (;o3 <= i3; ) {
var r3 = o3 + i3 >>> 1, s3 = e3[r3], a3 = n3 !== undefined ? n3(s3, t3) : s3 - t3;
if (a3 === 0)
return r3;
a3 <= 0 ? o3 = r3 + 1 : i3 = r3 - 1;
}
return -1;
}
function a2(e3, t3, n3, o3, i3, r3) {
return typeof n3 == "function" ? r3(e3, t3, n3, o3 === undefined ? 0 : 0 | o3, i3 === undefined ? e3.length - 1 : 0 | i3) : r3(e3, t3, undefined, n3 === undefined ? 0 : 0 | n3, o3 === undefined ? e3.length - 1 : 0 | o3);
}
t2.exports = { ge: function(e3, t3, o3, i3, r3) {
return a2(e3, t3, o3, i3, r3, n2);
}, gt: function(e3, t3, n3, i3, r3) {
return a2(e3, t3, n3, i3, r3, o2);
}, lt: function(e3, t3, n3, o3, r3) {
return a2(e3, t3, n3, o3, r3, i2);
}, le: function(e3, t3, n3, o3, i3) {
return a2(e3, t3, n3, o3, i3, r2);
}, eq: function(e3, t3, n3, o3, i3) {
return a2(e3, t3, n3, o3, i3, s2);
} };
} });
var y = s({ "node_modules/two-product/two-product.js"(e2, t2) {
t2.exports = function(e3, t3, o2) {
var i2 = e3 * t3, r2 = n2 * e3, s2 = r2 - (r2 - e3), a2 = e3 - s2, c2 = n2 * t3, l2 = c2 - (c2 - t3), h2 = t3 - l2, d2 = a2 * h2 - (i2 - s2 * l2 - a2 * l2 - s2 * h2);
if (o2)
return o2[0] = d2, o2[1] = i2, o2;
return [d2, i2];
};
var n2 = +(Math.pow(2, 27) + 1);
} });
var b = s({ "node_modules/robust-sum/robust-sum.js"(e2, t2) {
t2.exports = function(e3, t3) {
var n2 = 0 | e3.length, o2 = 0 | t3.length;
if (n2 === 1 && o2 === 1)
return function(e4, t4) {
var n3 = e4 + t4, o3 = n3 - e4, i3 = n3 - o3, r3 = t4 - o3, s3 = e4 - i3, a3 = s3 + r3;
if (a3)
return [a3, n3];
return [n3];
}(e3[0], t3[0]);
var i2, r2, s2 = new Array(n2 + o2), a2 = 0, c2 = 0, l2 = 0, h2 = Math.abs, d2 = e3[c2], u2 = h2(d2), p2 = t3[l2], m2 = h2(p2);
u2 < m2 ? (r2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e3[c2]))) : (r2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = t3[l2])));
c2 < n2 && u2 < m2 || l2 >= o2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e3[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = t3[l2])));
var g2, f2, _2 = i2 + r2, y2 = _2 - i2, b2 = r2 - y2, x = b2, v = _2;
for (;c2 < n2 && l2 < o2; )
u2 < m2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e3[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = t3[l2]))), (b2 = (r2 = x) - (y2 = (_2 = i2 + r2) - i2)) && (s2[a2++] = b2), x = v - ((g2 = v + _2) - (f2 = g2 - v)) + (_2 - f2), v = g2;
for (;c2 < n2; )
(b2 = (r2 = x) - (y2 = (_2 = (i2 = d2) + r2) - i2)) && (s2[a2++] = b2), x = v - ((g2 = v + _2) - (f2 = g2 - v)) + (_2 - f2), v = g2, (c2 += 1) < n2 && (d2 = e3[c2]);
for (;l2 < o2; )
(b2 = (r2 = x) - (y2 = (_2 = (i2 = p2) + r2) - i2)) && (s2[a2++] = b2), x = v - ((g2 = v + _2) - (f2 = g2 - v)) + (_2 - f2), v = g2, (l2 += 1) < o2 && (p2 = t3[l2]);
x && (s2[a2++] = x);
v && (s2[a2++] = v);
a2 || (s2[a2++] = 0);
return s2.length = a2, s2;
};
} });
var x = s({ "node_modules/two-sum/two-sum.js"(e2, t2) {
t2.exports = function(e3, t3, n2) {
var o2 = e3 + t3, i2 = o2 - e3, r2 = t3 - i2, s2 = e3 - (o2 - i2);
if (n2)
return n2[0] = s2 + r2, n2[1] = o2, n2;
return [s2 + r2, o2];
};
} });
var v = s({ "node_modules/robust-scale/robust-scale.js"(e2, t2) {
var n2 = y(), o2 = x();
t2.exports = function(e3, t3) {
var i2 = e3.length;
if (i2 === 1) {
var r2 = n2(e3[0], t3);
return r2[0] ? r2 : [r2[1]];
}
var s2 = new Array(2 * i2), a2 = [0.1, 0.1], c2 = [0.1, 0.1], l2 = 0;
n2(e3[0], t3, a2), a2[0] && (s2[l2++] = a2[0]);
for (var h2 = 1;h2 < i2; ++h2) {
n2(e3[h2], t3, c2);
var d2 = a2[1];
o2(d2, c2[0], a2), a2[0] && (s2[l2++] = a2[0]);
var u2 = c2[1], p2 = a2[1], m2 = u2 + p2, g2 = p2 - (m2 - u2);
a2[1] = m2, g2 && (s2[l2++] = g2);
}
a2[1] && (s2[l2++] = a2[1]);
l2 === 0 && (s2[l2++] = 0);
return s2.length = l2, s2;
};
} });
var I = s({ "node_modules/robust-subtract/robust-diff.js"(e2, t2) {
t2.exports = function(e3, t3) {
var n2 = 0 | e3.length, o2 = 0 | t3.length;
if (n2 === 1 && o2 === 1)
return function(e4, t4) {
var n3 = e4 + t4, o3 = n3 - e4, i3 = n3 - o3, r3 = t4 - o3, s3 = e4 - i3, a3 = s3 + r3;
if (a3)
return [a3, n3];
return [n3];
}(e3[0], -t3[0]);
var i2, r2, s2 = new Array(n2 + o2), a2 = 0, c2 = 0, l2 = 0, h2 = Math.abs, d2 = e3[c2], u2 = h2(d2), p2 = -t3[l2], m2 = h2(p2);
u2 < m2 ? (r2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e3[c2]))) : (r2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = -t3[l2])));
c2 < n2 && u2 < m2 || l2 >= o2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e3[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = -t3[l2])));
var g2, f2, _2 = i2 + r2, y2 = _2 - i2, b2 = r2 - y2, x2 = b2, v2 = _2;
for (;c2 < n2 && l2 < o2; )
u2 < m2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e3[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = -t3[l2]))), (b2 = (r2 = x2) - (y2 = (_2 = i2 + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2;
for (;c2 < n2; )
(b2 = (r2 = x2) - (y2 = (_2 = (i2 = d2) + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2, (c2 += 1) < n2 && (d2 = e3[c2]);
for (;l2 < o2; )
(b2 = (r2 = x2) - (y2 = (_2 = (i2 = p2) + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2, (l2 += 1) < o2 && (p2 = -t3[l2]);
x2 && (s2[a2++] = x2);
v2 && (s2[a2++] = v2);
a2 || (s2[a2++] = 0);
return s2.length = a2, s2;
};
} });
var S = s({ "node_modules/robust-orientation/orientation.js"(e2, t2) {
var n2 = y(), o2 = b(), i2 = v(), r2 = I();
function s2(e3, t3, n3, o3) {
return function(n4, i3, r3) {
var s3 = e3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), e3(t3(n4[1], i3[0]), t3(-i3[1], n4[0]))), a3 = e3(t3(n4[1], r3[0]), t3(-r3[1], n4[0])), c3 = o3(s3, a3);
return c3[c3.length - 1];
};
}
function a2(e3, t3, n3, o3) {
return function(i3, r3, s3, a3) {
var c3 = e3(e3(n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), r3[2]), e3(n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), -s3[2]), n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), a3[2]))), e3(n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), a3[2])))), l3 = e3(e3(n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), i3[2]), e3(n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -s3[2]), n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), a3[2]))), e3(n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), s3[2])))), h3 = o3(c3, l3);
return h3[h3.length - 1];
};
}
function c2(e3, t3, n3, o3) {
return function(i3, r3, s3, a3, c3) {
var l3 = e3(e3(e3(n3(e3(n3(e3(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), s3[2]), e3(n3(e3(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), -a3[2]), n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), c3[2]))), r3[3]), e3(n3(e3(n3(e3(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), r3[2]), e3(n3(e3(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -a3[2]), n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), c3[2]))), -s3[3]), n3(e3(n3(e3(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), r3[2]), e3(n3(e3(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -s3[2]), n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), c3[2]))), a3[3]))), e3(n3(e3(n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), r3[2]), e3(n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), -s3[2]), n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), a3[2]))), -c3[3]), e3(n3(e3(n3(e3(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), r3[2]), e3(n3(e3(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -a3[2]), n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), c3[2]))), i3[3]), n3(e3(n3(e3(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), i3[2]), e3(n3(e3(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -a3[2]), n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), c3[2]))), -r3[3])))), e3(e3(n3(e3(n3(e3(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), c3[2]))), a3[3]), e3(n3(e3(n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), a3[2]))), -c3[3]), n3(e3(n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), r3[2]), e3(n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), -s3[2]), n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), a3[2]))), i3[3]))), e3(n3(e3(n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), i3[2]), e3(n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -s3[2]), n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), a3[2]))), -r3[3]), e3(n3(e3(n3(e3(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), a3[2]))), s3[3]), n3(e3(n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), s3[2]))), -a3[3]))))), h3 = e3(e3(e3(n3(e3(n3(e3(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), s3[2]), e3(n3(e3(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), -a3[2]), n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), c3[2]))), i3[3]), n3(e3(n3(e3(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), i3[2]), e3(n3(e3(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -a3[2]), n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), c3[2]))), -s3[3])), e3(n3(e3(n3(e3(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), i3[2]), e3(n3(e3(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -s3[2]), n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), c3[2]))), a3[3]), n3(e3(n3(e3(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), i3[2]), e3(n3(e3(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -s3[2]), n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), a3[2]))), -c3[3]))), e3(e3(n3(e3(n3(e3(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), r3[2]), e3(n3(e3(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -s3[2]), n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), c3[2]))), i3[3]), n3(e3(n3(e3(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), i3[2]), e3(n3(e3(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -s3[2]), n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), c3[2]))), -r3[3])), e3(n3(e3(n3(e3(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), c3[2]))), s3[3]), n3(e3(n3(e3(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), i3[2]), e3(n3(e3(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), -r3[2]), n3(e3(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), s3[2]))), -c3[3])))), d3 = o3(l3, h3);
return d3[d3.length - 1];
};
}
function l2(e3) {
return (e3 === 3 ? s2 : e3 === 4 ? a2 : c2)(o2, n2, i2, r2);
}
var h2 = l2(3), d2 = l2(4), u2 = [function() {
return 0;
}, function() {
return 0;
}, function(e3, t3) {
return t3[0] - e3[0];
}, function(e3, t3, n3) {
var o3, i3 = (e3[1] - n3[1]) * (t3[0] - n3[0]), r3 = (e3[0] - n3[0]) * (t3[1] - n3[1]), s3 = i3 - r3;
if (i3 > 0) {
if (r3 <= 0)
return s3;
o3 = i3 + r3;
} else {
if (!(i3 < 0))
return s3;
if (r3 >= 0)
return s3;
o3 = -(i3 + r3);
}
var a3 = 0.00000000000000033306690738754716 * o3;
return s3 >= a3 || s3 <= -a3 ? s3 : h2(e3, t3, n3);
}, function(e3, t3, n3, o3) {
var i3 = e3[0] - o3[0], r3 = t3[0] - o3[0], s3 = n3[0] - o3[0], a3 = e3[1] - o3[1], c3 = t3[1] - o3[1], l3 = n3[1] - o3[1], h3 = e3[2] - o3[2], u3 = t3[2] - o3[2], p3 = n3[2] - o3[2], m3 = r3 * l3, g2 = s3 * c3, f2 = s3 * a3, _2 = i3 * l3, y2 = i3 * c3, b2 = r3 * a3, x2 = h3 * (m3 - g2) + u3 * (f2 - _2) + p3 * (y2 - b2), v2 = 0.0000000000000007771561172376103 * ((Math.abs(m3) + Math.abs(g2)) * Math.abs(h3) + (Math.abs(f2) + Math.abs(_2)) * Math.abs(u3) + (Math.abs(y2) + Math.abs(b2)) * Math.abs(p3));
return x2 > v2 || -x2 > v2 ? x2 : d2(e3, t3, n3, o3);
}];
function p2(e3) {
var t3 = u2[e3.length];
return t3 || (t3 = u2[e3.length] = l2(e3.length)), t3.apply(undefined, e3);
}
function m2(e3, t3, n3, o3, i3, r3, s3) {
return function(t4, n4, a3, c3, l3) {
switch (arguments.length) {
case 0:
case 1:
return 0;
case 2:
return o3(t4, n4);
case 3:
return i3(t4, n4, a3);
case 4:
return r3(t4, n4, a3, c3);
case 5:
return s3(t4, n4, a3, c3, l3);
}
for (var h3 = new Array(arguments.length), d3 = 0;d3 < arguments.length; ++d3)
h3[d3] = arguments[d3];
return e3(h3);
};
}
(function() {
for (;u2.length <= 5; )
u2.push(l2(u2.length));
t2.exports = m2.apply(undefined, [p2].concat(u2));
for (var e3 = 0;e3 <= 5; ++e3)
t2.exports[e3] = u2[e3];
})();
} });
var C = s({ "node_modules/cdt2d/lib/monotone.js"(e2, t2) {
var n2 = _(), o2 = S()[3];
function i2(e3, t3, n3, o3, i3) {
this.a = e3, this.b = t3, this.idx = n3, this.lowerIds = o3, this.upperIds = i3;
}
function r2(e3, t3, n3, o3) {
this.a = e3, this.b = t3, this.type = n3, this.idx = o3;
}
function s2(e3, t3) {
var n3 = e3.a[0] - t3.a[0] || e3.a[1] - t3.a[1] || e3.type - t3.type;
return n3 || (e3.type !== 0 && (n3 = o2(e3.a, e3.b, t3.b)) ? n3 : e3.idx - t3.idx);
}
function a2(e3, t3) {
return o2(e3.a, e3.b, t3);
}
function c2(e3, t3, i3, r3, s3) {
for (var c3 = n2.lt(t3, r3, a2), l3 = n2.gt(t3, r3, a2), h3 = c3;h3 < l3; ++h3) {
for (var d3 = t3[h3], u2 = d3.lowerIds, p2 = u2.length;p2 > 1 && o2(i3[u2[p2 - 2]], i3[u2[p2 - 1]], r3) > 0; )
e3.push([u2[p2 - 1], u2[p2 - 2], s3]), p2 -= 1;
u2.length = p2, u2.push(s3);
var m2 = d3.upperIds;
for (p2 = m2.length;p2 > 1 && o2(i3[m2[p2 - 2]], i3[m2[p2 - 1]], r3) < 0; )
e3.push([m2[p2 - 2], m2[p2 - 1], s3]), p2 -= 1;
m2.length = p2, m2.push(s3);
}
}
function l2(e3, t3) {
var n3;
return (n3 = e3.a[0] < t3.a[0] ? o2(e3.a, e3.b, t3.a) : o2(t3.b, t3.a, e3.a)) ? n3 : (n3 = t3.b[0] < e3.b[0] ? o2(e3.a, e3.b, t3.b) : o2(t3.b, t3.a, e3.b)) || e3.idx - t3.idx;
}
function h2(e3, t3, o3) {
var r3 = n2.le(e3, o3, l2), s3 = e3[r3], a3 = s3.upperIds, c3 = a3[a3.length - 1];
s3.upperIds = [c3], e3.splice(r3 + 1, 0, new i2(o3.a, o3.b, o3.idx, [c3], a3));
}
function d2(e3, t3, o3) {
var i3 = o3.a;
o3.a = o3.b, o3.b = i3;
var r3 = n2.eq(e3, o3, l2), s3 = e3[r3];
e3[r3 - 1].upperIds = s3.upperIds, e3.splice(r3, 1);
}
t2.exports = function(e3, t3) {
for (var n3 = e3.length, o3 = t3.length, a3 = [], l3 = 0;l3 < n3; ++l3)
a3.push(new r2(e3[l3], null, 0, l3));
for (l3 = 0;l3 < o3; ++l3) {
var u2 = t3[l3], p2 = e3[u2[0]], m2 = e3[u2[1]];
p2[0] < m2[0] ? a3.push(new r2(p2, m2, 2, l3), new r2(m2, p2, 1, l3)) : p2[0] > m2[0] && a3.push(new r2(m2, p2, 2, l3), new r2(p2, m2, 1, l3));
}
a3.sort(s2);
for (var g2 = a3[0].a[0] - (1 + Math.abs(a3[0].a[0])) * Math.pow(2, -52), f2 = [new i2([g2, 1], [g2, 0], -1, [], [])], _2 = [], y2 = (l3 = 0, a3.length);l3 < y2; ++l3) {
var b2 = a3[l3], x2 = b2.type;
x2 === 0 ? c2(_2, f2, e3, b2.a, b2.idx) : x2 === 2 ? h2(f2, e3, b2) : d2(f2, e3, b2);
}
return _2;
};
} });
var P = s({ "node_modules/cdt2d/lib/triangulation.js"(e2, t2) {
var n2 = _();
function o2(e3, t3) {
this.stars = e3, this.edges = t3;
}
t2.exports = function(e3, t3) {
for (var n3 = new Array(e3), i3 = 0;i3 < e3; ++i3)
n3[i3] = [];
return new o2(n3, t3);
};
var i2 = o2.prototype;
function r2(e3, t3, n3) {
for (var o3 = 1, i3 = e3.length;o3 < i3; o3 += 2)
if (e3[o3 - 1] === t3 && e3[o3] === n3)
return e3[o3 - 1] = e3[i3 - 2], e3[o3] = e3[i3 - 1], void (e3.length = i3 - 2);
}
i2.isConstraint = function() {
var e3 = [0, 0];
function t3(e4, t4) {
return e4[0] - t4[0] || e4[1] - t4[1];
}
return function(o3, i3) {
return e3[0] = Math.min(o3, i3), e3[1] = Math.max(o3, i3), n2.eq(this.edges, e3, t3) >= 0;
};
}(), i2.removeTriangle = function(e3, t3, n3) {
var o3 = this.stars;
r2(o3[e3], t3, n3), r2(o3[t3], n3, e3), r2(o3[n3], e3, t3);
}, i2.addTriangle = function(e3, t3, n3) {
var o3 = this.stars;
o3[e3].push(t3, n3), o3[t3].push(n3, e3), o3[n3].push(e3, t3);
}, i2.opposite = function(e3, t3) {
for (var n3 = this.stars[t3], o3 = 1, i3 = n3.length;o3 < i3; o3 += 2)
if (n3[o3] === e3)
return n3[o3 - 1];
return -1;
}, i2.flip = function(e3, t3) {
var n3 = this.opposite(e3, t3), o3 = this.opposite(t3, e3);
this.removeTriangle(e3, t3, n3), this.removeTriangle(t3, e3, o3), this.addTriangle(e3, o3, n3), this.addTriangle(t3, n3, o3);
}, i2.edges = function() {
for (var e3 = this.stars, t3 = [], n3 = 0, o3 = e3.length;n3 < o3; ++n3)
for (var i3 = e3[n3], r3 = 0, s2 = i3.length;r3 < s2; r3 += 2)
t3.push([i3[r3], i3[r3 + 1]]);
return t3;
}, i2.cells = function() {
for (var e3 = this.stars, t3 = [], n3 = 0, o3 = e3.length;n3 < o3; ++n3)
for (var i3 = e3[n3], r3 = 0, s2 = i3.length;r3 < s2; r3 += 2) {
var a2 = i3[r3], c2 = i3[r3 + 1];
n3 < Math.min(a2, c2) && t3.push([n3, a2, c2]);
}
return t3;
};
} });
var M = s({ "node_modules/robust-in-sphere/in-sphere.js"(e2, t2) {
var n2 = y(), o2 = b(), i2 = I(), r2 = v();
function s2(e3) {
return (e3 === 3 ? a2 : e3 === 4 ? c2 : e3 === 5 ? l2 : h2)(o2, i2, n2, r2);
}
function a2(e3, t3, n3, o3) {
return function(i3, r3, s3) {
var a3 = n3(i3[0], i3[0]), c3 = o3(a3, r3[0]), l3 = o3(a3, s3[0]), h3 = n3(r3[0], r3[0]), d3 = o3(h3, i3[0]), u3 = o3(h3, s3[0]), p3 = n3(s3[0], s3[0]), m2 = o3(p3, i3[0]), g2 = o3(p3, r3[0]), f2 = e3(t3(g2, u3), t3(d3, c3)), _2 = t3(m2, l3), y2 = t3(f2, _2);
return y2[y2.length - 1];
};
}
function c2(e3, t3, n3, o3) {
return function(i3, r3, s3, a3) {
var c3 = e3(n3(i3[0], i3[0]), n3(i3[1], i3[1])), l3 = o3(c3, r3[0]), h3 = o3(c3, s3[0]), d3 = o3(c3, a3[0]), u3 = e3(n3(r3[0], r3[0]), n3(r3[1], r3[1])), p3 = o3(u3, i3[0]), m2 = o3(u3, s3[0]), g2 = o3(u3, a3[0]), f2 = e3(n3(s3[0], s3[0]), n3(s3[1], s3[1])), _2 = o3(f2, i3[0]), y2 = o3(f2, r3[0]), b2 = o3(f2, a3[0]), x2 = e3(n3(a3[0], a3[0]), n3(a3[1], a3[1])), v2 = o3(x2, i3[0]), I2 = o3(x2, r3[0]), S2 = o3(x2, s3[0]), C2 = e3(e3(o3(t3(S2, b2), r3[1]), e3(o3(t3(I2, g2), -s3[1]), o3(t3(y2, m2), a3[1]))), e3(o3(t3(I2, g2), i3[1]), e3(o3(t3(v2, d3), -r3[1]), o3(t3(p3, l3), a3[1])))), P2 = e3(e3(o3(t3(S2, b2), i3[1]), e3(o3(t3(v2, d3), -s3[1]), o3(t3(_2, h3), a3[1]))), e3(o3(t3(y2, m2), i3[1]), e3(o3(t3(_2, h3), -r3[1]), o3(t3(p3, l3), s3[1])))), M2 = t3(C2, P2);
return M2[M2.length - 1];
};
}
function l2(e3, t3, n3, o3) {
return function(i3, r3, s3, a3, c3) {
var l3 = e3(n3(i3[0], i3[0]), e3(n3(i3[1], i3[1]), n3(i3[2], i3[2]))), h3 = o3(l3, r3[0]), d3 = o3(l3, s3[0]), u3 = o3(l3, a3[0]), p3 = o3(l3, c3[0]), m2 = e3(n3(r3[0], r3[0]), e3(n3(r3[1], r3[1]), n3(r3[2], r3[2]))), g2 = o3(m2, i3[0]), f2 = o3(m2, s3[0]), _2 = o3(m2, a3[0]), y2 = o3(m2, c3[0]), b2 = e3(n3(s3[0], s3[0]), e3(n3(s3[1], s3[1]), n3(s3[2], s3[2]))), x2 = o3(b2, i3[0]), v2 = o3(b2, r3[0]), I2 = o3(b2, a3[0]), S2 = o3(b2, c3[0]), C2 = e3(n3(a3[0], a3[0]), e3(n3(a3[1], a3[1]), n3(a3[2], a3[2]))), P2 = o3(C2, i3[0]), M2 = o3(C2, r3[0]), w = o3(C2, s3[0]), N = o3(C2, c3[0]), T = e3(n3(c3[0], c3[0]), e3(n3(c3[1], c3[1]), n3(c3[2], c3[2]))), R = o3(T, i3[0]), E = o3(T, r3[0]), A = o3(T, s3[0]), O = o3(T, a3[0]), k = e3(e3(e3(o3(e3(o3(t3(O, N), s3[1]), e3(o3(t3(A, S2), -a3[1]), o3(t3(w, I2), c3[1]))), r3[2]), e3(o3(e3(o3(t3(O, N), r3[1]), e3(o3(t3(E, y2), -a3[1]), o3(t3(M2, _2), c3[1]))), -s3[2]), o3(e3(o3(t3(A, S2), r3[1]), e3(o3(t3(E, y2), -s3[1]), o3(t3(v2, f2), c3[1]))), a3[2]))), e3(o3(e3(o3(t3(w, I2), r3[1]), e3(o3(t3(M2, _2), -s3[1]), o3(t3(v2, f2), a3[1]))), -c3[2]), e3(o3(e3(o3(t3(O, N), r3[1]), e3(o3(t3(E, y2), -a3[1]), o3(t3(M2, _2), c3[1]))), i3[2]), o3(e3(o3(t3(O, N), i3[1]), e3(o3(t3(R, p3), -a3[1]), o3(t3(P2, u3), c3[1]))), -r3[2])))), e3(e3(o3(e3(o3(t3(E, y2), i3[1]), e3(o3(t3(R, p3), -r3[1]), o3(t3(g2, h3), c3[1]))), a3[2]), e3(o3(e3(o3(t3(M2, _2), i3[1]), e3(o3(t3(P2, u3), -r3[1]), o3(t3(g2, h3), a3[1]))), -c3[2]), o3(e3(o3(t3(w, I2), r3[1]), e3(o3(t3(M2, _2), -s3[1]), o3(t3(v2, f2), a3[1]))), i3[2]))), e3(o3(e3(o3(t3(w, I2), i3[1]), e3(o3(t3(P2, u3), -s3[1]), o3(t3(x2, d3), a3[1]))), -r3[2]), e3(o3(e3(o3(t3(M2, _2), i3[1]), e3(o3(t3(P2, u3), -r3[1]), o3(t3(g2, h3), a3[1]))), s3[2]), o3(e3(o3(t3(v2, f2), i3[1]), e3(o3(t3(x2, d3), -r3[1]), o3(t3(g2, h3), s3[1]))), -a3[2]))))), D = e3(e3(e3(o3(e3(o3(t3(O, N), s3[1]), e3(o3(t3(A, S2), -a3[1]), o3(t3(w, I2), c3[1]))), i3[2]), o3(e3(o3(t3(O, N), i3[1]), e3(o3(t3(R, p3), -a3[1]), o3(t3(P2, u3), c3[1]))), -s3[2])), e3(o3(e3(o3(t3(A, S2), i3[1]), e3(o3(t3(R, p3), -s3[1]), o3(t3(x2, d3), c3[1]))), a3[2]), o3(e3(o3(t3(w, I2), i3[1]), e3(o3(t3(P2, u3), -s3[1]), o3(t3(x2, d3), a3[1]))), -c3[2]))), e3(e3(o3(e3(o3(t3(A, S2), r3[1]), e3(o3(t3(E, y2), -s3[1]), o3(t3(v2, f2), c3[1]))), i3[2]), o3(e3(o3(t3(A, S2), i3[1]), e3(o3(t3(R, p3), -s3[1]), o3(t3(x2, d3), c3[1]))), -r3[2])), e3(o3(e3(o3(t3(E, y2), i3[1]), e3(o3(t3(R, p3), -r3[1]), o3(t3(g2, h3), c3[1]))), s3[2]), o3(e3(o3(t3(v2, f2), i3[1]), e3(o3(t3(x2, d3), -r3[1]), o3(t3(g2, h3), s3[1]))), -c3[2])))), L = t3(k, D);
return L[L.length - 1];
};
}
function h2(e3, t3, n3, o3) {
return function(i3, r3, s3, a3, c3, l3) {
var h3 = e3(e3(n3(i3[0], i3[0]), n3(i3[1], i3[1])), e3(n3(i3[2], i3[2]), n3(i3[3], i3[3]))), d3 = o3(h3, r3[0]), u3 = o3(h3, s3[0]), p3 = o3(h3, a3[0]), m2 = o3(h3, c3[0]), g2 = o3(h3, l3[0]), f2 = e3(e3(n3(r3[0], r3[0]), n3(r3[1], r3[1])), e3(n3(r3[2], r3[2]), n3(r3[3], r3[3]))), _2 = o3(f2, i3[0]), y2 = o3(f2, s3[0]), b2 = o3(f2, a3[0]), x2 = o3(f2, c3[0]), v2 = o3(f2, l3[0]), I2 = e3(e3(n3(s3[0], s3[0]), n3(s3[1], s3[1])), e3(n3(s3[2], s3[2]), n3(s3[3], s3[3]))), S2 = o3(I2, i3[0]), C2 = o3(I2, r3[0]), P2 = o3(I2, a3[0]), M2 = o3(I2, c3[0]), w = o3(I2, l3[0]), N = e3(e3(n3(a3[0], a3[0]), n3(a3[1], a3[1])), e3(n3(a3[2], a3[2]), n3(a3[3], a3[3]))), T = o3(N, i3[0]), R = o3(N, r3[0]), E = o3(N, s3[0]), A = o3(N, c3[0]), O = o3(N, l3[0]), k = e3(e3(n3(c3[0], c3[0]), n3(c3[1], c3[1])), e3(n3(c3[2], c3[2]), n3(c3[3], c3[3]))), D = o3(k, i3[0]), L = o3(k, r3[0]), z = o3(k, s3[0]), B = o3(k, a3[0]), F = o3(k, l3[0]), j = e3(e3(n3(l3[0], l3[0]), n3(l3[1], l3[1])), e3(n3(l3[2], l3[2]), n3(l3[3], l3[3]))), $ = o3(j, i3[0]), Y = o3(j, r3[0]), X = o3(j, s3[0]), W = o3(j, a3[0]), V = o3(j, c3[0]), H = e3(e3(e3(o3(e3(e3(o3(e3(o3(t3(V, F), a3[1]), e3(o3(t3(W, O), -c3[1]), o3(t3(B, A), l3[1]))), s3[2]), o3(e3(o3(t3(V, F), s3[1]), e3(o3(t3(X, w), -c3[1]), o3(t3(z, M2), l3[1]))), -a3[2])), e3(o3(e3(o3(t3(W, O), s3[1]), e3(o3(t3(X, w), -a3[1]), o3(t3(E, P2), l3[1]))), c3[2]), o3(e3(o3(t3(B, A), s3[1]), e3(o3(t3(z, M2), -a3[1]), o3(t3(E, P2), c3[1]))), -l3[2]))), r3[3]), e3(o3(e3(e3(o3(e3(o3(t3(V, F), a3[1]), e3(o3(t3(W, O), -c3[1]), o3(t3(B, A), l3[1]))), r3[2]), o3(e3(o3(t3(V, F), r3[1]), e3(o3(t3(Y, v2), -c3[1]), o3(t3(L, x2), l3[1]))), -a3[2])), e3(o3(e3(o3(t3(W, O), r3[1]), e3(o3(t3(Y, v2), -a3[1]), o3(t3(R, b2), l3[1]))), c3[2]), o3(e3(o3(t3(B, A), r3[1]), e3(o3(t3(L, x2), -a3[1]), o3(t3(R, b2), c3[1]))), -l3[2]))), -s3[3]), o3(e3(e3(o3(e3(o3(t3(V, F), s3[1]), e3(o3(t3(X, w), -c3[1]), o3(t3(z, M2), l3[1]))), r3[2]), o3(e3(o3(t3(V, F), r3[1]), e3(o3(t3(Y, v2), -c3[1]), o3(t3(L, x2), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), r3[1]), e3(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), c3[2]), o3(e3(o3(t3(z, M2), r3[1]), e3(o3(t3(L, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), -l3[2]))), a3[3]))), e3(e3(o3(e3(e3(o3(e3(o3(t3(W, O), s3[1]), e3(o3(t3(X, w), -a3[1]), o3(t3(E, P2), l3[1]))), r3[2]), o3(e3(o3(t3(W, O), r3[1]), e3(o3(t3(Y, v2), -a3[1]), o3(t3(R, b2), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), r3[1]), e3(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), a3[2]), o3(e3(o3(t3(E, P2), r3[1]), e3(o3(t3(R, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -l3[2]))), -c3[3]), o3(e3(e3(o3(e3(o3(t3(B, A), s3[1]), e3(o3(t3(z, M2), -a3[1]), o3(t3(E, P2), c3[1]))), r3[2]), o3(e3(o3(t3(B, A), r3[1]), e3(o3(t3(L, x2), -a3[1]), o3(t3(R, b2), c3[1]))), -s3[2])), e3(o3(e3(o3(t3(z, M2), r3[1]), e3(o3(t3(L, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), a3[2]), o3(e3(o3(t3(E, P2), r3[1]), e3(o3(t3(R, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -c3[2]))), l3[3])), e3(o3(e3(e3(o3(e3(o3(t3(V, F), a3[1]), e3(o3(t3(W, O), -c3[1]), o3(t3(B, A), l3[1]))), r3[2]), o3(e3(o3(t3(V, F), r3[1]), e3(o3(t3(Y, v2), -c3[1]), o3(t3(L, x2), l3[1]))), -a3[2])), e3(o3(e3(o3(t3(W, O), r3[1]), e3(o3(t3(Y, v2), -a3[1]), o3(t3(R, b2), l3[1]))), c3[2]), o3(e3(o3(t3(B, A), r3[1]), e3(o3(t3(L, x2), -a3[1]), o3(t3(R, b2), c3[1]))), -l3[2]))), i3[3]), o3(e3(e3(o3(e3(o3(t3(V, F), a3[1]), e3(o3(t3(W, O), -c3[1]), o3(t3(B, A), l3[1]))), i3[2]), o3(e3(o3(t3(V, F), i3[1]), e3(o3(t3($, g2), -c3[1]), o3(t3(D, m2), l3[1]))), -a3[2])), e3(o3(e3(o3(t3(W, O), i3[1]), e3(o3(t3($, g2), -a3[1]), o3(t3(T, p3), l3[1]))), c3[2]), o3(e3(o3(t3(B, A), i3[1]), e3(o3(t3(D, m2), -a3[1]), o3(t3(T, p3), c3[1]))), -l3[2]))), -r3[3])))), e3(e3(e3(o3(e3(e3(o3(e3(o3(t3(V, F), r3[1]), e3(o3(t3(Y, v2), -c3[1]), o3(t3(L, x2), l3[1]))), i3[2]), o3(e3(o3(t3(V, F), i3[1]), e3(o3(t3($, g2), -c3[1]), o3(t3(D, m2), l3[1]))), -r3[2])), e3(o3(e3(o3(t3(Y, v2), i3[1]), e3(o3(t3($, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), c3[2]), o3(e3(o3(t3(L, x2), i3[1]), e3(o3(t3(D, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), -l3[2]))), a3[3]), o3(e3(e3(o3(e3(o3(t3(W, O), r3[1]), e3(o3(t3(Y, v2), -a3[1]), o3(t3(R, b2), l3[1]))), i3[2]), o3(e3(o3(t3(W, O), i3[1]), e3(o3(t3($, g2), -a3[1]), o3(t3(T, p3), l3[1]))), -r3[2])), e3(o3(e3(o3(t3(Y, v2), i3[1]), e3(o3(t3($, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), a3[2]), o3(e3(o3(t3(R, b2), i3[1]), e3(o3(t3(T, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -l3[2]))), -c3[3])), e3(o3(e3(e3(o3(e3(o3(t3(B, A), r3[1]), e3(o3(t3(L, x2), -a3[1]), o3(t3(R, b2), c3[1]))), i3[2]), o3(e3(o3(t3(B, A), i3[1]), e3(o3(t3(D, m2), -a3[1]), o3(t3(T, p3), c3[1]))), -r3[2])), e3(o3(e3(o3(t3(L, x2), i3[1]), e3(o3(t3(D, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), a3[2]), o3(e3(o3(t3(R, b2), i3[1]), e3(o3(t3(T, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -c3[2]))), l3[3]), o3(e3(e3(o3(e3(o3(t3(W, O), s3[1]), e3(o3(t3(X, w), -a3[1]), o3(t3(E, P2), l3[1]))), r3[2]), o3(e3(o3(t3(W, O), r3[1]), e3(o3(t3(Y, v2), -a3[1]), o3(t3(R, b2), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), r3[1]), e3(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), a3[2]), o3(e3(o3(t3(E, P2), r3[1]), e3(o3(t3(R, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -l3[2]))), i3[3]))), e3(e3(o3(e3(e3(o3(e3(o3(t3(W, O), s3[1]), e3(o3(t3(X, w), -a3[1]), o3(t3(E, P2), l3[1]))), i3[2]), o3(e3(o3(t3(W, O), i3[1]), e3(o3(t3($, g2), -a3[1]), o3(t3(T, p3), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), i3[1]), e3(o3(t3($, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), a3[2]), o3(e3(o3(t3(E, P2), i3[1]), e3(o3(t3(T, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -l3[2]))), -r3[3]), o3(e3(e3(o3(e3(o3(t3(W, O), r3[1]), e3(o3(t3(Y, v2), -a3[1]), o3(t3(R, b2), l3[1]))), i3[2]), o3(e3(o3(t3(W, O), i3[1]), e3(o3(t3($, g2), -a3[1]), o3(t3(T, p3), l3[1]))), -r3[2])), e3(o3(e3(o3(t3(Y, v2), i3[1]), e3(o3(t3($, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), a3[2]), o3(e3(o3(t3(R, b2), i3[1]), e3(o3(t3(T, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -l3[2]))), s3[3])), e3(o3(e3(e3(o3(e3(o3(t3(X, w), r3[1]), e3(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), i3[2]), o3(e3(o3(t3(X, w), i3[1]), e3(o3(t3($, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), -r3[2])), e3(o3(e3(o3(t3(Y, v2), i3[1]), e3(o3(t3($, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), s3[2]), o3(e3(o3(t3(C2, y2), i3[1]), e3(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -l3[2]))), -a3[3]), o3(e3(e3(o3(e3(o3(t3(E, P2), r3[1]), e3(o3(t3(R, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), i3[2]), o3(e3(o3(t3(E, P2), i3[1]), e3(o3(t3(T, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -r3[2])), e3(o3(e3(o3(t3(R, b2), i3[1]), e3(o3(t3(T, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), s3[2]), o3(e3(o3(t3(C2, y2), i3[1]), e3(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -a3[2]))), l3[3]))))), G = e3(e3(e3(o3(e3(e3(o3(e3(o3(t3(V, F), a3[1]), e3(o3(t3(W, O), -c3[1]), o3(t3(B, A), l3[1]))), s3[2]), o3(e3(o3(t3(V, F), s3[1]), e3(o3(t3(X, w), -c3[1]), o3(t3(z, M2), l3[1]))), -a3[2])), e3(o3(e3(o3(t3(W, O), s3[1]), e3(o3(t3(X, w), -a3[1]), o3(t3(E, P2), l3[1]))), c3[2]), o3(e3(o3(t3(B, A), s3[1]), e3(o3(t3(z, M2), -a3[1]), o3(t3(E, P2), c3[1]))), -l3[2]))), i3[3]), e3(o3(e3(e3(o3(e3(o3(t3(V, F), a3[1]), e3(o3(t3(W, O), -c3[1]), o3(t3(B, A), l3[1]))), i3[2]), o3(e3(o3(t3(V, F), i3[1]), e3(o3(t3($, g2), -c3[1]), o3(t3(D, m2), l3[1]))), -a3[2])), e3(o3(e3(o3(t3(W, O), i3[1]), e3(o3(t3($, g2), -a3[1]), o3(t3(T, p3), l3[1]))), c3[2]), o3(e3(o3(t3(B, A), i3[1]), e3(o3(t3(D, m2), -a3[1]), o3(t3(T, p3), c3[1]))), -l3[2]))), -s3[3]), o3(e3(e3(o3(e3(o3(t3(V, F), s3[1]), e3(o3(t3(X, w), -c3[1]), o3(t3(z, M2), l3[1]))), i3[2]), o3(e3(o3(t3(V, F), i3[1]), e3(o3(t3($, g2), -c3[1]), o3(t3(D, m2), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), i3[1]), e3(o3(t3($, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), c3[2]), o3(e3(o3(t3(z, M2), i3[1]), e3(o3(t3(D, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -l3[2]))), a3[3]))), e3(e3(o3(e3(e3(o3(e3(o3(t3(W, O), s3[1]), e3(o3(t3(X, w), -a3[1]), o3(t3(E, P2), l3[1]))), i3[2]), o3(e3(o3(t3(W, O), i3[1]), e3(o3(t3($, g2), -a3[1]), o3(t3(T, p3), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), i3[1]), e3(o3(t3($, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), a3[2]), o3(e3(o3(t3(E, P2), i3[1]), e3(o3(t3(T, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -l3[2]))), -c3[3]), o3(e3(e3(o3(e3(o3(t3(B, A), s3[1]), e3(o3(t3(z, M2), -a3[1]), o3(t3(E, P2), c3[1]))), i3[2]), o3(e3(o3(t3(B, A), i3[1]), e3(o3(t3(D, m2), -a3[1]), o3(t3(T, p3), c3[1]))), -s3[2])), e3(o3(e3(o3(t3(z, M2), i3[1]), e3(o3(t3(D, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), a3[2]), o3(e3(o3(t3(E, P2), i3[1]), e3(o3(t3(T, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -c3[2]))), l3[3])), e3(o3(e3(e3(o3(e3(o3(t3(V, F), s3[1]), e3(o3(t3(X, w), -c3[1]), o3(t3(z, M2), l3[1]))), r3[2]), o3(e3(o3(t3(V, F), r3[1]), e3(o3(t3(Y, v2), -c3[1]), o3(t3(L, x2), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), r3[1]), e3(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), c3[2]), o3(e3(o3(t3(z, M2), r3[1]), e3(o3(t3(L, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), -l3[2]))), i3[3]), o3(e3(e3(o3(e3(o3(t3(V, F), s3[1]), e3(o3(t3(X, w), -c3[1]), o3(t3(z, M2), l3[1]))), i3[2]), o3(e3(o3(t3(V, F), i3[1]), e3(o3(t3($, g2), -c3[1]), o3(t3(D, m2), l3[1]))), -s3[2])), e3(o3(e3(o3(t3(X, w), i3[1]), e3(o3(t3($, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), c3[2]), o3(e3(o3(t3(z, M2), i3[1]), e3(o3(t3(D, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -l3[2]))), -r3[3])))), e3(e3(e3(o3(e3(e3(o3(e3(o3(t3(V, F), r3[1]), e3(o3(t3(Y, v2), -c3[1]), o3(t3(L, x2), l3[1]))), i3[2]), o3(e3(o3(t3(V, F), i3[1]), e3(o3(t3($, g2), -c3[1]), o3(t3(D, m2), l3[1]))), -r3[2])), e3(o3(e3(o3(t3(Y, v2), i3[1]), e3(o3(t3($, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), c3[2]), o3(e3(o3(t3(L, x2), i3[1]), e3(o3(t3(D, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), -l3[2]))), s3[3]), o3(e3(e3(o3(e3(o3(t3(X, w), r3[1]), e3(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), i3[2]), o3(e3(o3(t3(X, w), i3[1]), e3(o3(t3($, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), -r3[2])), e3(o3(e3(o3(t3(Y, v2), i3[1]), e3(o3(t3($, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), s3[2]), o3(e3(o3(t3(C2, y2), i3[1]), e3(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -l3[2]))), -c3[3])), e3(o3(e3(e3(o3(e3(o3(t3(z, M2), r3[1]), e3(o3(t3(L, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), i3[2]), o3(e3(o3(t3(z, M2), i3[1]), e3(o3(t3(D, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -r3[2])), e3(o3(e3(o3(t3(L, x2), i3[1]), e3(o3(t3(D, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), s3[2]), o3(e3(o3(t3(C2, y2), i3[1]), e3(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -c3[2]))), l3[3]), o3(e3(e3(o3(e3(o3(t3(B, A), s3[1]), e3(o3(t3(z, M2), -a3[1]), o3(t3(E, P2), c3[1]))), r3[2]), o3(e3(o3(t3(B, A), r3[1]), e3(o3(t3(L, x2), -a3[1]), o3(t3(R, b2), c3[1]))), -s3[2])), e3(o3(e3(o3(t3(z, M2), r3[1]), e3(o3(t3(L, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), a3[2]), o3(e3(o3(t3(E, P2), r3[1]), e3(o3(t3(R, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -c3[2]))), i3[3]))), e3(e3(o3(e3(e3(o3(e3(o3(t3(B, A), s3[1]), e3(o3(t3(z, M2), -a3[1]), o3(t3(E, P2), c3[1]))), i3[2]), o3(e3(o3(t3(B, A), i3[1]), e3(o3(t3(D, m2), -a3[1]), o3(t3(T, p3), c3[1]))), -s3[2])), e3(o3(e3(o3(t3(z, M2), i3[1]), e3(o3(t3(D, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), a3[2]), o3(e3(o3(t3(E, P2), i3[1]), e3(o3(t3(T, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -c3[2]))), -r3[3]), o3(e3(e3(o3(e3(o3(t3(B, A), r3[1]), e3(o3(t3(L, x2), -a3[1]), o3(t3(R, b2), c3[1]))), i3[2]), o3(e3(o3(t3(B, A), i3[1]), e3(o3(t3(D, m2), -a3[1]), o3(t3(T, p3), c3[1]))), -r3[2])), e3(o3(e3(o3(t3(L, x2), i3[1]), e3(o3(t3(D, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), a3[2]), o3(e3(o3(t3(R, b2), i3[1]), e3(o3(t3(T, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -c3[2]))), s3[3])), e3(o3(e3(e3(o3(e3(o3(t3(z, M2), r3[1]), e3(o3(t3(L, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), i3[2]), o3(e3(o3(t3(z, M2), i3[1]), e3(o3(t3(D, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -r3[2])), e3(o3(e3(o3(t3(L, x2), i3[1]), e3(o3(t3(D, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), s3[2]), o3(e3(o3(t3(C2, y2), i3[1]), e3(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -c3[2]))), -a3[3]), o3(e3(e3(o3(e3(o3(t3(E, P2), r3[1]), e3(o3(t3(R, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), i3[2]), o3(e3(o3(t3(E, P2), i3[1]), e3(o3(t3(T, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -r3[2])), e3(o3(e3(o3(t3(R, b2), i3[1]), e3(o3(t3(T, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), s3[2]), o3(e3(o3(t3(C2, y2), i3[1]), e3(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -a3[2]))), c3[3]))))), U = t3(H, G);
return U[U.length - 1];
};
}
var d2 = [function() {
return 0;
}, function() {
return 0;
}, function() {
return 0;
}];
function u2(e3) {
var t3 = d2[e3.length];
return t3 || (t3 = d2[e3.length] = s2(e3.length)), t3.apply(undefined, e3);
}
function p2(e3, t3, n3, o3, i3, r3, s3, a3) {
return function(t4, n4, c3, l3, h3, d3) {
switch (arguments.length) {
case 0:
case 1:
return 0;
case 2:
return o3(t4, n4);
case 3:
return i3(t4, n4, c3);
case 4:
return r3(t4, n4, c3, l3);
case 5:
return s3(t4, n4, c3, l3, h3);
case 6:
return a3(t4, n4, c3, l3, h3, d3);
}
for (var u3 = new Array(arguments.length), p3 = 0;p3 < arguments.length; ++p3)
u3[p3] = arguments[p3];
return e3(u3);
};
}
(function() {
for (;d2.length <= 6; )
d2.push(s2(d2.length));
t2.exports = p2.apply(undefined, [u2].concat(d2));
for (var e3 = 0;e3 <= 6; ++e3)
t2.exports[e3] = d2[e3];
})();
} });
var w = s({ "node_modules/cdt2d/lib/delaunay.js"(e2, t2) {
var n2 = M()[4];
_();
function o2(e3, t3, o3, i2, r2, s2) {
var a2 = t3.opposite(i2, r2);
if (!(a2 < 0)) {
if (r2 < i2) {
var c2 = i2;
i2 = r2, r2 = c2, c2 = s2, s2 = a2, a2 = c2;
}
t3.isConstraint(i2, r2) || n2(e3[i2], e3[r2], e3[s2], e3[a2]) < 0 && o3.push(i2, r2);
}
}
t2.exports = function(e3, t3) {
for (var i2 = [], r2 = e3.length, s2 = t3.stars, a2 = 0;a2 < r2; ++a2)
for (var c2 = s2[a2], l2 = 1;l2 < c2.length; l2 += 2) {
if (!((p2 = c2[l2]) < a2) && !t3.isConstraint(a2, p2)) {
for (var h2 = c2[l2 - 1], d2 = -1, u2 = 1;u2 < c2.length; u2 += 2)
if (c2[u2 - 1] === p2) {
d2 = c2[u2];
break;
}
d2 < 0 || n2(e3[a2], e3[p2], e3[h2], e3[d2]) < 0 && i2.push(a2, p2);
}
}
for (;i2.length > 0; ) {
for (var p2 = i2.pop(), m2 = (h2 = -1, d2 = -1, c2 = s2[a2 = i2.pop()], 1);m2 < c2.length; m2 += 2) {
var g2 = c2[m2 - 1], f2 = c2[m2];
g2 === p2 ? d2 = f2 : f2 === p2 && (h2 = g2);
}
h2 < 0 || d2 < 0 || (n2(e3[a2], e3[p2], e3[h2], e3[d2]) >= 0 || (t3.flip(a2, p2), o2(e3, t3, i2, h2, a2, d2), o2(e3, t3, i2, a2, d2, h2), o2(e3, t3, i2, d2, p2, h2), o2(e3, t3, i2, p2, h2, d2)));
}
};
} });
var N = s({ "node_modules/cdt2d/lib/filter.js"(e2, t2) {
var n2 = _();
function o2(e3, t3, n3, o3, i3, r2, s2) {
this.cells = e3, this.neighbor = t3, this.flags = o3, this.constraint = n3, this.active = i3, this.next = r2, this.boundary = s2;
}
function i2(e3, t3) {
return e3[0] - t3[0] || e3[1] - t3[1] || e3[2] - t3[2];
}
t2.exports = function(e3, t3, n3) {
var r2 = function(e4, t4) {
for (var n4 = e4.cells(), r3 = n4.length, s3 = 0;s3 < r3; ++s3) {
var a3 = (_3 = n4[s3])[0], c3 = _3[1], l3 = _3[2];
c3 < l3 ? c3 < a3 && (_3[0] = c3, _3[1] = l3, _3[2] = a3) : l3 < a3 && (_3[0] = l3, _3[1] = a3, _3[2] = c3);
}
n4.sort(i2);
var h3 = new Array(r3);
for (s3 = 0;s3 < h3.length; ++s3)
h3[s3] = 0;
var d3 = [], u3 = [], p3 = new Array(3 * r3), m3 = new Array(3 * r3), g3 = null;
t4 && (g3 = []);
var f3 = new o2(n4, p3, m3, h3, d3, u3, g3);
for (s3 = 0;s3 < r3; ++s3)
for (var _3 = n4[s3], y2 = 0;y2 < 3; ++y2) {
a3 = _3[y2], c3 = _3[(y2 + 1) % 3];
var b2 = p3[3 * s3 + y2] = f3.locate(c3, a3, e4.opposite(c3, a3)), x2 = m3[3 * s3 + y2] = e4.isConstraint(a3, c3);
b2 < 0 && (x2 ? u3.push(s3) : (d3.push(s3), h3[s3] = 1), t4 && g3.push([c3, a3, -1]));
}
return f3;
}(e3, n3);
if (t3 === 0)
return n3 ? r2.cells.concat(r2.boundary) : r2.cells;
var s2 = 1, a2 = r2.active, c2 = r2.next, l2 = r2.flags, h2 = r2.cells, d2 = r2.constraint, u2 = r2.neighbor;
for (;a2.length > 0 || c2.length > 0; ) {
for (;a2.length > 0; ) {
var p2 = a2.pop();
if (l2[p2] !== -s2) {
l2[p2] = s2;
h2[p2];
for (var m2 = 0;m2 < 3; ++m2) {
var g2 = u2[3 * p2 + m2];
g2 >= 0 && l2[g2] === 0 && (d2[3 * p2 + m2] ? c2.push(g2) : (a2.push(g2), l2[g2] = s2));
}
}
}
var f2 = c2;
c2 = a2, a2 = f2, c2.length = 0, s2 = -s2;
}
var _2 = function(e4, t4, n4) {
for (var o3 = 0, i3 = 0;i3 < e4.length; ++i3)
t4[i3] === n4 && (e4[o3++] = e4[i3]);
return e4.length = o3, e4;
}(h2, l2, t3);
if (n3)
return _2.concat(r2.boundary);
return _2;
}, o2.prototype.locate = function() {
var e3 = [0, 0, 0];
return function(t3, o3, r2) {
var s2 = t3, a2 = o3, c2 = r2;
return o3 < r2 ? o3 < t3 && (s2 = o3, a2 = r2, c2 = t3) : r2 < t3 && (s2 = r2, a2 = t3, c2 = o3), s2 < 0 ? -1 : (e3[0] = s2, e3[1] = a2, e3[2] = c2, n2.eq(this.cells, e3, i2));
};
}();
} });
var T = s({ "node_modules/cdt2d/cdt2d.js"(e2, t2) {
var n2 = C(), o2 = P(), i2 = w(), r2 = N();
function s2(e3) {
return [Math.min(e3[0], e3[1]), Math.max(e3[0], e3[1])];
}
function a2(e3, t3) {
return e3[0] - t3[0] || e3[1] - t3[1];
}
function c2(e3, t3, n3) {
return t3 in e3 ? e3[t3] : n3;
}
t2.exports = function(e3, t3, l2) {
Array.isArray(t3) ? (l2 = l2 || {}, t3 = t3 || []) : (l2 = t3 || {}, t3 = []);
var h2 = !!c2(l2, "delaunay", true), d2 = !!c2(l2, "interior", true), u2 = !!c2(l2, "exterior", true), p2 = !!c2(l2, "infinity", false);
if (!d2 && !u2 || e3.length === 0)
return [];
var m2 = n2(e3, t3);
if (h2 || d2 !== u2 || p2) {
for (var g2 = o2(e3.length, function(e4) {
return e4.map(s2).sort(a2);
}(t3)), f2 = 0;f2 < m2.length; ++f2) {
var _2 = m2[f2];
g2.addTriangle(_2[0], _2[1], _2[2]);
}
return h2 && i2(e3, g2), u2 ? d2 ? p2 ? r2(g2, 0, p2) : g2.cells() : r2(g2, 1, p2) : r2(g2, -1);
}
return m2;
};
} });
function R(e2, t2) {
return Array.isArray(t2) ? [e2.a * t2[0] + e2.c * t2[1] + e2.e, e2.b * t2[0] + e2.d * t2[1] + e2.f] : { x: e2.a * t2.x + e2.c * t2.y + e2.e, y: e2.b * t2.x + e2.d * t2.y + e2.f };
}
function E(e2, t2) {
return t2.map((t3) => R(e2, t3));
}
function A(e2) {
const { a: t2, b: n2, c: o2, d: i2, e: r2, f: s2 } = e2, a2 = t2 * i2 - n2 * o2;
return { a: i2 / a2, b: n2 / -a2, c: o2 / -a2, d: t2 / a2, e: (i2 * r2 - o2 * s2) / -a2, f: (n2 * r2 - t2 * s2) / a2 };
}
function O(e2) {
return e2 === undefined;
}
function k(e2, t2 = 0) {
return { a: 1, c: 0, e: e2, b: 0, d: 1, f: t2 };
}
function D(...e2) {
const t2 = (e3, t3) => ({ a: e3.a * t3.a + e3.c * t3.b, c: e3.a * t3.c + e3.c * t3.d, e: e3.a * t3.e + e3.c * t3.f + e3.e, b: e3.b * t3.a + e3.d * t3.b, d: e3.b * t3.c + e3.d * t3.d, f: e3.b * t3.e + e3.d * t3.f + e3.f });
switch ((e2 = Array.isArray(e2[0]) ? e2[0] : e2).length) {
case 0:
throw new Error("no matrices provided");
case 1:
return e2[0];
case 2:
return t2(e2[0], e2[1]);
default: {
const [n2, o2, ...i2] = e2;
return D(t2(n2, o2), ...i2);
}
}
}
function L(...e2) {
return D(...e2);
}
var { cos: z, sin: B, PI: F } = Math;
function j(e2, t2, n2) {
const o2 = z(e2), i2 = B(e2), r2 = { a: o2, c: -i2, e: 0, b: i2, d: o2, f: 0 };
return O(t2) || O(n2) ? r2 : D([k(t2, n2), r2, k(-t2, -n2)]);
}
function $(e2, t2 = undefined, n2 = undefined) {
return j(e2 * F / 180, t2, n2);
}
(c(u()), c(f()), new TextEncoder, (() => {
const e2 = new Uint8Array(4);
new Uint32Array(e2.buffer)[0] = 1, e2[0];
})(), []);
var W = new Uint16Array([255]);
var V = (new Uint8Array(W.buffer)[0], new Uint16Array([255]));
new Uint8Array(V.buffer)[0], new TextDecoder("latin1");
function H() {
return H = Object.assign ? Object.assign.bind() : function(e2) {
for (var t2 = 1;t2 < arguments.length; t2++) {
var n2 = arguments[t2];
for (var o2 in n2)
({}).hasOwnProperty.call(n2, o2) && (e2[o2] = n2[o2]);
}
return e2;
}, H.apply(null, arguments);
}
function G(e2, t2) {
return (G = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(e3, t3) {
return e3.__proto__ = t3, e3;
})(e2, t2);
}
function U(e2) {
return (U = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(e3) {
return e3.__proto__ || Object.getPrototypeOf(e3);
})(e2);
}
function Z() {
try {
var e2 = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
} catch (e3) {}
return (Z = function() {
return !!e2;
})();
}
function q(e2) {
var t2 = typeof Map == "function" ? new Map : undefined;
return q = function(e3) {
if (e3 === null || !function(e4) {
try {
return Function.toString.call(e4).indexOf("[native code]") !== -1;
} catch (t3) {
return typeof e4 == "function";
}
}(e3))
return e3;
if (typeof e3 != "function")
throw new TypeError("Super expression must either be null or a function");
if (t2 !== undefined) {
if (t2.has(e3))
return t2.get(e3);
t2.set(e3, n2);
}
function n2() {
return function(e4, t3, n3) {
if (Z())
return Reflect.construct.apply(null, arguments);
var o2 = [null];
o2.push.apply(o2, t3);
var i2 = new (e4.bind.apply(e4, o2));
return n3 && G(i2, n3.prototype), i2;
}(e3, arguments, U(this).constructor);
}
return n2.prototype = Object.create(e3.prototype, { constructor: { value: n2, enumerable: false, writable: true, configurable: true } }), G(n2, e3);
}, q(e2);
}
var J = { 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 }).
`, 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 }).
`, 3: `Passed an incorrect argument to a color function, please pass a string representation of a color.
`, 4: `Couldn't generate valid rgb string from %s, it returned %s.
`, 5: `Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.
`, 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 }).
`, 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 }).
`, 8: `Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.
`, 9: `Please provide a number of steps to the modularScale helper.
`, 10: `Please pass a number or one of the predefined scales to the modularScale helper as the ratio.
`, 11: `Invalid value passed as base to modularScale, expected number or em string but got "%s"
`, 12: `Expected a string ending in "px" or a number passed as the first argument to %s(), got "%s" instead.
`, 13: `Expected a string ending in "px" or a number passed as the second argument to %s(), got "%s" instead.
`, 14: `Passed invalid pixel value ("%s") to %s(), please pass a value like "12px" or 12.
`, 15: `Passed invalid base value ("%s") to %s(), please pass a value like "12px" or 12.
`, 16: `You must provide a template to this method.
`, 17: `You passed an unsupported selector state to this method.
`, 18: `minScreen and maxScreen must be provided as stringified numbers with the same units.
`, 19: `fromSize and toSize must be provided as stringified numbers with the same units.
`, 20: `expects either an array of objects or a single object with the properties prop, fromSize, and toSize.
`, 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.
`, 24: `fontFace expects either the path to the font file(s) or a name of a local copy.
`, 25: `fontFace expects localFonts to be an array.
`, 26: `fontFace expects fileFormats to be an array.
`, 27: `radialGradient requries at least 2 color-stops to properly render.
`, 28: `Please supply a filename to retinaImage() as the first argument.
`, 29: `Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.
`, 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
`, 32: `To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])
To pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')
`, 33: `The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation
`, 34: `borderRadius expects a radius value as a string or number as the second argument.
`, 35: `borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.
`, 36: `Property must be a string value.
`, 37: `Syntax Error at %s.
`, 38: `Formula contains a function that needs parentheses at %s.
`, 39: `Formula is missing closing parenthesis at %s.
`, 40: `Formula has too many closing parentheses at %s.
`, 41: `All values in a formula must have the same unit or be unitless.
`, 42: `Please provide a number of steps to the modularScale helper.
`, 43: `Please pass a number or one of the predefined scales to the modularScale helper as the ratio.
`, 44: `Invalid value passed as base to modularScale, expected number or em/rem string but got %s.
`, 45: `Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.
`, 46: `Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.
`, 47: `minScreen and maxScreen must be provided as stringified numbers with the same units.
`, 48: `fromSize and toSize must be provided as stringified numbers with the same units.
`, 49: `Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.
`, 50: `Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.
`, 51: `Expects the first argument object to have the properties prop, fromSize, and toSize.
`, 52: `fontFace expects either the path to the font file(s) or a name of a local copy.
`, 53: `fontFace expects localFonts to be an array.
`, 54: `fontFace expects fileFormats to be an array.
`, 55: `fontFace expects a name of a font-family.
`, 56: `linearGradient requries at least 2 color-stops to properly render.
`, 57: `radialGradient requries at least 2 color-stops to properly render.
`, 58: `Please supply a filename to retinaImage() as the first argument.
`, 59: `Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.
`, 60: "Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n", 61: `Property must be a string value.
`, 62: `borderRadius expects a radius value as a string or number as the second argument.
`, 63: `borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.
`, 64: `The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.
`, 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').
`, 66: `The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.
`, 67: `You must provide a template to this method.
`, 68: `You passed an unsupported selector state to this method.
`, 69: `Expected a string ending in "px" or a number passed as the first argument to %s(), got %s instead.
`, 70: `Expected a string ending in "px" or a number passed as the second argument to %s(), got %s instead.
`, 71: `Passed invalid pixel value %s to %s(), please pass a value like "12px" or 12.
`, 72: `Passed invalid base value %s to %s(), please pass a value like "12px" or 12.
`, 73: `Please provide a valid CSS variable.
`, 74: `CSS variable not found and no default was provided.
`, 75: `important requires a valid style object, got a %s instead.
`, 76: `fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.
`, 77: `remToPx expects a value in "rem" but you provided it in "%s".
`, 78: `base must be set in "px" or "%" but you set it in "%s".
` };
function Q() {
for (var e2 = arguments.length, t2 = new Array(e2), n2 = 0;n2 < e2; n2++)
t2[n2] = arguments[n2];
var o2, i2 = t2[0], r2 = [];
for (o2 = 1;o2 < t2.length; o2 += 1)
r2.push(t2[o2]);
return r2.forEach(function(e3) {
i2 = i2.replace(/%[a-z]/, e3);
}), i2;
}
var K = function(e2) {
var t2, n2;
function o2(t3) {
var n3;
{
for (var o3 = arguments.length, i2 = new Array(o3 > 1 ? o3 - 1 : 0), r2 = 1;r2 < o3; r2++)
i2[r2 - 1] = arguments[r2];
n3 = e2.call(this, Q.apply(undefined, [J[t3]].concat(i2))) || this;
}
return function(e3) {
if (e3 === undefined)
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
return e3;
}(n3);
}
return n2 = e2, (t2 = o2).prototype = Object.create(n2.prototype), t2.prototype.constructor = t2, G(t2, n2), o2;
}(q(Error));
function ie(e2) {
return Math.round(255 * e2);
}
function re(e2, t2, n2) {
return ie(e2) + "," + ie(t2) + "," + ie(n2);
}
function se(e2, t2, n2, o2) {
if (o2 === undefined && (o2 = re), t2 === 0)
return o2(n2, n2, n2);
var i2 = (e2 % 360 + 360) % 360 / 60, r2 = (1 - Math.abs(2 * n2 - 1)) * t2, s2 = r2 * (1 - Math.abs(i2 % 2 - 1)), a2 = 0, c2 = 0, l2 = 0;
i2 >= 0 && i2 < 1 ? (a2 = r2, c2 = s2) : i2 >= 1 && i2 < 2 ? (a2 = s2, c2 = r2) : i2 >= 2 && i2 < 3 ? (c2 = r2, l2 = s2) : i2 >= 3 && i2 < 4 ? (c2 = s2, l2 = r2) : i2 >= 4 && i2 < 5 ? (a2 = s2, l2 = r2) : i2 >= 5 && i2 < 6 && (a2 = r2, l2 = s2);
var h2 = n2 - r2 / 2;
return o2(a2 + h2, c2 + h2, l2 + h2);
}
var ae = { 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 ce = /^#[a-fA-F0-9]{6}$/;
var le = /^#[a-fA-F0-9]{8}$/;
var he = /^#[a-fA-F0-9]{3}$/;
var de = /^#[a-fA-F0-9]{4}$/;
var ue = /^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i;
var pe = /^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;
var me = /^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i;
var ge = /^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 fe(e2) {
if (typeof e2 != "string")
throw new K(3);
var t2 = function(e3) {
if (typeof e3 != "string")
return e3;
var t3 = e3.toLowerCase();
return ae[t3] ? "#" + ae[t3] : e3;
}(e2);
if (t2.match(ce))
return { red: parseInt("" + t2[1] + t2[2], 16), green: parseInt("" + t2[3] + t2[4], 16), blue: parseInt("" + t2[5] + t2[6], 16) };
if (t2.match(le)) {
var n2 = parseFloat((parseInt("" + t2[7] + t2[8], 16) / 255).toFixed(2));
return { red: parseInt("" + t2[1] + t2[2], 16), green: parseInt("" + t2[3] + t2[4], 16), blue: parseInt("" + t2[5] + t2[6], 16), alpha: n2 };
}
if (t2.match(he))
return { red: parseInt("" + t2[1] + t2[1], 16), green: parseInt("" + t2[2] + t2[2], 16), blue: parseInt("" + t2[3] + t2[3], 16) };
if (t2.match(de)) {
var o2 = parseFloat((parseInt("" + t2[4] + t2[4], 16) / 255).toFixed(2));
return { red: parseInt("" + t2[1] + t2[1], 16), green: parseInt("" + t2[2] + t2[2], 16), blue: parseInt("" + t2[3] + t2[3], 16), alpha: o2 };
}
var i2 = ue.exec(t2);
if (i2)
return { red: parseInt("" + i2[1], 10), green: parseInt("" + i2[2], 10), blue: parseInt("" + i2[3], 10) };
var r2 = pe.exec(t2.substring(0, 50));
if (r2)
return { red: parseInt("" + r2[1], 10), green: parseInt("" + r2[2], 10), blue: parseInt("" + r2[3], 10), alpha: parseFloat("" + r2[4]) > 1 ? parseFloat("" + r2[4]) / 100 : parseFloat("" + r2[4]) };
var s2 = me.exec(t2);
if (s2) {
var a2 = "rgb(" + se(parseInt("" + s2[1], 10), parseInt("" + s2[2], 10) / 100, parseInt("" + s2[3], 10) / 100) + ")", c2 = ue.exec(a2);
if (!c2)
throw new K(4, t2, a2);
return { red: parseInt("" + c2[1], 10), green: parseInt("" + c2[2], 10), blue: parseInt("" + c2[3], 10) };
}
var l2 = ge.exec(t2.substring(0, 50));
if (l2) {
var h2 = "rgb(" + se(parseInt("" + l2[1], 10), parseInt("" + l2[2], 10) / 100, parseInt("" + l2[3], 10) / 100) + ")", d2 = ue.exec(h2);
if (!d2)
throw new K(4, t2, h2);
return { red: parseInt("" + d2[1], 10), green: parseInt("" + d2[2], 10), blue: parseInt("" + d2[3], 10), alpha: parseFloat("" + l2[4]) > 1 ? parseFloat("" + l2[4]) / 100 : parseFloat("" + l2[4]) };
}
throw new K(5);
}
function _e(e2) {
return function(e3) {
var t2, n2 = e3.red / 255, o2 = e3.green / 255, i2 = e3.blue / 255, r2 = Math.max(n2, o2, i2), s2 = Math.min(n2, o2, i2), a2 = (r2 + s2) / 2;
if (r2 === s2)
return e3.alpha !== undefined ? { hue: 0, saturation: 0, lightness: a2, alpha: e3.alpha } : { hue: 0, saturation: 0, lightness: a2 };
var c2 = r2 - s2, l2 = a2 > 0.5 ? c2 / (2 - r2 - s2) : c2 / (r2 + s2);
switch (r2) {
case n2:
t2 = (o2 - i2) / c2 + (o2 < i2 ? 6 : 0);
break;
case o2:
t2 = (i2 - n2) / c2 + 2;
break;
default:
t2 = (n2 - o2) / c2 + 4;
}
return t2 *= 60, e3.alpha !== undefined ? { hue: t2, saturation: l2, lightness: a2, alpha: e3.alpha } : { hue: t2, saturation: l2, lightness: a2 };
}(fe(e2));
}
var ye = function(e2) {
return e2.length === 7 && e2[1] === e2[2] && e2[3] === e2[4] && e2[5] === e2[6] ? "#" + e2[1] + e2[3] + e2[5] : e2;
};
function be(e2) {
var t2 = e2.toString(16);
return t2.length === 1 ? "0" + t2 : t2;
}
function xe(e2) {
return be(Math.round(255 * e2));
}
function ve(e2, t2, n2) {
return ye("#" + xe(e2) + xe(t2) + xe(n2));
}
function Ie(e2, t2, n2) {
return se(e2, t2, n2, ve);
}
function Se(e2, t2, n2) {
if (typeof e2 == "number" && typeof t2 == "number" && typeof n2 == "number")
return ye("#" + be(e2) + be(t2) + be(n2));
if (typeof e2 == "object" && t2 === undefined && n2 === undefined)
return ye("#" + be(e2.red) + be(e2.green) + be(e2.blue));
throw new K(6);
}
function Ce(e2, t2, n2, o2) {
if (typeof e2 == "object" && t2 === undefined && n2 === undefined && o2 === undefined)
return e2.alpha >= 1 ? Se(e2.red, e2.green, e2.blue) : "rgba(" + e2.red + "," + e2.green + "," + e2.blue + "," + e2.alpha + ")";
throw new K(7);
}
function Pe(e2) {
if (typeof e2 != "object")
throw new K(8);
if (function(e3) {
return typeof e3.red == "number" && typeof e3.green == "number" && typeof e3.blue == "number" && typeof e3.alpha == "number";
}(e2))
return Ce(e2);
if (function(e3) {
return typeof e3.red == "number" && typeof e3.green == "number" && typeof e3.blue == "number" && (typeof e3.alpha != "number" || e3.alpha === undefined);
}(e2))
return Se(e2);
if (function(e3) {
return typeof e3.hue == "number" && typeof e3.saturation == "number" && typeof e3.lightness == "number" && typeof e3.alpha == "number";
}(e2))
return function(e3, t2, n2, o2) {
if (typeof e3 == "object" && t2 === undefined && n2 === undefined && o2 === undefined)
return e3.alpha >= 1 ? Ie(e3.hue, e3.saturation, e3.lightness) : "rgba(" + se(e3.hue, e3.saturation, e3.lightness) + "," + e3.alpha + ")";
throw new K(2);
}(e2);
if (function(e3) {
return typeof e3.hue == "number" && typeof e3.saturation == "number" && typeof e3.lightness == "number" && (typeof e3.alpha != "number" || e3.alpha === undefined);
}(e2))
return function(e3, t2, n2) {
if (typeof e3 == "object" && t2 === undefined && n2 === undefined)
return Ie(e3.hue, e3.saturation, e3.lightness);
throw new K(1);
}(e2);
throw new K(8);
}
function Me(e2, t2, n2) {
return function() {
var o2 = n2.concat(Array.prototype.slice.call(arguments));
return o2.length >= t2 ? e2.apply(this, o2) : Me(e2, t2, o2);
};
}
function we(e2) {
return Me(e2, e2.length, []);
}
we(function(e2, t2) {
if (t2 === "transparent")
return t2;
var n2 = _e(t2);
return Pe(H({}, n2, { hue: n2.hue + parseFloat(e2) }));
});
function Ne(e2, t2, n2) {
return Math.max(e2, Math.min(t2, n2));
}
we(function(e2, t2) {
if (t2 === "transparent")
return t2;
var n2 = _e(t2);
return Pe(H({}, n2, { lightness: Ne(0, 1, n2.lightness - parseFloat(e2)) }));
});
we(function(e2, t2) {
if (t2 === "transparent")
return t2;
var n2 = _e(t2);
return Pe(H({}, n2, { saturation: Ne(0, 1, n2.saturation - parseFloat(e2)) }));
});
we(function(e2, t2) {
if (t2 === "transparent")
return t2;
var n2 = _e(t2);
return Pe(H({}, n2, { lightness: Ne(0, 1, n2.lightness + parseFloat(e2)) }));
});
var Te = we(function(e2, t2, n2) {
if (t2 === "transparent")
return n2;
if (n2 === "transparent")
return t2;
if (e2 === 0)
return n2;
var o2 = fe(t2), i2 = H({}, o2, { alpha: typeof o2.alpha == "number" ? o2.alpha : 1 }), r2 = fe(n2), s2 = H({}, r2, { alpha: typeof r2.alpha == "number" ? r2.alpha : 1 }), a2 = i2.alpha - s2.alpha, c2 = 2 * parseFloat(e2) - 1, l2 = ((c2 * a2 === -1 ? c2 : c2 + a2) / (1 + c2 * a2) + 1) / 2, h2 = 1 - l2;
return Ce({ red: Math.floor(i2.red * l2 + s2.red * h2), green: Math.floor(i2.green * l2 + s2.green * h2), blue: Math.floor(i2.blue * l2 + s2.blue * h2), alpha: i2.alpha * parseFloat(e2) + s2.alpha * (1 - parseFloat(e2)) });
});
we(function(e2, t2) {
if (t2 === "transparent")
return t2;
var n2 = fe(t2);
return Ce(H({}, n2, { alpha: Ne(0, 1, (100 * (typeof n2.alpha == "number" ? n2.alpha : 1) + 100 * parseFloat(e2)) / 100) }));
});
we(function(e2, t2) {
if (t2 === "transparent")
return t2;
var n2 = _e(t2);
return Pe(H({}, n2, { saturation: Ne(0, 1, n2.saturation + parseFloat(e2)) }));
});
we(function(e2, t2) {
return t2 === "transparent" ? t2 : Pe(H({}, _e(t2), { hue: parseFloat(e2) }));
});
we(function(e2, t2) {
return t2 === "transparent" ? t2 : Pe(H({}, _e(t2), { lightness: parseFloat(e2) }));
});
we(function(e2, t2) {
return t2 === "transparent" ? t2 : Pe(H({}, _e(t2), { saturation: parseFloat(e2) }));
});
we(function(e2, t2) {
return t2 === "transparent" ? t2 : Te(parseFloat(e2), "rgb(0, 0, 0)", t2);
});
we(function(e2, t2) {
return t2 === "transparent" ? t2 : Te(parseFloat(e2), "rgb(255, 255, 255)", t2);
});
var Re = we(function(e2, t2) {
if (t2 === "transparent")
return t2;
var n2 = fe(t2);
return Ce(H({}, n2, { alpha: Ne(0, 1, +(100 * (typeof n2.alpha == "number" ? n2.alpha : 1) - 100 * parseFloat(e2)).toFixed(2) / 100) }));
});
var Ee = { 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" };
var Ae = {};
for (const e2 in Ee) {
Ae[e2] = [];
const t2 = Ee[e2].split("M").slice(1).map((e3) => e3.split("L").map((e4) => e4.trim().split(" ").map(parseFloat)));
for (const n2 of t2)
for (let t3 = 0;t3 < n2.length - 1; t3++)
Ae[e2].push({ x1: n2[t3][0], y1: 1 - n2[t3][1], x2: n2[t3 + 1][0], y2: 1 - n2[t3 + 1][1] });
}
var Oe = (e2, t2) => ({ ...e2, rects: [...e2.rects ?? [], ...t2.rects ?? []], points: [...e2.points ?? [], ...t2.points ?? []], lines: [...e2.lines ?? [], ...t2.lines ?? []], infiniteLines: [...e2.infiniteLines ?? [], ...t2.infiniteLines ?? []], polygons: [...e2.polygons ?? [], ...t2.polygons ?? []], circles: [...e2.circles ?? [], ...t2.circles ?? []], arrows: [...e2.arrows ?? [], ...t2.arrows ?? []], texts: [...e2.texts ?? [], ...t2.texts ?? []] });
function ke(e2, t2) {
if (e2.points)
for (const n2 of e2.points)
n2.step = t2;
if (e2.lines)
for (const n2 of e2.lines)
n2.step = t2;
if (e2.infiniteLines)
for (const n2 of e2.infiniteLines)
n2.step = t2;
if (e2.polygons)
for (const n2 of e2.polygons)
n2.step = t2;
if (e2.rects)
for (const n2 of e2.rects)
n2.step = t2;
if (e2.circles)
for (const n2 of e2.circles)
n2.step = t2;
if (e2.texts)
for (const n2 of e2.texts)
n2.step = t2;
if (e2.arrows)
for (const n2 of e2.arrows)
n2.step = t2;
return e2;
}
var De = class {
MAX_ITERATIONS = 1e5;
solved = false;
failed = false;
iterations = 0;
progress = 0;
error = null;
activeSubSolver;
failedSubSolvers;
timeToSolve;
stats = {};
_setupDone = false;
getSolverName() {
return this.constructor.name;
}
setup() {
this._setupDone || (this._setup(), this._setupDone = true);
}
_setup() {}
step() {
if (this._setupDone || this.setup(), !this.solved && !this.failed) {
this.iterations++;
try {
this._step();
} catch (e2) {
throw this.error = `${this.getSolverName()} error: ${e2}`, this.failed = true, e2;
}
!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 = true), "computeProgress" in this && (this.progress = this.computeProgress());
}
}
_step() {}
getConstructorParams() {
throw new Error("getConstructorParams not implemented");
}
getOutput() {
return null;
}
solve() {
const e2 = Date.now();
for (;!this.solved && !this.failed; )
this.step();
const t2 = Date.now();
this.timeToSolve = t2 - e2;
}
visualize() {
return { lines: [], points: [], rects: [], circles: [] };
}
tryFinalAcceptance() {}
preview() {
return { lines: [], points: [], rects: [], circles: [] };
}
};
function Le(e2, t2, n2, o2 = {}) {
return { solverName: e2, solverClass: t2, getConstructorParams: n2, onSolved: o2.onSolved };
}
var ze = class extends De {
startTimeOfStage = {};
endTimeOfStage = {};
timeSpentOnStage = {};
firstIterationOfStage = {};
currentPipelineStageIndex = 0;
inputProblem;
pipelineOutputs = {};
constructor(e2) {
super(), this.inputProblem = e2, this.MAX_ITERATIONS = 1e6;
}
_step() {
const e2 = this.pipelineDef[this.currentPipelineStageIndex];
if (!e2)
return void (this.solved = true);
if (this.activeSubSolver) {
if (this.activeSubSolver.step(), this.activeSubSolver.solved) {
this.endTimeOfStage[e2.solverName] = performance.now(), this.timeSpentOnStage[e2.solverName] = this.endTimeOfStage[e2.solverName] - this.startTimeOfStage[e2.solverName];
const t3 = this.activeSubSolver.getOutput();
t3 !== null && (this.pipelineOutputs[e2.solverName] = t3), e2.onSolved?.(this), this.activeSubSolver = null, this.currentPipelineStageIndex++;
} else
this.activeSubSolver.failed && (this.error = this.activeSubSolver?.error, this.failed = true, this.activeSubSolver = null);
return;
}
const t2 = e2.getConstructorParams(this);
this.activeSubSolver = new e2.solverClass(...t2), this[e2.solverName] = this.activeSubSolver, this.timeSpentOnStage[e2.solverName] = 0, this.startTimeOfStage[e2.solverName] = performance.now(), this.firstIterationOfStage[e2.solverName] = this.iterations;
}
solveUntilStage(e2) {
for (;this.getCurrentStageName().toLowerCase() !== e2.toLowerCase() && (this.step(), !this.failed && !this.solved); )
;
}
getCurrentStageName() {
return this.pipelineDef[this.currentPipelineStageIndex]?.solverName ?? "none";
}
getStageProgress() {
const e2 = this.pipelineDef.length;
if (e2 === 0)
return 1;
const t2 = this.activeSubSolver?.progress ?? 0;
return (this.currentPipelineStageIndex + t2) / e2;
}
getStageStats() {
const e2 = {};
for (const t2 of this.pipelineDef) {
const n2 = this.timeSpentOnStage[t2.solverName] || 0, o2 = this.firstIterationOfStage[t2.solverName] || 0, i2 = this.iterations, r2 = t2.solverName === this.getCurrentStageName() ? i2 - o2 : 0, s2 = this.currentPipelineStageIndex > this.pipelineDef.findIndex((e3) => e3.solverName === t2.solverName);
e2[t2.solverName] = { timeSpent: n2, iterations: r2, completed: s2 };
}
return e2;
}
initialVisualize() {
return null;
}
finalVisualize() {
return null;
}
visualize() {
if (!this.solved && this.activeSubSolver)
return this.activeSubSolver.visualize();
let e2 = 0;
const t2 = this.initialVisualize();
t2 && (ke(t2, 0), e2 = 1);
let n2 = null;
this.solved && (n2 = this.finalVisualize());
const o2 = [t2].filter(Boolean).concat(this.pipelineDef.map((t3, n3) => {
const o3 = this[t3.solverName], i2 = o3?.visualize();
return i2 ? (ke(i2, n3 + e2), i2) : null;
}).filter(Boolean));
return o2.length === 0 ? { points: [], rects: [], lines: [], circles: [], texts: [] } : (this.solved && n2 && (ke(n2, o2.length + e2 + 1), o2.push(n2)), o2.length === 1 ? o2[0] : { points: o2.flatMap((e3) => e3.points || []), rects: o2.flatMap((e3) => e3.rects || []), lines: o2.flatMap((e3) => e3.lines || []), circles: o2.flatMap((e3) => e3.circles || []), texts: o2.flatMap((e3) => e3.texts || []) });
}
preview() {
return this.activeSubSolver ? this.activeSubSolver.preview() : super.preview();
}
computeProgress() {
return this.getStageProgress();
}
getStageOutput(e2) {
return this.pipelineOutputs[e2];
}
getAllOutputs() {
return { ...this.pipelineOutputs };
}
hasStageOutput(e2) {
return e2 in this.pipelineOutputs;
}
getSolver(e2) {
return this[e2];
}
};
var Be = class {
constructor(e2 = 1 / 0, t2 = Float64Array, n2 = Uint32Array) {
const o2 = e2 !== 1 / 0;
this.ids = o2 ? new n2(e2) : [], this.values = o2 ? new t2(e2) : [], this.capacity = e2, this.length = 0;
}
clear() {
this.length = 0;
}
push(e2, t2) {
if (this.length === this.capacity)
throw new RangeError("Queue is at capacity.");
let n2 = this.length++;
for (;n2 > 0; ) {
const e3 = n2 - 1 >> 1, o2 = this.values[e3];
if (t2 >= o2)
break;
this.ids[n2] = this.ids[e3], this.values[n2] = o2, n2 = e3;
}
this.ids[n2] = e2, this.values[n2] = t2;
}
pop() {
if (this.length === 0)
return;
const e2 = this.ids, t2 = this.values, n2 = e2[0], o2 = --this.length;
if (o2 > 0) {
const n3 = e2[o2], i2 = t2[o2];
let r2 = 0;
const s2 = o2 >> 1;
for (;r2 < s2; ) {
const n4 = 1 + (r2 << 1), s3 = n4 + 1, a2 = n4 + (+(s3 < o2) & +(t2[s3] < t2[n4]));
if (t2[a2] >= i2)
break;
e2[r2] = e2[a2], t2[r2] = t2[a2], r2 = a2;
}
e2[r2] = n3, t2[r2] = i2;
}
return n2;
}
peek() {
return this.length > 0 ? this.ids[0] : undefined;
}
peekValue() {
return this.length > 0 ? this.values[0] : undefined;
}
shrink() {
Array.isArray(this.ids) && (this.ids.length = this.length), Array.isArray(this.values) && (this.values.length = this.length);
}
};
var Fe = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array];
var je = class e2 {
static from(t2, n2 = 0) {
if (n2 % 8 != 0)
throw new Error("byteOffset must be 8-byte aligned.");
if (!t2 || t2.byteLength === undefined || "buffer" in t2)
throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");
const [o2, i2] = new Uint8Array(t2, n2 + 0, 2);
if (o2 !== 251)
throw new Error("Data does not appear to be in a Flatbush format.");
const r2 = i2 >> 4;
if (r2 !== 3)
throw new Error(`Got v${r2} data when expected v3.`);
const s2 = Fe[15 & i2];
if (!s2)
throw new Error("Unrecognized array type.");
const [a2] = new Uint16Array(t2, n2 + 2, 1), [c2] = new Uint32Array(t2, n2 + 4, 1);
return new e2(c2, a2, s2, undefined, t2, n2);
}
constructor(e3, t2 = 16, n2 = Float64Array, o2 = ArrayBuffer, i2, r2 = 0) {
if (e3 === undefined)
throw new Error("Missing required argument: numItems.");
if (isNaN(e3) || e3 <= 0)
throw new Error(`Unexpected numItems value: ${e3}.`);
this.numItems = +e3, this.nodeSize = Math.min(Math.max(+t2, 2), 65535), this.byteOffset = r2;
let s2 = e3, a2 = s2;
this._levelBounds = [4 * s2];
do {
s2 = Math.ceil(s2 / this.nodeSize), a2 += s2, this._levelBounds.push(4 * a2);
} while (s2 !== 1);
this.ArrayType = n2, this.IndexArrayType = a2 < 16384 ? Uint16Array : Uint32Array;
const c2 = Fe.indexOf(n2), l2 = 4 * a2 * n2.BYTES_PER_ELEMENT;
if (c2 < 0)
throw new Error(`Unexpected typed array class: ${n2}.`);
const h2 = n2, d2 = this.IndexArrayType;
if (i2)
this.data = i2, this._boxes = new h2(i2, r2 + 8, 4 * a2), this._indices = new d2(i2, r2 + 8 + l2, a2), this._pos = 4 * a2, 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 n3 = this.data = new o2(8 + l2 + a2 * this.IndexArrayType.BYTES_PER_ELEMENT);
this._boxes = new h2(n3, 8, 4 * a2), this._indices = new d2(n3, 8 + l2, a2), this._pos = 0, this.minX = 1 / 0, this.minY = 1 / 0, this.maxX = -1 / 0, this.maxY = -1 / 0, new Uint8Array(n3, 0, 2).set([251, 48 + c2]), new Uint16Array(n3, 2, 1)[0] = t2, new Uint32Array(n3, 4, 1)[0] = e3;
}
this._queue = new Be;
}
add(e3, t2, n2 = e3, o2 = t2) {
const i2 = this._pos, r2 = i2 >> 2, s2 = this._boxes;
return this._indices[r2] = r2, s2[i2] = e3, s2[i2 + 1] = t2, s2[i2 + 2] = n2, s2[i2 + 3] = o2, this._pos = i2 + 4, e3 < this.minX && (this.minX = e3), t2 < this.minY && (this.minY = t2), n2 > this.maxX && (this.maxX = n2), o2 > this.maxY && (this.maxY = o2), r2;
}
finish() {
if (this._pos >> 2 !== this.numItems)
throw new Error(`Added ${this._pos >> 2} items when expected ${this.numItems}.`);
const e3 = this._boxes;
if (this.numItems <= this.nodeSize)
return e3[this._pos++] = this.minX, e3[this._pos++] = this.minY, e3[this._pos++] = this.maxX, void (e3[this._pos++] = this.maxY);
const { numItems: t2, minX: n2, minY: o2, nodeSize: i2, _indices: r2, _levelBounds: s2 } = this, a2 = this.maxX - n2 || 1, c2 = this.maxY - o2 || 1, l2 = new Int32Array(t2), h2 = 65535 / a2, d2 = 65535 / c2;
for (let i3 = 0, r3 = 0;i3 < t2; i3++) {
const t3 = e3[r3++], s3 = e3[r3++], a3 = h2 * ((t3 + e3[r3++]) / 2 - n2) | 0, c3 = d2 * ((s3 + e3[r3++]) / 2 - o2) | 0;
l2[i3] = Xe(a3, c3);
}
(function(e4, t3, n3, o3, i3, r3) {
const s3 = [o3, i3];
for (;s3.length; ) {
const o4 = s3.pop() || 0, i4 = s3.pop() || 0;
if (o4 - i4 <= r3 && Math.floor(i4 / r3) >= Math.floor(o4 / r3))
continue;
const a3 = e4[i4], c3 = e4[i4 + o4 >> 1], l3 = e4[o4], h3 = a3 > c3 != a3 > l3 ? a3 : c3 < a3 != c3 < l3 ? c3 : l3;
let d3 = i4 - 1, u3 = o4 + 1;
for (;; ) {
do {
d3++;
} while (e4[d3] < h3);
do {
u3--;
} while (e4[u3] > h3);
if (d3 >= u3)
break;
Ye(e4, t3, n3, d3, u3);
}
s3.push(i4, u3, u3 + 1, o4);
}
})(l2, e3, r2, 0, t2 - 1, i2);
let u2 = 4 * t2;
for (let t3 = 0, n3 = 0;t3 < s2.length - 1; t3++) {
const o3 = s2[t3];
for (;n3 < o3; ) {
const t4 = n3;
let s3 = e3[n3++], a3 = e3[n3++], c3 = e3[n3++], l3 = e3[n3++];
for (let t5 = 1;t5 < i2 && n3 < o3; t5++)
s3 = Math.min(s3, e3[n3++]), a3 = Math.min(a3, e3[n3++]), c3 = Math.max(c3, e3[n3++]), l3 = Math.max(l3, e3[n3++]);
r2[u2 >> 2] = t4, e3[u2++] = s3, e3[u2++] = a3, e3[u2++] = c3, e3[u2++] = l3;
}
}
this._pos = u2;
}
search(e3, t2, n2, o2, i2) {
if (this._pos !== this._boxes.length)
throw new Error("Data not yet indexed - call index.finish().");
const { _boxes: r2, _levelBounds: s2, _indices: a2, nodeSize: c2 } = this, l2 = 4 * this.numItems;
let h2 = r2.length - 4, d2 = s2.length - 1;
const u2 = [], p2 = [];
let m2 = false;
for (;h2 !== undefined; ) {
const g2 = Math.min(h2 + 4 * c2, s2[d2]), f2 = h2 >= l2;
if (m2)
this._collectContained(h2, g2, d2, l2, p2, i2);
else
for (let s3 = h2;s3 < g2; s3 += 4) {
const c3 = r2[s3];
if (n2 < c3)
continue;
const l3 = r2[s3 + 1];
if (o2 < l3)
continue;
const h3 = r2[s3 + 2];
if (e3 > h3)
continue;
const m3 = r2[s3 + 3];
if (t2 > m3)
continue;
const g3 = 0 | a2[s3 >> 2];
if (f2) {
const i3 = +(e3 <= c3 && t2 <= l3 && n2 >= h3 && o2 >= m3);
u2.push(g3 | i3, d2 - 1);
} else
(i2 === undefined || i2(g3, c3, l3, h3, m3)) && p2.push(g3);
}
d2 = u2.pop(), h2 = u2.pop(), h2 !== undefined && (m2 = !(1 & ~h2), h2 &= -2);
}
return p2;
}
_collectContained(e3, t2, n2, o2, i2, r2) {
const s2 = this._boxes, a2 = this._indices;
let c2 = e3;
for (let e4 = n2;e4 > 0; e4--)
c2 = a2[c2 >> 2];
const l2 = Math.min(c2 + (t2 - e3) * this.nodeSize ** n2, o2);
if (r2 === undefined)
for (;c2 < l2; c2 += 4)
i2.push(0 | a2[c2 >> 2]);
else
for (;c2 < l2; c2 += 4) {
const e4 = 0 | a2[c2 >> 2];
r2(e4, s2[c2], s2[c2 + 1], s2[c2 + 2], s2[c2 + 3]) && i2.push(e4);
}
}
neighbors(e3, t2, n2 = 1 / 0, o2 = 1 / 0, i2) {
if (this._pos !== this._boxes.length)
throw new Error("Data not yet indexed - call index.finish().");
const { _boxes: r2, _levelBounds: s2, _indices: a2, _queue: c2, nodeSize: l2 } = this, h2 = 4 * this.numItems, d2 = 4 * l2, u2 = [], p2 = n2 === 1;
let m2 = o2 * o2;
for (c2.push(r2.length - 4 << 1, 0);c2.length; ) {
const o3 = c2.ids[0];
if (1 & o3) {
if (c2.pop(), u2.push(o3 >> 1), u2.length === n2)
break;
continue;
}
c2.pop();
const l3 = o3 >> 1, g2 = l3 < h2, f2 = Math.min(l3 + d2, $e(l3, s2));
for (let n3 = l3;n3 < f2; n3 += 4) {
const o4 = r2[n3], s3 = r2[n3 + 1], l4 = r2[n3 + 2], h3 = r2[n3 + 3], d3 = Math.max(Math.max(o4 - e3, e3 - l4), 0), u3 = Math.max(Math.max(s3 - t2, t2 - h3), 0), f3 = d3 * d3 + u3 * u3;
if (f3 > m2)
continue;
const _2 = 0 | a2[n3 >> 2];
g2 ? (i2 === undefined || i2(_2)) && (c2.push(_2 << 1 | 1, f3), p2 && f3 < m2 && (m2 = f3)) : c2.push(_2 << 1, f3);
}
}
return c2.clear(), u2;
}
};
function $e(e3, t2) {
let n2 = 0, o2 = t2.length - 1;
for (;n2 < o2; ) {
const i2 = n2 + o2 >> 1;
t2[i2] > e3 ? o2 = i2 : n2 = i2 + 1;
}
return t2[n2];
}
function Ye(e3, t2, n2, o2, i2) {
const r2 = e3[o2];
e3[o2] = e3[i2], e3[i2] = r2;
const s2 = 4 * o2, a2 = 4 * i2, c2 = t2[s2], l2 = t2[s2 + 1], h2 = t2[s2 + 2], d2 = t2[s2 + 3];
t2[s2] = t2[a2], t2[s2 + 1] = t2[a2 + 1], t2[s2 + 2] = t2[a2 + 2], t2[s2 + 3] = t2[a2 + 3], t2[a2] = c2, t2[a2 + 1] = l2, t2[a2 + 2] = h2, t2[a2 + 3] = d2;
const u2 = n2[o2];
n2[o2] = n2[i2], n2[i2] = u2;
}
function Xe(e3, t2) {
let n2 = e3 ^ t2, o2 = 65535 ^ n2, i2 = 65535 ^ (e3 | t2), r2 = e3 & (65535 ^ t2), s2 = n2 | o2 >> 1, a2 = n2 >> 1 ^ n2, c2 = i2 ^ i2 >> 1 ^ o2 & r2 >> 1, l2 = r2 ^ n2 & i2 >> 1 ^ r2 >> 1;
return n2 = s2 & s2 >> 2 ^ a2 & a2 >> 2, o2 = s2 & a2 >> 2 ^ a2 & (s2 ^ a2) >> 2, i2 = c2 ^ s2 & c2 >> 2 ^ a2 & l2 >> 2, r2 = l2 ^ a2 & c2 >> 2 ^ (s2 ^ a2) & l2 >> 2, s2 = n2 & n2 >> 4 ^ o2 & o2 >> 4, a2 = n2 & o2 >> 4 ^ o2 & (n2 ^ o2) >> 4, c2 = i2 ^ n2 & i2 >> 4 ^ o2 & r2 >> 4, l2 = r2 ^ o2 & i2 >> 4 ^ (n2 ^ o2) & r2 >> 4, i2 = c2 ^ s2 & c2 >> 8 ^ a2 & l2 >> 8, r2 = l2 ^ a2 & c2 >> 8 ^ (s2 ^ a2) & l2 >> 8, i2 ^= i2 >> 1, r2 ^= r2 >> 1, n2 = e3 ^ t2, o2 = r2 | 65535 ^ (n2 | i2), n2 = 16711935 & (n2 | n2 << 8), n2 = 252645135 & (n2 | n2 << 4), n2 = 858993459 & (n2 | n2 << 2), n2 = 1431655765 & (n2 | n2 << 1), o2 = 16711935 & (o2 | o2 << 8), o2 = 252645135 & (o2 | o2 << 4), o2 = 858993459 & (o2 | o2 << 2), o2 = 1431655765 & (o2 | o2 << 1), ((o2 << 1 | n2) >>> 0) - 2147483648;
}
var We = 0.0001;
var Ve = [{ facingDirection: "x-", dx: -1, dy: 0, startX: -0.5, startY: 0.5, endX: -0.5, endY: -0.5 }, { facingDirection: "x+", dx: 1, dy: 0, startX: 0.5, startY: 0.5, endX: 0.5, endY: -0.5 }, { facingDirection: "y-", dx: 0, dy: -1, startX: -0.5, startY: -0.5, endX: 0.5, endY: -0.5 }, { facingDirection: "y+", dx: 0, dy: 1, startX: 0.5, startY: 0.5, endX: -0.5, endY: 0.5 }];
var He = { "x-": Ve.find((e3) => e3.facingDirection === "x-"), "x+": Ve.find((e3) => e3.facingDirection === "x+"), "y-": Ve.find((e3) => e3.facingDirection === "y-"), "y+": Ve.find((e3) => e3.facingDirection === "y+") };
var Ge = { "x-": { x: -1, y: 0 }, "x+": { x: 1, y: 0 }, "y-": { x: 0, y: -1 }, "y+": { x: 0, y: 1 } };
var Ue = (e3, t2) => {
const { dir: n2, amt: o2 } = t2, i2 = Ge[n2];
return e3.map((e4) => ({ x: e4.x + i2.x * o2, y: e4.y + i2.y * o2 }));
};
var Ze = 0.0001;
function qe(e3) {
const t2 = [];
for (const n2 of e3)
for (const e4 of Ve) {
let o2 = { x: n2.center.x + n2.width * e4.startX, y: n2.center.y + n2.height * e4.startY }, i2 = { x: n2.center.x + n2.width * e4.endX, y: n2.center.y + n2.height * e4.endY };
o2.x > i2.x && ([o2, i2] = [i2, o2]), Math.abs(o2.x - i2.x) < Ze && o2.y > i2.y && ([o2, i2] = [i2, o2]);
for (const r2 of n2.availableZ)
t2.push({ parent: n2, start: o2, end: i2, facingDirection: e4.facingDirection, z: r2 });
}
return t2;
}
var Je = class extends De {
constructor(e3) {
super(), this.input = e3;
const t2 = this.input.targetMeshNodes ?? this.input.allMeshNodes, n2 = new Set(t2.map((e4) => e4.capacityMeshNodeId)), o2 = this.input.allMeshNodes.filter((e4) => !n2.has(e4.capacityMeshNodeId));
this.unprocessedEdges = qe(t2), this.allEdges = [...this.unprocessedEdges, ...qe(o2)], this.edgeSpatialIndex = new je(this.allEdges.length);
for (const e4 of this.allEdges)
this.edgeSpatialIndex.add(e4.start.x, e4.start.y, e4.end.x, e4.end.y);
this.edgeSpatialIndex.finish();
}
input;
allEdges;
unprocessedEdges = [];
segmentsWithAdjacentEmptySpace = [];
edgeSpatialIndex;
lastCandidateEdge = null;
lastOverlappingEdges = null;
lastUncoveredSegments = null;
_step() {
if (this.unprocessedEdges.length === 0)
return this.solved = true, this.lastCandidateEdge = null, this.lastOverlappingEdges = null, void (this.lastUncoveredSegments = null);
const e3 = this.unprocessedEdges.shift();
this.lastCandidateEdge = e3;
const t2 = this.edgeSpatialIndex.search(e3.start.x - Ze, e3.start.y - Ze, e3.end.x + Ze, e3.end.y + Ze).map((e4) => this.allEdges[e4]).filter((t3) => t3.z === e3.z);
this.lastOverlappingEdges = t2;
const n2 = function(e4, t3) {
const n3 = Math.abs(e4.start.y - e4.end.y) < We, o2 = Math.abs(e4.start.x - e4.end.x) < We;
if (!n3 && !o2)
return [];
const i2 = n3 ? "x" : "y", r2 = n3 ? "y" : "x", s2 = e4.start[r2], a2 = e4.start[i2], c2 = e4.end[i2], l2 = Math.min(a2, c2), h2 = Math.max(a2, c2), d2 = (e5) => Math.max(l2, Math.min(h2, e5)), u2 = [];
for (const n4 of t3) {
if (n4 === e4)
continue;
const t4 = Math.abs(n4.start.y - n4.end.y) < We, o3 = Math.abs(n4.start.x - n4.end.x) < We;
if (i2 === "x" && !t4)
continue;
if (i2 === "y" && !o3)
continue;
if (Math.abs(n4.start[r2] - s2) > We)
continue;
const a3 = Math.min(n4.start[i2], n4.end[i2]), c3 = Math.max(n4.start[i2], n4.end[i2]), l3 = d2(a3), h3 = d2(c3);
h3 - l3 > We && u2.push({ s: l3, e: h3 });
}
if (u2.length === 0)
return [{ ...e4, start: { ...e4.start }, end: { ...e4.end } }];
u2.sort((e5, t4) => e5.s - t4.s);
const p2 = [];
for (const e5 of u2) {
const t4 = p2[p2.length - 1];
!t4 || e5.s > t4.e + We ? p2.push({ ...e5 }) : t4.e = Math.max(t4.e, e5.e);
}
const m2 = [];
let g2 = l2;
for (const e5 of p2)
if (e5.s > g2 + We && m2.push({ s: g2, e: e5.s }), g2 = Math.max(g2, e5.e), g2 >= h2 - We)
break;
return h2 > g2 + We && m2.push({ s: g2, e: h2 }), m2.length === 0 ? [] : m2.filter((e5) => e5.e - e5.s > We).map((t4) => {
const n4 = i2 === "x" ? { x: t4.s, y: s2 } : { x: s2, y: t4.s }, o3 = i2 === "x" ? { x: t4.e, y: s2 } : { x: s2, y: t4.e };
return { parent: e4.parent, facingDirection: e4.facingDirection, start: n4, end: o3, z: e4.z };
});
}(e3, t2);
this.lastUncoveredSegments = n2, this.segmentsWithAdjacentEmptySpace.push(...n2);
}
getOutput() {
return { segmentsWithAdjacentEmptySpace: this.segmentsWithAdjacentEmptySpace };
}
visualize() {
const e3 = { title: "FindSegmentsWithAdjacentEmptySpace", coordinateSystem: "cartesian", rects: [], points: [], lines: [], circles: [], infiniteLines: [], polygons: [], arrows: [], texts: [] };
for (const t2 of this.input.allMeshNodes)
e3.rects.push({ center: t2.center, width: t2.width, height: t2.height, stroke: "rgba(0, 0, 0, 0.1)" });
for (const t2 of this.unprocessedEdges)
e3.lines.push({ points: Ue([t2.start, t2.end], { dir: t2.facingDirection, amt: -0.1 }), strokeColor: "rgba(0, 0, 255, 0.5)", strokeDash: "5 5" });
for (const t2 of this.segmentsWithAdjacentEmptySpace)
e3.lines.push({ points: [t2.start, t2.end], strokeColor: "rgba(0,255,0, 0.5)" });
if (this.lastCandidateEdge && e3.lines.push({ points: [this.lastCandidateEdge.start, this.lastCandidateEdge.end], strokeColor: "blue" }), this.lastOverlappingEdges)
for (const t2 of this.lastOverlappingEdges)
e3.lines.push({ points: Ue([t2.start, t2.end], { dir: t2.facingDirection, amt: 0.05 }), strokeColor: "red", strokeDash: "2 2" });
if (this.lastUncoveredSegments)
for (const t2 of this.lastUncoveredSegments)
e3.lines.push({ points: Ue([t2.start, t2.end], { dir: t2.facingDirection, amt: -0.05 }), strokeColor: "green", strokeDash: "2 2" });
return e3;
}
};
function Qe(e3, t2, n2 = 0, o2 = e3.length - 1, i2 = et) {
for (;o2 > n2; ) {
if (o2 - n2 > 600) {
const r3 = o2 - n2 + 1, s3 = t2 - n2 + 1, a3 = Math.log(r3), c2 = 0.5 * Math.exp(2 * a3 / 3), l2 = 0.5 * Math.sqrt(a3 * c2 * (r3 - c2) / r3) * (s3 - r3 / 2 < 0 ? -1 : 1);
Qe(e3, t2, Math.max(n2, Math.floor(t2 - s3 * c2 / r3 + l2)), Math.min(o2, Math.floor(t2 + (r3 - s3) * c2 / r3 + l2)), i2);
}
const r2 = e3[t2];
let s2 = n2, a2 = o2;
for (Ke(e3, n2, t2), i2(e3[o2], r2) > 0 && Ke(e3, n2, o2);s2 < a2; ) {
for (Ke(e3, s2, a2), s2++, a2--;i2(e3[s2], r2) < 0; )
s2++;
for (;i2(e3[a2], r2) > 0; )
a2--;
}
i2(e3[n2], r2) === 0 ? Ke(e3, n2, a2) : (a2++, Ke(e3, a2, o2)), a2 <= t2 && (n2 = a2 + 1), t2 <= a2 && (o2 = a2 - 1);
}
}
function Ke(e3, t2, n2) {
const o2 = e3[t2];
e3[t2] = e3[n2], e3[n2] = o2;
}
function et(e3, t2) {
return e3 < t2 ? -1 : e3 > t2 ? 1 : 0;
}
var tt = class {
constructor(e3 = 9) {
this._maxEntries = Math.max(4, e3), this._minEntries = Math.max(2, Math.ceil(0.4 * this._maxEntries)), this.clear();
}
all() {
return this._all(this.data, []);
}
search(e3) {
let t2 = this.data;
const n2 = [];
if (!pt(e3, t2))
return n2;
const o2 = this.toBBox, i2 = [];
for (;t2; ) {
for (let r2 = 0;r2 < t2.children.length; r2++) {
const s2 = t2.children[r2], a2 = t2.leaf ? o2(s2) : s2;
pt(e3, a2) && (t2.leaf ? n2.push(s2) : ut(e3, a2) ? this._all(s2, n2) : i2.push(s2));
}
t2 = i2.pop();
}
return n2;
}
collides(e3) {
let t2 = this.data;
if (!pt(e3, t2))
return false;
const n2 = [];
for (;t2; ) {
for (let o2 = 0;o2 < t2.children.length; o2++) {
const i2 = t2.children[o2], r2 = t2.leaf ? this.toBBox(i2) : i2;
if (pt(e3, r2)) {
if (t2.leaf || ut(e3, r2))
return true;
n2.push(i2);
}
}
t2 = n2.pop();
}
return false;
}
load(e3) {
if (!e3 || !e3.length)
return this;
if (e3.length < this._minEntries) {
for (let t3 = 0;t3 < e3.length; t3++)
this.insert(e3[t3]);
return this;
}
let t2 = this._build(e3.slice(), 0, e3.length - 1, 0);
if (this.data.children.length)
if (this.data.height === t2.height)
this._splitRoot(this.data, t2);
else {
if (this.data.height < t2.height) {
const e4 = this.data;
this.data = t2, t2 = e4;
}
this._insert(t2, this.data.height - t2.height - 1, true);
}
else
this.data = t2;
return this;
}
insert(e3) {
return e3 && this._insert(e3, this.data.height - 1), this;
}
clear() {
return this.data = mt([]), this;
}
remove(e3, t2) {
if (!e3)
return this;
let n2 = this.data;
const o2 = this.toBBox(e3), i2 = [], r2 = [];
let s2, a2, c2;
for (;n2 || i2.length; ) {
if (n2 || (n2 = i2.pop(), a2 = i2[i2.length - 1], s2 = r2.pop(), c2 = true), n2.leaf) {
const o3 = nt(e3, n2.children, t2);
if (o3 !== -1)
return n2.children.splice(o3, 1), i2.push(n2), this._condense(i2), this;
}
c2 || n2.leaf || !ut(n2, o2) ? a2 ? (s2++, n2 = a2.children[s2], c2 = false) : n2 = null : (i2.push(n2), r2.push(s2), s2 = 0, a2 = n2, n2 = n2.children[0]);
}
return this;
}
toBBox(e3) {
return e3;
}
compareMinX(e3, t2) {
return e3.minX - t2.minX;
}
compareMinY(e3, t2) {
return e3.minY - t2.minY;
}
toJSON() {
return this.data;
}
fromJSON(e3) {
return this.data = e3, this;
}
_all(e3, t2) {
const n2 = [];
for (;e3; )
e3.leaf ? t2.push(...e3.children) : n2.push(...e3.children), e3 = n2.pop();
return t2;
}
_build(e3, t2, n2, o2) {
const i2 = n2 - t2 + 1;
let r2, s2 = this._maxEntries;
if (i2 <= s2)
return r2 = mt(e3.slice(t2, n2 + 1)), ot(r2, this.toBBox), r2;
o2 || (o2 = Math.ceil(Math.log(i2) / Math.log(s2)), s2 = Math.ceil(i2 / Math.pow(s2, o2 - 1))), r2 = mt([]), r2.leaf = false, r2.height = o2;
const a2 = Math.ceil(i2 / s2), c2 = a2 * Math.ceil(Math.sqrt(s2));
gt(e3, t2, n2, c2, this.compareMinX);
for (let i3 = t2;i3 <= n2; i3 += c2) {
const t3 = Math.min(i3 + c2 - 1, n2);
gt(e3, i3, t3, a2, this.compareMinY);
for (let n3 = i3;n3 <= t3; n3 += a2) {
const i4 = Math.min(n3 + a2 - 1, t3);
r2.children.push(this._build(e3, n3, i4, o2 - 1));
}
}
return ot(r2, this.toBBox), r2;
}
_chooseSubtree(e3, t2, n2, o2) {
for (;o2.push(t2), !t2.leaf && o2.length - 1 !== n2; ) {
let n3, o3 = 1 / 0, i2 = 1 / 0;
for (let r2 = 0;r2 < t2.children.length; r2++) {
const s2 = t2.children[r2], a2 = ct(s2), c2 = ht(e3, s2) - a2;
c2 < i2 ? (i2 = c2, o3 = a2 < o3 ? a2 : o3, n3 = s2) : c2 === i2 && a2 < o3 && (o3 = a2, n3 = s2);
}
t2 = n3 || t2.children[0];
}
return t2;
}
_insert(e3, t2, n2) {
const o2 = n2 ? e3 : this.toBBox(e3), i2 = [], r2 = this._chooseSubtree(o2, this.data, t2, i2);
for (r2.children.push(e3), rt(r2, o2);t2 >= 0 && i2[t2].children.length > this._maxEntries; )
this._split(i2, t2), t2--;
this._adjustParentBBoxes(o2, i2, t2);
}
_split(e3, t2) {
const n2 = e3[t2], o2 = n2.children.length, i2 = this._minEntries;
this._chooseSplitAxis(n2, i2, o2);
const r2 = this._chooseSplitIndex(n2, i2, o2), s2 = mt(n2.children.splice(r2, n2.children.length - r2));
s2.height = n2.height, s2.leaf = n2.leaf, ot(n2, this.toBBox), ot(s2, this.toBBox), t2 ? e3[t2 - 1].children.push(s2) : this._splitRoot(n2, s2);
}
_splitRoot(e3, t2) {
this.data = mt([e3, t2]), this.data.height = e3.height + 1, this.data.leaf = false, ot(this.data, this.toBBox);
}
_chooseSplitIndex(e3, t2, n2) {
let o2, i2 = 1 / 0, r2 = 1 / 0;
for (let s2 = t2;s2 <= n2 - t2; s2++) {
const t3 = it(e3, 0, s2, this.toBBox), a2 = it(e3, s2, n2, this.toBBox), c2 = dt(t3, a2), l2 = ct(t3) + ct(a2);
c2 < i2 ? (i2 = c2, o2 = s2, r2 = l2 < r2 ? l2 : r2) : c2 === i2 && l2 < r2 && (r2 = l2, o2 = s2);
}
return o2 || n2 - t2;
}
_chooseSplitAxis(e3, t2, n2) {
const o2 = e3.leaf ? this.compareMinX : st, i2 = e3.leaf ? this.compareMinY : at;
this._allDistMargin(e3, t2, n2, o2) < this._allDistMargin(e3, t2, n2, i2) && e3.children.sort(o2);
}
_allDistMargin(e3, t2, n2, o2) {
e3.children.sort(o2);
const i2 = this.toBBox, r2 = it(e3, 0, t2, i2), s2 = it(e3, n2 - t2, n2, i2);
let a2 = lt(r2) + lt(s2);
for (let o3 = t2;o3 < n2 - t2; o3++) {
const t3 = e3.children[o3];
rt(r2, e3.leaf ? i2(t3) : t3), a2 += lt(r2);
}
for (let o3 = n2 - t2 - 1;o3 >= t2; o3--) {
const t3 = e3.children[o3];
rt(s2, e3.leaf ? i2(t3) : t3), a2 += lt(s2);
}
return a2;
}
_adjustParentBBoxes(e3, t2, n2) {
for (let o2 = n2;o2 >= 0; o2--)
rt(t2[o2], e3);
}
_condense(e3) {
for (let t2, n2 = e3.length - 1;n2 >= 0; n2--)
e3[n2].children.length === 0 ? n2 > 0 ? (t2 = e3[n2 - 1].children, t2.splice(t2.indexOf(e3[n2]), 1)) : this.clear() : ot(e3[n2], this.toBBox);
}
};
function nt(e3, t2, n2) {
if (!n2)
return t2.indexOf(e3);
for (let o2 = 0;o2 < t2.length; o2++)
if (n2(e3, t2[o2]))
return o2;
return -1;
}
function ot(e3, t2) {
it(e3, 0, e3.children.length, t2, e3);
}
function it(e3, t2, n2, o2, i2) {
i2 || (i2 = mt(null)), i2.minX = 1 / 0, i2.minY = 1 / 0, i2.maxX = -1 / 0, i2.maxY = -1 / 0;
for (let r2 = t2;r2 < n2; r2++) {
const t3 = e3.children[r2];
rt(i2, e3.leaf ? o2(t3) : t3);
}
return i2;
}
function rt(e3, t2) {
return e3.minX = Math.min(e3.minX, t2.minX), e3.minY = Math.min(e3.minY, t2.minY), e3.maxX = Math.max(e3.maxX, t2.maxX), e3.maxY = Math.max(e3.maxY, t2.maxY), e3;
}
function st(e3, t2) {
return e3.minX - t2.minX;
}
function at(e3, t2) {
return e3.minY - t2.minY;
}
function ct(e3) {
return (e3.maxX - e3.minX) * (e3.maxY - e3.minY);
}
function lt(e3) {
return e3.maxX - e3.minX + (e3.maxY - e3.minY);
}
function ht(e3, t2) {
return (Math.max(t2.maxX, e3.maxX) - Math.min(t2.minX, e3.minX)) * (Math.max(t2.maxY, e3.maxY) - Math.min(t2.minY, e3.minY));
}
function dt(e3, t2) {
const n2 = Math.max(e3.minX, t2.minX), o2 = Math.max(e3.minY, t2.minY), i2 = Math.min(e3.maxX, t2.maxX), r2 = Math.min(e3.maxY, t2.maxY);
return Math.max(0, i2 - n2) * Math.max(0, r2 - o2);
}
function ut(e3, t2) {
return e3.minX <= t2.minX && e3.minY <= t2.minY && t2.maxX <= e3.maxX && t2.maxY <= e3.maxY;
}
function pt(e3, t2) {
return t2.minX <= e3.maxX && t2.minY <= e3.maxY && t2.maxX >= e3.minX && t2.maxY >= e3.minY;
}
function mt(e3) {
return { children: e3, height: 1, leaf: true, minX: 1 / 0, minY: 1 / 0, maxX: -1 / 0, maxY: -1 / 0 };
}
function gt(e3, t2, n2, o2, i2) {
const r2 = [t2, n2];
for (;r2.length; ) {
if ((n2 = r2.pop()) - (t2 = r2.pop()) <= o2)
continue;
const s2 = t2 + Math.ceil((n2 - t2) / o2 / 2) * o2;
Qe(e3, s2, t2, n2, i2), r2.push(t2, s2, s2, n2);
}
}
var ft = (e3) => ({ minX: Math.min(...e3.map((e4) => e4.x)), minY: Math.min(...e3.map((e4) => e4.y)), maxX: Math.max(...e3.map((e4) => e4.x)), maxY: Math.max(...e3.map((e4) => e4.y)) });
function _t(e3, t2, n2, o2) {
const i2 = yt(e3, t2, n2), r2 = yt(e3, t2, o2), s2 = yt(n2, o2, e3), a2 = yt(n2, o2, t2);
return i2 !== r2 && s2 !== a2 || (!(i2 !== 0 || !bt(e3, n2, t2)) || (!(r2 !== 0 || !bt(e3, o2, t2)) || (!(s2 !== 0 || !bt(n2, e3, o2)) || !(a2 !== 0 || !bt(n2, t2, o2)))));
}
function yt(e3, t2, n2) {
const o2 = (t2.y - e3.y) * (n2.x - t2.x) - (t2.x - e3.x) * (n2.y - t2.y);
return o2 === 0 ? 0 : o2 > 0 ? 1 : 2;
}
function bt(e3, t2, n2) {
return t2.x <= Math.max(e3.x, n2.x) && t2.x >= Math.min(e3.x, n2.x) && t2.y <= Math.max(e3.y, n2.y) && t2.y >= Math.min(e3.y, n2.y);
}
function xt(e3, t2, n2) {
const o2 = (n2.x - t2.x) ** 2 + (n2.y - t2.y) ** 2;
if (o2 === 0)
return vt(e3, t2);
let i2 = ((e3.x - t2.x) * (n2.x - t2.x) + (e3.y - t2.y) * (n2.y - t2.y)) / o2;
i2 = Math.max(0, Math.min(1, i2));
return vt(e3, { x: t2.x + i2 * (n2.x - t2.x), y: t2.y + i2 * (n2.y - t2.y) });
}
function vt(e3, t2) {
const n2 = e3.x - t2.x, o2 = e3.y - t2.y;
return Math.sqrt(n2 * n2 + o2 * o2);
}
function It(e3, t2, n2, o2) {
const i2 = t2.x - e3.x, r2 = t2.y - e3.y, s2 = o2.x - n2.x, a2 = o2.y - n2.y, c2 = e3.x - n2.x, l2 = e3.y - n2.y, h2 = i2 * a2 - r2 * s2;
if (Math.abs(h2) < 0.0000000001)
return null;
const d2 = (l2 * s2 - c2 * a2) / h2, u2 = (i2 * l2 - r2 * c2) / h2, p2 = 0.000000001;
if (d2 >= -1e-9 && d2 <= 1 + p2 && u2 >= -1e-9 && u2 <= 1 + p2) {
return { x: e3.x + d2 * i2, y: e3.y + d2 * r2 };
}
return null;
}
var St = (e3) => {
if ("minX" in e3)
return e3;
const t2 = e3.width / 2, n2 = e3.height / 2;
return { minX: e3.center.x - t2, minY: e3.center.y - n2, maxX: e3.center.x + t2, maxY: e3.center.y + n2 };
};
var Ct = (e3) => [{ x: e3.minX, y: e3.minY }, { x: e3.maxX, y: e3.minY }, { x: e3.maxX, y: e3.maxY }, { x: e3.minX, y: e3.maxY }];
var Pt = (e3) => {
const t2 = [];
for (let n2 = 0;n2 < e3.length; n2++) {
const o2 = e3[n2], i2 = e3[(n2 + 1) % e3.length];
t2.push([o2, i2]);
}
return t2;
};
var Mt = (e3, t2, n2) => {
const o2 = (e3.y - t2.y) * (n2.x - t2.x) - (e3.x - t2.x) * (n2.y - t2.y);
if (Math.abs(o2) > 0.000000001)
return false;
const i2 = (e3.x - t2.x) * (n2.x - t2.x) + (e3.y - t2.y) * (n2.y - t2.y);
if (i2 < 0)
return false;
const r2 = (n2.x - t2.x) ** 2 + (n2.y - t2.y) ** 2;
return r2 !== 0 && !(i2 > r2);
};
var wt = (e3, t2) => e3.x >= t2.minX && e3.x <= t2.maxX && e3.y >= t2.minY && e3.y <= t2.maxY;
var Nt = (e3, t2) => {
if (t2.length < 3)
return false;
const n2 = Pt(t2);
for (const [t3, o3] of n2)
if (Mt(e3, t3, o3))
return true;
let o2 = false;
for (let n3 = 0, i2 = t2.length - 1;n3 < t2.length; i2 = n3++) {
const r2 = t2[n3].x, s2 = t2[n3].y, a2 = t2[i2].x, c2 = t2[i2].y;
s2 > e3.y != c2 > e3.y && e3.x < (a2 - r2) * (e3.y - s2) / (c2 - s2) + r2 && (o2 = !o2);
}
return o2;
};
var Tt = (e3, t2) => {
const n2 = Ct(e3), o2 = [[n2[0], n2[1]], [n2[1], n2[2]], [n2[2], n2[3]], [n2[3], n2[0]]], i2 = Pt(t2);
for (const [e4, t3] of i2)
for (const [n3, i3] of o2)
if (_t(e4, t3, n3, i3))
return true;
return false;
};
var Rt = (e3, t2) => ((e4, t3) => !(t3.length < 3) && (!!t3.some((t4) => wt(t4, e4)) || (!!Ct(e4).some((e5) => Nt(e5, t3)) || Tt(e4, t3))))(St(e3), t2);
function At(e3) {
const t2 = e3.width / 2, n2 = e3.height / 2;
return { minX: e3.center.x - t2, maxX: e3.center.x + t2, minY: e3.center.y - n2, maxY: e3.center.y + n2 };
}
function Ot(e3, t2, n2) {
return Math.max(t2, Math.min(n2, e3));
}
function kt(e3, t2, n2, o2) {
if (e3.x === t2.x && e3.y === t2.y)
return xt(e3, n2, o2);
if (n2.x === o2.x && n2.y === o2.y)
return xt(n2, e3, t2);
if (_t(e3, t2, n2, o2))
return 0;
const i2 = [xt(e3, n2, o2), xt(t2, n2, o2), xt(n2, e3, t2), xt(o2, e3, t2)];
return Math.min(...i2);
}
function Dt(e3, t2, n2) {
const o2 = { x: n2.minX, y: n2.minY }, i2 = { x: n2.maxX, y: n2.minY }, r2 = { x: n2.minX, y: n2.maxY }, s2 = { x: n2.maxX, y: n2.maxY };
if (_t(e3, t2, o2, i2) || _t(e3, t2, i2, s2) || _t(e3, t2, s2, r2) || _t(e3, t2, r2, o2))
return 0;
if (e3.x >= n2.minX && e3.x <= n2.maxX && e3.y >= n2.minY && e3.y <= n2.maxY && t2.x >= n2.minX && t2.x <= n2.maxX && t2.y >= n2.minY && t2.y <= n2.maxY)
return 0;
const a2 = [xt(o2, e3, t2), xt(i2, e3, t2), xt(r2, e3, t2), xt(s2, e3, t2)];
if (e3.x >= n2.minX && e3.x <= n2.maxX && e3.y >= n2.minY && e3.y <= n2.maxY)
return 0;
if (t2.x >= n2.minX && t2.x <= n2.maxX && t2.y >= n2.minY && t2.y <= n2.maxY)
return 0;
if (e3.x < n2.minX || e3.x > n2.maxX || e3.y < n2.minY || e3.y > n2.maxY) {
const t3 = Ot(e3.x, n2.minX, n2.maxX), o3 = Ot(e3.y, n2.minY, n2.maxY);
a2.push(vt(e3, { x: t3, y: o3 }));
}
if (t2.x < n2.minX || t2.x > n2.maxX || t2.y < n2.minY || t2.y > n2.maxY) {
const e4 = Ot(t2.x, n2.minX, n2.maxX), o3 = Ot(t2.y, n2.minY, n2.maxY);
a2.push(vt(t2, { x: e4, y: o3 }));
}
return Math.min(...a2);
}
function Lt(e3, t2, n2) {
const o2 = n2.width / 2, i2 = n2.height / 2;
return Dt(e3, t2, { minX: n2.center.x - o2, maxX: n2.center.x + o2, minY: n2.center.y - i2, maxY: n2.center.y + i2 });
}
function zt(e3, t2, n2) {
const o2 = { x: n2.x, y: n2.y };
if (e3.x === t2.x && e3.y === t2.y)
return Math.max(0, vt(e3, o2) - n2.radius);
const i2 = t2.x - e3.x, r2 = t2.y - e3.y, s2 = o2.x - e3.x, a2 = o2.y - e3.y, c2 = i2 * i2 + r2 * r2, l2 = Math.max(0, Math.min(1, (i2 * s2 + r2 * a2) / c2)), h2 = vt({ x: e3.x + l2 * i2, y: e3.y + l2 * r2 }, o2);
return Math.max(0, h2 - n2.radius);
}
function Bt(e3, t2, n2) {
const o2 = n2.x - t2.x, i2 = n2.y - t2.y, r2 = o2 * o2 + i2 * i2;
if (r2 === 0)
return { x: t2.x, y: t2.y };
let s2 = ((e3.x - t2.x) * o2 + (e3.y - t2.y) * i2) / r2;
s2 = Math.max(0, Math.min(1, s2));
return { x: t2.x + s2 * o2, y: t2.y + s2 * i2 };
}
var Ft = (e3, t2) => {
const n2 = t2.x - e3.x, o2 = t2.y - e3.y, i2 = Math.sqrt(n2 ** 2 + o2 ** 2);
return { x: n2 / i2, y: o2 / i2 };
};
function jt(e3, t2) {
const n2 = t2.width / 2, o2 = t2.height / 2, i2 = t2.center.x - n2, r2 = t2.center.x + n2, s2 = t2.center.y - o2, a2 = t2.center.y + o2;
if (e3.x >= i2 && e3.x <= r2 && e3.y >= s2 && e3.y <= a2)
return 0;
return vt(e3, { x: Ot(e3.x, i2, r2), y: Ot(e3.y, s2, a2) });
}
function $t(e3, t2) {
if (e3.x >= t2.minX && e3.x <= t2.maxX && e3.y >= t2.minY && e3.y <= t2.maxY)
return 0;
return vt(e3, { x: Ot(e3.x, t2.minX, t2.maxX), y: Ot(e3.y, t2.minY, t2.maxY) });
}
function Yt(e3, t2) {
return { x: (e3.x + t2.x) / 2, y: (e3.y + t2.y) / 2 };
}
function Xt(e3, t2) {
const n2 = e3.x - t2.x, o2 = e3.y - t2.y;
return n2 * n2 + o2 * o2;
}
var Wt = (e3, t2) => !(e3.maxX < t2.minX || t2.maxX < e3.minX || e3.maxY < t2.minY || t2.maxY < e3.minY);
var Vt = (e3) => {
const { center: t2, width: n2, height: o2 } = e3, i2 = n2 / 2, r2 = o2 / 2;
return { minX: t2.x - i2, maxX: t2.x + i2, minY: t2.y - r2, maxY: t2.y + r2 };
};
var Ht = (e3) => {
if (e3.length === 0)
return null;
let t2 = e3[0].x, n2 = e3[0].y, o2 = e3[0].x, i2 = e3[0].y;
for (let r2 = 1;r2 < e3.length; r2++) {
const s2 = e3[r2];
s2.x < t2 && (t2 = s2.x), s2.y < n2 && (n2 = s2.y), s2.x > o2 && (o2 = s2.x), s2.y > i2 && (i2 = s2.y);
}
return { minX: t2, minY: n2, maxX: o2, maxY: i2 };
};
var Gt = 0.0001;
var Ut = class extends De {
constructor(e3) {
super(), this.input = e3, this.input.bounds && ((e4) => {
const { minX: t2, maxX: n2, minY: o2, maxY: i2 } = e4;
if (![t2, n2, o2, i2].every(Number.isFinite))
throw new Error(`ExpandEdgesToEmptySpaceSolver bounds must be finite, got ${JSON.stringify(e4)}`);
if (t2 > n2 || o2 > i2)
throw new Error(`ExpandEdgesToEmptySpaceSolver bounds must satisfy minX <= maxX and minY <= maxY, got ${JSON.stringify(e4)}`);
})(this.input.bounds), this.unprocessedSegments = [...this.input.segmentsWithAdjacentEmptySpace], this.rectSpatialIndex = new tt, this.rectSpatialIndex.load(this.input.boardVoid?.boardVoidRects.map((e4, t2) => ({ capacityMeshNodeId: `void-rect-${t2}`, center: { x: e4.x + e4.width / 2, y: e4.y + e4.height / 2 }, width: e4.width, height: e4.height, availableZ: Array.from({ length: this.input.boardVoid?.layerCount || 0 }, (e5, t3) => t3), layer: "void", minX: e4.x, minY: e4.y, maxX: e4.x + e4.width, maxY: e4.y + e4.height })) || []), this.rectSpatialIndex.load(this.input.inputMeshNodes.map((e4) => ({ ...e4, minX: e4.center.x - e4.width / 2, minY: e4.center.y - e4.height / 2, maxX: e4.center.x + e4.width / 2, maxY: e4.center.y + e4.height / 2 })));
}
input;
unprocessedSegments = [];
expandedSegments = [];
lastSegment = null;
lastSearchBounds = null;
lastCollidingNodes = null;
lastSearchCorner1 = null;
lastSearchCorner2 = null;
lastExpandedSegment = null;
rectSpatialIndex;
_step() {
if (this.unprocessedSegments.length === 0)
return void (this.solved = true);
const e3 = this.unprocessedSegments.shift();
this.lastSegment = e3;
const t2 = this.input.bounds;
let n2 = e3;
if (t2) {
const o3 = ((e4, t3) => {
const n3 = { ...e4.start }, o4 = { ...e4.end };
if (He[e4.facingDirection].dx !== 0) {
if (n3.x < t3.minX || n3.x > t3.maxX)
return null;
n3.y = Math.max(t3.minY, Math.min(t3.maxY, n3.y)), o4.y = Math.max(t3.minY, Math.min(t3.maxY, o4.y));
} else {
if (n3.y < t3.minY || n3.y > t3.maxY)
return null;
n3.x = Math.max(t3.minX, Math.min(t3.maxX, n3.x)), o4.x = Math.max(t3.minX, Math.min(t3.maxX, o4.x));
}
return { ...e4, start: n3, end: o4 };
})(e3, t2);
if (!o3)
return;
n2 = o3, this.lastSegment = o3;
}
const { dx: o2, dy: i2 } = He[n2.facingDirection], r2 = n2.end.x - n2.start.x, s2 = n2.end.y - n2.start.y, a2 = Math.sqrt(r2 ** 2 + s2 ** 2);
if (a2 < Gt)
return;
const c2 = r2 / a2, l2 = s2 / a2, h2 = t2 ? ((e4, t3) => {
switch (e4.facingDirection) {
case "x+":
return t3.maxX - e4.start.x;
case "x-":
return e4.start.x - t3.minX;
case "y+":
return t3.maxY - e4.start.y;
case "y-":
return e4.start.y - t3.minY;
}
})(n2, t2) : 1 / 0;
if (h2 < Gt)
return;
const d2 = { x: n2.start.x + o2 * Gt + c2 * Gt * 10, y: n2.start.y + i2 * Gt + l2 * Gt * 10 }, u2 = { x: n2.end.x + o2 * Gt - c2 * Gt * 10, y: n2.end.y + i2 * Gt - l2 * Gt * 10 };
this.lastSearchCorner1 = d2, this.lastSearchCorner2 = u2;
let p2 = [];
for (let e4 = 1;t2 || e4 < 1000; e4 *= 4) {
const t3 = Math.min(e4, h2), r3 = ft([d2, u2, { x: d2.x + o2 * t3, y: d2.y + i2 * t3 }, { x: u2.x + o2 * t3, y: u2.y + i2 * t3 }]);
if (this.lastSearchBounds = r3, p2 = this.rectSpatialIndex.search(r3).filter((e5) => e5.availableZ.includes(n2.z)).filter((e5) => e5.capacityMeshNodeId !== n2.parent.capacityMeshNodeId), p2.length > 0)
break;
if (e4 >= h2)
break;
}
if (p2.length === 0 && !t2)
return;
this.lastCollidingNodes = p2;
let m2 = h2;
for (const e4 of p2) {
const t3 = Lt(n2.start, n2.end, e4);
t3 < m2 && (m2 = t3);
}
const g2 = m2, f2 = ft([n2.start, n2.end, { x: n2.start.x + o2 * g2, y: n2.start.y + i2 * g2 }, { x: n2.end.x + o2 * g2, y: n2.end.y + i2 * g2 }]), _2 = { x: (f2.minX + f2.maxX) / 2, y: (f2.minY + f2.maxY) / 2 }, y2 = f2.maxX - f2.minX, b2 = f2.maxY - f2.minY, x2 = { segment: n2, newNode: { capacityMeshNodeId: `new-${n2.parent.capacityMeshNodeId}-${this.expandedSegments.length}`, center: _2, width: y2, height: b2, availableZ: [n2.z], layer: n2.parent.layer } };
this.lastExpandedSegment = x2, y2 < Gt || b2 < Gt || (this.expandedSegments.push(x2), this.rectSpatialIndex.insert({ ...x2.newNode, ...f2 }));
}
getOutput() {
return { expandedSegments: this.expandedSegments };
}
visualize() {
const e3 = { title: "ExpandEdgesToEmptySpace", coordinateSystem: "cartesian", rects: [], points: [], lines: [], circles: [], infiniteLines: [], polygons: [], arrows: [], texts: [] };
for (const t2 of this.input.inputMeshNodes)
e3.rects.push({ center: t2.center, width: t2.width, height: t2.height, stroke: "rgba(0, 0, 0, 0.1)", layer: `z${t2.availableZ.join(",")}`, label: [`node ${t2.capacityMeshNodeId}`, `z:${t2.availableZ.join(",")}`].join(`
`) });
for (const { newNode: t2 } of this.expandedSegments)
e3.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: "green", label: `expandedSegment (z=${t2.availableZ.join(",")})`, layer: `z${t2.availableZ.join(",")}` });
if (this.lastSegment && e3.lines.push({ points: [this.lastSegment.start, this.lastSegment.end], strokeColor: "rgba(0, 0, 255, 0.5)" }), this.lastSearchBounds && e3.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 && (e3.points.push({ x: this.lastSearchCorner1.x, y: this.lastSearchCorner1.y, color: "rgba(0, 0, 255, 0.5)", label: ["searchCorner1", `z=${this.lastSegment?.z}`].join(`
`) }), e3.points.push({ x: this.lastSearchCorner2.x, y: this.lastSearchCorner2.y, color: "rgba(0, 0, 255, 0.5)", label: ["searchCorner2", `z=${this.lastSegment?.z}`].join(`
`) })), this.lastExpandedSegment && e3.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 t2 of this.lastCollidingNodes)
e3.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: "rgba(255, 0, 0, 0.5)" });
return e3;
}
};
var Zt = class extends ze {
findSegmentsWithAdjacentEmptySpaceSolver;
expandEdgesToEmptySpaceSolver;
outputNodes = [];
passExpandedCounts = [];
currentPassNodes = [];
currentTargetNodes = [];
currentPassIndex = 0;
expandedNodeIds = new Set;
maxGapFillPasses = 1;
pipelineDef = [Le("findSegmentsWithAdjacentEmptySpaceSolver", Je, (e3) => [{ allMeshNodes: e3.currentPassNodes, targetMeshNodes: e3.currentTargetNodes }], { onSolved: () => {} }), Le("expandEdgesToEmptySpaceSolver", Ut, (e3) => [{ inputMeshNodes: e3.currentPassNodes, segmentsWithAdjacentEmptySpace: e3.findSegmentsWithAdjacentEmptySpaceSolver.getOutput().segmentsWithAdjacentEmptySpace, boardVoid: e3.inputProblem.boardVoid, bounds: e3.inputProblem.bounds }], { onSolved: (e3) => {
e3.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 e3 = this.inputProblem.maxGapFillPasses;
this.maxGapFillPasses = Number.isFinite(e3) ? Math.max(1, Math.floor(e3)) : 1;
}
completePass() {
const e3 = (this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments ?? []).map((e4) => e4.newNode);
for (const t2 of e3)
this.expandedNodeIds.add(t2.capacityMeshNodeId);
this.passExpandedCounts.push(e3.length), this.currentPassNodes = [...this.currentPassNodes, ...e3], this.currentTargetNodes = e3, this.outputNodes = this.currentPassNodes, e3.length === 0 || this.currentPassIndex + 1 >= this.maxGapFillPasses || (this.currentPassIndex += 1, this.currentPipelineStageIndex = -1);
}
getOutput() {
return { outputNodes: this.outputNodes.length ? this.outputNodes : this.inputProblem.meshNodes };
}
initialVisualize() {
const e3 = { title: "GapFillSolverPipeline - Initial", coordinateSystem: "cartesian", rects: [], points: [], lines: [], circles: [], infiniteLines: [], polygons: [], arrows: [], texts: [] };
for (const t2 of this.inputProblem.meshNodes)
e3.rects.push({ center: t2.center, width: t2.width, height: t2.height, stroke: "rgba(0, 0, 0, 0.3)", fill: "rgba(100, 100, 100, 0.1)", layer: `z${t2.availableZ.join(",")}`, label: [`node ${t2.capacityMeshNodeId}`, `z:${t2.availableZ.join(",")}`].join(`
`) });
return e3;
}
finalVisualize() {
const e3 = { title: "GapFillSolverPipeline - Final", coordinateSystem: "cartesian", rects: [], points: [], lines: [], circles: [], infiniteLines: [], polygons: [], arrows: [], texts: [] }, { outputNodes: t2 } = this.getOutput();
for (const n2 of t2) {
const t3 = this.expandedNodeIds.has(n2.capacityMeshNodeId);
e3.rects.push({ center: n2.center, width: n2.width, height: n2.height, stroke: t3 ? "rgba(0, 128, 0, 0.8)" : "rgba(0, 0, 0, 0.3)", fill: t3 ? "rgba(0, 200, 0, 0.3)" : "rgba(100, 100, 100, 0.1)", layer: `z${n2.availableZ.join(",")}`, label: [`${t3 ? "[expanded] " : ""}node ${n2.capacityMeshNodeId}`, `z:${n2.availableZ.join(",")}`].join(`
`) });
}
return e3;
}
};
function qt(e3) {
const t2 = e3.toLowerCase();
if (t2 === "top")
return -1e6;
if (t2 === "bottom")
return 1e6;
const n2 = /^inner(\d+)$/i.exec(t2);
return n2 ? parseInt(n2[1], 10) || 0 : 100 + t2.charCodeAt(0);
}
function Jt(e3) {
const t2 = function(e4) {
return Array.from(new Set(e4)).sort((e5, t3) => {
const n3 = qt(e5), o3 = qt(t3);
return n3 !== o3 ? n3 - o3 : e5.localeCompare(t3);
});
}((e3.obstacles ?? []).flatMap((e4) => e4.layers ?? [])), n2 = Math.max(1, e3.layerCount || t2.length || 1), o2 = Array.from({ length: n2 }, (e4, t3) => t3 === 0 ? "top" : t3 === n2 - 1 ? "bottom" : `inner${t3}`), i2 = [], r2 = new Set, s2 = (e4) => {
const t3 = e4.toLowerCase();
r2.has(t3) || (r2.add(t3), i2.push(e4));
};
o2.forEach(s2), t2.forEach(s2);
const a2 = i2.slice(0, n2), c2 = new Map;
return a2.forEach((e4, t3) => c2.set(e4.toLowerCase(), t3)), i2.slice(a2.length).forEach((e4) => {
const t3 = e4.toLowerCase();
c2.set(t3, ((e5) => {
if (a2.length <= 1)
return 0;
if (e5 === "top")
return 0;
if (e5 === "bottom")
return a2.length - 1;
const t4 = /^inner(\d+)$/i.exec(e5);
if (t4) {
if (a2.length <= 2)
return a2.length - 1;
const e6 = parseInt(t4[1], 10), n3 = a2.length - 2;
return Math.min(n3, Math.max(1, Number.isFinite(e6) ? e6 : 1));
}
return 0;
})(t3));
}), { layerNames: a2, zIndexByName: c2 };
}
function Qt(e3, t2) {
if (e3.zLayers?.length)
return Array.from(new Set(e3.zLayers)).sort((e4, t3) => e4 - t3);
const n2 = (e3.layers ?? []).map((e4) => t2.get(e4.toLowerCase())).filter((e4) => typeof e4 == "number");
return Array.from(new Set(n2)).sort((e4, t3) => e4 - t3);
}
function Kt(e3) {
const { width: t2, height: n2 } = e3;
return typeof t2 != "number" || typeof n2 != "number" ? null : { x: e3.center.x - t2 / 2, y: e3.center.y - n2 / 2, width: t2, height: n2 };
}
var en = (e3) => {
const t2 = [{ 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 t2[Math.min(...e3) % t2.length];
};
var tn = 0.000000001;
var nn = (e3, t2) => e3 > t2 + tn;
var on = (e3, t2) => e3 > t2 - tn;
var rn = (e3, t2) => e3 < t2 - tn;
var sn = (e3, t2) => e3 < t2 + tn;
function an(e3, t2) {
return !(e3.x + e3.width <= t2.x + tn || t2.x + t2.width <= e3.x + tn || e3.y + e3.height <= t2.y + tn || t2.y + t2.height <= e3.y + tn);
}
function cn(e3, t2) {
const n2 = t2.x, o2 = t2.x + t2.width, i2 = t2.y, r2 = t2.y + t2.height;
if (e3.x >= n2 && e3.x <= o2 && e3.y >= i2 && e3.y <= r2)
return Math.min(e3.x - n2, o2 - e3.x, e3.y - i2, r2 - e3.y);
const s2 = e3.x < n2 ? n2 - e3.x : e3.x > o2 ? e3.x - o2 : 0, a2 = e3.y < i2 ? i2 - e3.y : e3.y > r2 ? e3.y - r2 : 0;
return s2 === 0 ? a2 : a2 === 0 ? s2 : Math.hypot(s2, a2);
}
function ln(e3, t2) {
const n2 = Math.max(e3[0], t2[0]), o2 = Math.min(e3[1], t2[1]);
return o2 > n2 + tn ? [n2, o2] : null;
}
function hn(e3, t2) {
if (!an(e3, t2))
return [e3];
const n2 = ln([e3.x, e3.x + e3.width], [t2.x, t2.x + t2.width]), o2 = ln([e3.y, e3.y + e3.height], [t2.y, t2.y + t2.height]);
if (!n2 || !o2)
return [e3];
const [i2, r2] = n2, [s2, a2] = o2, c2 = [];
i2 > e3.x + tn && c2.push({ x: e3.x, y: e3.y, width: i2 - e3.x, height: e3.height }), e3.x + e3.width > r2 + tn && c2.push({ x: r2, y: e3.y, width: e3.x + e3.width - r2, height: e3.height });
const l2 = Math.max(0, r2 - i2);
return l2 > tn && s2 > e3.y + tn && c2.push({ x: i2, y: e3.y, width: l2, height: s2 - e3.y }), l2 > tn && e3.y + e3.height > a2 + tn && c2.push({ x: i2, y: a2, width: l2, height: e3.y + e3.height - a2 }), c2.filter((e4) => e4.width > tn && e4.height > tn);
}
var dn = (e3, t2) => !t2 || t2 <= 0 ? e3 : { x: e3.x - t2, y: e3.y - t2, width: e3.width + 2 * t2, height: e3.height + 2 * t2 };
var un = (e3) => ({ x: e3.center.x - e3.width / 2, y: e3.center.y - e3.height / 2, width: e3.width, height: e3.height });
var pn = (e3) => e3.width * e3.height;
var mn = (e3) => ({ ...e3, center: { ...e3.center }, availableZ: [...e3.availableZ] });
var gn = (e3, t2, n2) => ({ ...e3, capacityMeshNodeId: n2, center: { x: t2.x + t2.width / 2, y: t2.y + t2.height / 2 }, width: t2.width, height: t2.height, availableZ: [...e3.availableZ], layer: `z${e3.availableZ.join(",")}` });
var fn = (e3) => !e3._containsObstacle && !e3._containsTarget;
var _n = (e3, t2) => e3.availableZ.length === 1 && e3.availableZ[0] === t2;
var yn = (e3, t2) => Math.abs(e3.x - t2.x) <= tn && Math.abs(e3.y - t2.y) <= tn && Math.abs(e3.width - t2.width) <= tn && Math.abs(e3.height - t2.height) <= tn;
var bn = (e3, t2) => {
let n2 = [e3];
for (const e4 of t2) {
if (n2.length === 0)
return n2;
const t3 = [];
for (const o2 of n2)
t3.push(...hn(o2, e4));
n2 = t3;
}
return n2;
};
var xn = (e3, t2) => bn(e3, t2).length === 0;
var vn = class extends De {
constructor(e3) {
super(), this.input = e3;
}
input;
outputNodes = [];
promotedNodeIds = new Set;
residualNodeIds = new Set;
_setup() {
this.outputNodes = this.input.meshNodes.map(mn), this.promotedNodeIds.clear(), this.residualNodeIds.clear();
}
_step() {
this.outputNodes = this.processOuterLayerContainmentMerges(), this.solved = true;
}
processOuterLayerContainmentMerges() {
const e3 = this.input.simpleRouteJson, t2 = Math.max(1, e3.layerCount || 1);
if (t2 < 3)
return this.input.meshNodes.map(mn);
const n2 = t2 - 1, o2 = Math.max(e3.minViaDiameter ?? 0, e3.minTraceWidth || 0), i2 = this.input.meshNodes.map(mn), r2 = this.buildObstaclesByLayer(t2);
if (!r2.slice(1, -1).some((e4) => e4.some((e5) => e5.obstacle.isCopperPour)))
return i2;
const s2 = i2.filter((e4) => fn(e4) && (_n(e4, 0) || _n(e4, n2))), a2 = i2.filter((e4) => !fn(e4)), c2 = a2.filter((e4) => e4.availableZ.includes(0) || e4.availableZ.includes(n2)).map(un), l2 = new Map;
l2.set(0, i2.filter((e4) => fn(e4) && e4.availableZ.includes(0))), l2.set(n2, i2.filter((e4) => fn(e4) && e4.availableZ.includes(n2)));
const h2 = [], d2 = [], u2 = s2.filter((e4) => e4.width + tn >= o2 && e4.height + tn >= o2).sort((e4, t3) => pn(un(t3)) - pn(un(e4)));
for (const e4 of u2) {
const t3 = e4.availableZ[0], i3 = t3 === 0 ? n2 : 0, s3 = un(e4);
if (c2.some((e5) => an(e5, s3)))
continue;
const a3 = (l2.get(i3) ?? []).filter((e5) => an(s3, un(e5))), u3 = a3[0]?.availableZ;
if (!u3)
continue;
if (d2.some((e5) => an(s3, e5)))
continue;
if (!this.isTransitCompatibleAcrossIntermediateLayers({ rect: s3, fromZ: t3, toZ: i3, obstaclesByLayer: r2 }))
continue;
if (!xn(s3, a3.map(un)))
continue;
const p3 = a3.every((e5) => e5.availableZ.length === u3.length && e5.availableZ.every((e6) => u3.includes(e6))) ? [{ rect: s3, availableZ: u3 }] : a3.map((e5) => {
const t4 = un(e5), n3 = Math.max(s3.x, t4.x), o3 = Math.max(s3.y, t4.y);
return { rect: { x: n3, y: o3, width: Math.min(s3.x + s3.width, t4.x + t4.width) - n3, height: Math.min(s3.y + s3.height, t4.y + t4.height) - o3 }, availableZ: e5.availableZ };
});
for (const [n3, i4] of p3.entries()) {
if (i4.rect.width + tn < o2 || i4.rect.height + tn < o2)
continue;
const r3 = [...new Set([t3, ...i4.availableZ])].sort((e5, t4) => e5 - t4), s4 = n3 === 0 ? e4.capacityMeshNodeId : `${e4.capacityMeshNodeId}-outer-support-${n3}`;
h2.push(gn({ ...e4, availableZ: r3 }, i4.rect, s4)), d2.push(i4.rect), this.promotedNodeIds.add(s4);
}
}
if (h2.length === 0)
return i2;
let p2 = 0;
const m2 = [];
for (const e4 of i2.filter(fn)) {
const t3 = un(e4);
if (e4.availableZ.filter((e5) => e5 === 0 || e5 === n2).length === 0) {
m2.push(e4);
continue;
}
const o3 = bn(t3, d2);
if (o3.length === 1 && yn(o3[0], t3))
m2.push(e4);
else
for (const t4 of o3) {
const n3 = gn(e4, t4, `${e4.capacityMeshNodeId}-outer-merge-${p2++}`);
m2.push(n3), this.residualNodeIds.add(n3.capacityMeshNodeId);
}
}
return [...a2, ...h2, ...m2];
}
buildObstaclesByLayer(e3) {
const t2 = Array.from({ length: e3 }, () => []);
for (const n2 of this.input.simpleRouteJson.obstacles ?? []) {
const o2 = Kt(n2);
if (!o2)
continue;
const i2 = dn(o2, this.input.obstacleClearance ?? 0), r2 = Qt(n2, this.input.zIndexByName);
for (const o3 of r2)
o3 < 0 || o3 >= e3 || t2[o3].push({ obstacle: n2, rect: i2 });
}
return t2;
}
isTransitCompatibleAcrossIntermediateLayers(e3) {
const { rect: t2, fromZ: n2, toZ: o2, obstaclesByLayer: i2 } = e3, r2 = Math.min(n2, o2), s2 = Math.max(n2, o2);
if (s2 - r2 < 2)
return false;
let a2 = false;
for (let e4 = r2 + 1;e4 < s2; e4++) {
const n3 = (i2[e4] ?? []).filter((e5) => an(e5.rect, t2));
if (n3.length === 0)
continue;
if (n3.some((e5) => !e5.obstacle.isCopperPour))
return false;
if (!xn(t2, n3.map((e5) => e5.rect)))
return false;
a2 = true;
}
return a2;
}
getOutput() {
return { outputNodes: this.outputNodes };
}
visualize() {
return { title: "OuterLayerContainmentMergeSolver", coordinateSystem: "cartesian", rects: this.outputNodes.map((e3) => {
const t2 = en(e3.availableZ), n2 = this.promotedNodeIds.has(e3.capacityMeshNodeId), o2 = this.residualNodeIds.has(e3.capacityMeshNodeId);
return { center: e3.center, width: e3.width, height: e3.height, stroke: n2 ? "rgba(22, 163, 74, 0.95)" : o2 ? "rgba(37, 99, 235, 0.95)" : t2.stroke, fill: e3._containsObstacle ? "rgba(239, 68, 68, 0.35)" : n2 ? "rgba(34, 197, 94, 0.28)" : o2 ? "rgba(59, 130, 246, 0.18)" : t2.fill, layer: `z${e3.availableZ.join(",")}`, label: [`node ${e3.capacityMeshNodeId}`, `z:${e3.availableZ.join(",")}`].join(`
`) };
}), points: [], lines: [], texts: [] };
}
};
var In = 0.000000001;
var Sn = (e3) => Math.abs(e3.rect.x + e3.rect.width / 2 - e3.startX) < In && Math.abs(e3.rect.y + e3.rect.height / 2 - e3.startY) < In && Math.abs(e3.rect.width - e3.initialW) < In && Math.abs(e3.rect.height - e3.initialH) < In;
var Cn = ({ rect: e3, bounds: t2 }) => ({ x: e3.x, y: e3.y, width: t2.x + t2.width - e3.x, height: e3.height });
var Pn = ({ rect: e3, bounds: t2 }) => ({ x: e3.x, y: e3.y, width: e3.width, height: t2.y + t2.height - e3.y });
var Mn = ({ rect: e3, bounds: t2 }) => ({ x: t2.x, y: e3.y, width: e3.x - t2.x, height: e3.height });
var wn = ({ rect: e3, bounds: t2 }) => ({ x: e3.x, y: t2.y, width: e3.width, height: e3.y - t2.y });
var Nn = (e3, t2 = 0.000001) => Math.round(e3 / t2) * t2;
var Tn = (e3) => ({ x: Nn(e3.x), y: Nn(e3.y), width: Nn(e3.width), height: Nn(e3.height) });
function Rn(e3) {
const { r: t2, bounds: n2, blockers: o2, maxAspect: i2 } = e3;
let r2 = n2.x + n2.width - t2.x;
for (const e4 of o2) {
if (t2.y + t2.height > e4.y + tn && e4.y + e4.height > t2.y + tn) {
if (on(e4.x, t2.x + t2.width))
r2 = Math.min(r2, e4.x - t2.x);
else if (e4.x + e4.width > t2.x + t2.width - tn && e4.x < t2.x + t2.width + tn)
return 0;
}
}
let s2 = Math.max(0, r2 - t2.width);
if (s2 <= 0)
return 0;
if (i2 != null) {
const { width: e4, height: n3 } = t2;
e4 >= n3 && (s2 = Math.min(s2, i2 * n3 - e4));
}
return Math.max(0, s2);
}
function En(e3) {
const { r: t2, bounds: n2, blockers: o2, maxAspect: i2 } = e3;
let r2 = n2.y + n2.height - t2.y;
for (const e4 of o2) {
if (t2.x + t2.width > e4.x + tn && e4.x + e4.width > t2.x + tn) {
if (on(e4.y, t2.y + t2.height))
r2 = Math.min(r2, e4.y - t2.y);
else if (e4.y + e4.height > t2.y + t2.height - tn && e4.y < t2.y + t2.height + tn)
return 0;
}
}
let s2 = Math.max(0, r2 - t2.height);
if (s2 <= 0)
return 0;
if (i2 != null) {
const { width: e4, height: n3 } = t2;
n3 >= e4 && (s2 = Math.min(s2, i2 * e4 - n3));
}
return Math.max(0, s2);
}
function An(e3) {
const { r: t2, bounds: n2, blockers: o2, maxAspect: i2 } = e3;
let r2 = n2.x;
for (const e4 of o2) {
if (t2.y + t2.height > e4.y + tn && e4.y + e4.height > t2.y + tn) {
if (sn(e4.x + e4.width, t2.x))
r2 = Math.max(r2, e4.x + e4.width);
else if (e4.x < t2.x + tn && e4.x + e4.width > t2.x - tn)
return 0;
}
}
let s2 = Math.max(0, t2.x - r2);
if (s2 <= 0)
return 0;
if (i2 != null) {
const { width: e4, height: n3 } = t2;
e4 >= n3 && (s2 = Math.min(s2, i2 * n3 - e4));
}
return Math.max(0, s2);
}
function On(e3) {
const { r: t2, bounds: n2, blockers: o2, maxAspect: i2 } = e3;
let r2 = n2.y;
for (const e4 of o2) {
if (t2.x + t2.width > e4.x + tn && e4.x + e4.width > t2.x + tn) {
if (sn(e4.y + e4.height, t2.y))
r2 = Math.max(r2, e4.y + e4.height);
else if (e4.y < t2.y + tn && e4.y + e4.height > t2.y - tn)
return 0;
}
}
let s2 = Math.max(0, t2.y - r2);
if (s2 <= 0)
return 0;
if (i2 != null) {
const { width: e4, height: n3 } = t2;
n3 >= e4 && (s2 = Math.min(s2, i2 * e4 - n3));
}
return Math.max(0, s2);
}
var kn = (e3) => {
const { rect: t2, seen: n2, blockers: o2 } = e3;
n2.has(t2) || (n2.add(t2), o2.push(t2));
};
function Dn(e3) {
const { startX: t2, startY: n2, gridSize: o2, bounds: i2, obsticalIndexByLayer: r2, placedIndexByLayer: s2, initialCellRatio: a2, maxAspectRatio: c2, minReq: l2 } = e3, h2 = Math.max(0.000000001, o2 * a2), d2 = Math.max(h2, l2.width), u2 = Math.max(h2, l2.height), p2 = [], m2 = new Set, g2 = s2.length, f2 = (o3) => {
const a3 = ((e4) => {
const { bounds: t3, rect: n3 } = e4, o4 = Math.max(t3.x, n3.x), i3 = Math.max(t3.y, n3.y), r3 = Math.min(t3.x + t3.width, n3.x + n3.width), s3 = Math.min(t3.y + t3.height, n3.y + n3.height);
return r3 <= o4 + tn || s3 <= i3 + tn ? null : { minX: o4, minY: i3, maxX: r3, maxY: s3 };
})({ bounds: i2, rect: o3 });
if (a3)
for (const o4 of e3.zLayers) {
const e4 = r2[o4];
if (e4)
for (const t3 of e4.search(a3))
kn({ rect: t3, seen: m2, blockers: p2 });
const i3 = s2[o4];
if (i3)
for (const e5 of i3.search(a3)) {
e5.zLayers.length >= g2 && (Sn({ rect: e5, startX: t2, startY: n2, initialW: d2, initialH: u2 }) || kn({ rect: e5, seen: m2, blockers: p2 }));
}
}
}, _2 = [{ ox: 0, oy: 0 }, { ox: -d2, oy: 0 }, { ox: 0, oy: -u2 }, { ox: -d2, oy: -u2 }, { ox: -d2 / 2, oy: -u2 / 2 }];
let y2 = null, b2 = 0;
e:
for (const e4 of _2) {
let o3 = { x: t2 + e4.ox, y: n2 + e4.oy, width: d2, height: u2 };
if (f2(o3), rn(o3.x, i2.x) || rn(o3.y, i2.y) || nn(o3.x + o3.width, i2.x + i2.width) || nn(o3.y + o3.height, i2.y + i2.height))
continue;
for (const e5 of p2)
if (an(o3, e5))
continue e;
const r3 = 0.000001, s3 = 1000;
let a3 = true, h3 = 0;
for (;a3 && h3 < s3; ) {
h3++, a3 = false;
const e5 = { bounds: i2, blockers: p2, maxAspect: c2 };
f2(Cn({ rect: o3, bounds: i2 }));
const t3 = Rn({ ...e5, r: o3 });
t3 > r3 && (o3 = { ...o3, width: o3.width + t3 }, f2(o3), a3 = true), f2(Pn({ rect: o3, bounds: i2 }));
const n3 = En({ ...e5, r: o3 });
n3 > r3 && (o3 = { ...o3, height: o3.height + n3 }, f2(o3), a3 = true), f2(Mn({ rect: o3, bounds: i2 }));
const s4 = An({ ...e5, r: o3 });
s4 > r3 && (o3 = { x: o3.x - s4, y: o3.y, width: o3.width + s4, height: o3.height }, f2(o3), a3 = true), f2(wn({ rect: o3, bounds: i2 }));
const l3 = On({ ...e5, r: o3 });
l3 > r3 && (o3 = { x: o3.x, y: o3.y - l3, width: o3.width, height: o3.height + l3 }, f2(o3), a3 = true);
}
if (o3.width + tn >= l2.width && o3.height + tn >= l2.height) {
const e5 = o3.width * o3.height;
e5 > b2 && (y2 = Tn(o3), b2 = e5);
}
}
return y2;
}
function Ln(e3) {
const t2 = Math.max(e3.width, e3.height);
return [t2 / 8, t2 / 16, t2 / 32];
}
function zn(e3) {
const t2 = { minX: e3.point.x, minY: e3.point.y, maxX: e3.point.x, maxY: e3.point.y };
for (let n2 = 0;n2 < e3.layerCount; n2++) {
const o2 = e3.obstacleIndexByLayer[n2], i2 = !!o2 && o2.collides(t2), r2 = e3.placedIndexByLayer[n2], s2 = !!r2 && r2.collides(t2);
if (!i2 && !s2)
return false;
}
return true;
}
function Bn(e3) {
const { x: t2, y: n2, z: o2, layerCount: i2, minSpan: r2, maxSpan: s2, obstacleIndexByLayer: a2, additionalBlockersByLayer: c2 } = e3, l2 = (e4) => {
const o3 = { minX: t2, minY: n2, maxX: t2, maxY: n2 }, i3 = a2[e4];
if (i3 && i3.collides(o3))
return false;
return !(c2?.[e4] ?? []).some((e5) => {
return (i4 = { x: t2, y: n2 }).x >= (o4 = e5).x - tn && i4.x <= o4.x + o4.width + tn && i4.y >= o4.y - tn && i4.y <= o4.y + o4.height + tn;
var o4, i4;
});
};
let h2 = o2, d2 = o2;
for (;h2 - 1 >= 0 && l2(h2 - 1); )
h2--;
for (;d2 + 1 < i2 && l2(d2 + 1); )
d2++;
if (typeof s2 == "number") {
const e4 = ((e5, t3, n3) => Math.max(t3, Math.min(n3, e5)))(s2, 1, i2);
for (;d2 - h2 + 1 > e4; )
o2 - h2 > d2 - o2 ? h2++ : d2--;
}
const u2 = [];
for (let e4 = h2;e4 <= d2; e4++)
u2.push(e4);
return u2.length >= r2 ? u2 : [];
}
var Fn = (e3, t2 = 0.000001) => Math.round(e3 / t2) * t2;
var jn = (e3, t2 = 0.000001) => Math.round(e3 / t2) * t2;
var $n = (e3) => ("minX" in e3) ? { x: e3.minX, y: e3.minY, width: e3.maxX - e3.minX, height: e3.maxY - e3.minY } : e3;
function Yn(e3) {
const { lineStart: t2, lineEnd: n2, coveringIntervals: o2, minSegmentLength: i2 } = e3, r2 = jn(t2), s2 = jn(n2), a2 = o2.map((e4) => {
const t3 = jn(e4.start), n3 = jn(e4.end);
return { start: Math.min(t3, n3), end: Math.max(t3, n3) };
}).filter((e4) => e4.end > e4.start + tn);
if (a2.length === 0) {
return [{ start: r2, end: s2, center: (r2 + s2) / 2 }];
}
const c2 = [...a2].sort((e4, t3) => e4.start - t3.start), l2 = [];
let h2 = { ...c2[0] };
for (let e4 = 1;e4 < c2.length; e4++) {
const t3 = c2[e4];
t3.start <= h2.end + tn ? h2.end = Math.max(h2.end, t3.end) : (l2.push(h2), h2 = { ...t3 });
}
l2.push(h2);
const d2 = [];
if (l2[0].start > r2 + tn) {
const e4 = r2, t3 = l2[0].start;
t3 - e4 >= i2 && d2.push({ start: e4, end: t3, center: (e4 + t3) / 2 });
}
for (let e4 = 0;e4 < l2.length - 1; e4++) {
const t3 = l2[e4].end, n3 = l2[e4 + 1].start;
n3 - t3 >= i2 && d2.push({ start: t3, end: n3, center: (t3 + n3) / 2 });
}
if (l2[l2.length - 1].end < s2 - tn) {
const e4 = l2[l2.length - 1].end, t3 = s2;
t3 - e4 >= i2 && d2.push({ start: e4, end: t3, center: (e4 + t3) / 2 });
}
return d2;
}
function Xn(e3) {
const { bounds: t2, minSize: n2, layerCount: o2, obstacleIndexByLayer: i2, placedIndexByLayer: r2, hardPlacedByLayer: s2 } = e3, a2 = [], c2 = Math.max(0.15 * n2, 3 * tn), l2 = new Set, h2 = Array.from({ length: o2 }, (e4, t3) => [...i2[t3]?.all() ?? [], ...s2[t3] ?? []].map($n));
function d2(e4) {
const n3 = jn(e4.x), c3 = jn(e4.y), { z: d3 } = e4, u2 = n3, p2 = c3;
if (u2 < t2.x + tn || p2 < t2.y + tn || u2 > t2.x + t2.width - tn || p2 > t2.y + t2.height - tn)
return;
if (function(e5) {
return zn({ layerCount: o2, obstacleIndexByLayer: i2, placedIndexByLayer: r2, point: e5 });
}({ x: u2, y: p2 }))
return;
const m2 = h2[d3] ?? [];
let g2 = cn({ x: u2, y: p2 }, t2);
for (const e5 of m2)
g2 = Math.min(g2, cn({ x: u2, y: p2 }, e5));
const f2 = jn(g2), _2 = ((e5) => `${e5.z}|${e5.x.toFixed(6)}|${e5.y.toFixed(6)}`)({ x: u2, y: p2, z: d3 });
if (l2.has(_2))
return;
l2.add(_2);
const y2 = Bn({ x: u2, y: p2, z: d3, layerCount: o2, minSpan: 1, maxSpan: undefined, obstacleIndexByLayer: i2, additionalBlockersByLayer: s2 });
a2.push({ x: u2, y: p2, z: d3, distance: f2, zSpanLen: y2.length, isEdgeSeed: true });
}
for (let e4 = 0;e4 < o2; e4++) {
const o3 = (h2[e4] ?? []).map((e5) => ({ x: jn(e5.x), y: jn(e5.y), width: jn(e5.width), height: jn(e5.height) })), i3 = [{ x: t2.x + c2, y: t2.y + c2 }, { x: t2.x + t2.width - c2, y: t2.y + c2 }, { x: t2.x + c2, y: t2.y + t2.height - c2 }, { x: t2.x + t2.width - c2, y: t2.y + t2.height - c2 }];
for (const t3 of i3)
d2({ x: t3.x, y: t3.y, z: e4 });
const r3 = t2.y + c2, s3 = o3.filter((e5) => e5.y <= r3 && e5.y + e5.height >= r3).map((e5) => ({ start: Math.max(t2.x, e5.x), end: Math.min(t2.x + t2.width, e5.x + e5.width) })), a3 = Yn({ lineStart: t2.x + c2, lineEnd: t2.x + t2.width - c2, coveringIntervals: s3, minSegmentLength: 0.5 * n2 });
for (const t3 of a3) {
const o4 = t3.end - t3.start;
o4 >= n2 && (d2({ x: t3.center, y: r3, z: e4 }), o4 > 1.5 * n2 && (d2({ x: t3.start + 0.4 * n2, y: r3, z: e4 }), d2({ x: t3.end - 0.4 * n2, y: r3, z: e4 })));
}
const l3 = t2.y + t2.height - c2, u2 = o3.filter((e5) => e5.y <= l3 && e5.y + e5.height >= l3).map((e5) => ({ start: Math.max(t2.x, e5.x), end: Math.min(t2.x + t2.width, e5.x + e5.width) })), p2 = Yn({ lineStart: t2.x + c2, lineEnd: t2.x + t2.width - c2, coveringIntervals: u2, minSegmentLength: 0.5 * n2 });
for (const t3 of p2) {
const o4 = t3.end - t3.start;
o4 >= n2 && (d2({ x: t3.center, y: l3, z: e4 }), o4 > 1.5 * n2 && (d2({ x: t3.start + 0.4 * n2, y: l3, z: e4 }), d2({ x: t3.end - 0.4 * n2, y: l3, z: e4 })));
}
const m2 = t2.x + c2, g2 = o3.filter((e5) => e5.x <= m2 && e5.x + e5.width >= m2).map((e5) => ({ start: Math.max(t2.y, e5.y), end: Math.min(t2.y + t2.height, e5.y + e5.height) })), f2 = Yn({ lineStart: t2.y + c2, lineEnd: t2.y + t2.height - c2, coveringIntervals: g2, minSegmentLength: 0.5 * n2 });
for (const t3 of f2) {
const o4 = t3.end - t3.start;
o4 >= n2 && (d2({ x: m2, y: t3.center, z: e4 }), o4 > 1.5 * n2 && (d2({ x: m2, y: t3.start + 0.4 * n2, z: e4 }), d2({ x: m2, y: t3.end - 0.4 * n2, z: e4 })));
}
const _2 = t2.x + t2.width - c2, y2 = o3.filter((e5) => e5.x <= _2 && e5.x + e5.width >= _2).map((e5) => ({ start: Math.max(t2.y, e5.y), end: Math.min(t2.y + t2.height, e5.y + e5.height) })), b2 = Yn({ lineStart: t2.y + c2, lineEnd: t2.y + t2.height - c2, coveringIntervals: y2, minSegmentLength: 0.5 * n2 });
for (const t3 of b2) {
const o4 = t3.end - t3.start;
o4 >= n2 && (d2({ x: _2, y: t3.center, z: e4 }), o4 > 1.5 * n2 && (d2({ x: _2, y: t3.start + 0.4 * n2, z: e4 }), d2({ x: _2, y: t3.end - 0.4 * n2, z: e4 })));
}
for (const i4 of o3) {
const r4 = i4.x - c2;
if (r4 > t2.x + tn && r4 < t2.x + t2.width - tn) {
const t3 = o3.filter((e5) => e5 !== i4 && e5.x <= r4 && e5.x + e5.width >= r4).map((e5) => ({ start: Math.max(i4.y, e5.y), end: Math.min(i4.y + i4.height, e5.y + e5.height) })), s5 = Yn({ lineStart: i4.y, lineEnd: i4.y + i4.height, coveringIntervals: t3, minSegmentLength: 0.5 * n2 });
for (const t4 of s5)
d2({ x: r4, y: t4.center, z: e4 });
}
const s4 = i4.x + i4.width + c2;
if (s4 > t2.x + tn && s4 < t2.x + t2.width - tn) {
const t3 = o3.filter((e5) => e5 !== i4 && e5.x <= s4 && e5.x + e5.width >= s4).map((e5) => ({ start: Math.max(i4.y, e5.y), end: Math.min(i4.y + i4.height, e5.y + e5.height) })), r5 = Yn({ lineStart: i4.y, lineEnd: i4.y + i4.height, coveringIntervals: t3, minSegmentLength: 0.5 * n2 });
for (const t4 of r5)
d2({ x: s4, y: t4.center, z: e4 });
}
const a4 = i4.y - c2;
if (a4 > t2.y + tn && a4 < t2.y + t2.height - tn) {
const t3 = o3.filter((e5) => e5 !== i4 && e5.y <= a4 && e5.y + e5.height >= a4).map((e5) => ({ start: Math.max(i4.x, e5.x), end: Math.min(i4.x + i4.width, e5.x + e5.width) })), r5 = Yn({ lineStart: i4.x, lineEnd: i4.x + i4.width, coveringIntervals: t3, minSegmentLength: 0.5 * n2 });
for (const t4 of r5)
d2({ x: t4.center, y: a4, z: e4 });
}
const l4 = i4.y + i4.height + c2;
if (l4 > t2.y + tn && l4 < t2.y + t2.height - tn) {
const t3 = o3.filter((e5) => e5 !== i4 && e5.y <= l4 && e5.y + e5.height >= l4).map((e5) => ({ start: Math.max(i4.x, e5.x), end: Math.min(i4.x + i4.width, e5.x + e5.width) })), r5 = Yn({ lineStart: i4.x, lineEnd: i4.x + i4.width, coveringIntervals: t3, minSegmentLength: 0.5 * n2 });
for (const t4 of r5)
d2({ x: t4.center, y: l4, z: e4 });
}
}
}
return a2.sort((e4, t3) => t3.zSpanLen - e4.zSpanLen || t3.distance - e4.distance || e4.z - t3.z || e4.x - t3.x || e4.y - t3.y), a2;
}
function Wn(e3) {
const t2 = Array.from({ length: e3.layerCount }, () => []);
for (const n2 of e3.placed)
if (n2.zLayers.length >= e3.layerCount)
for (const e4 of n2.zLayers)
t2[e4].push(n2.rect);
return t2;
}
var Vn = (e3, t2) => ({ ...e3, minX: e3.x, minY: e3.y, maxX: e3.x + e3.width, maxY: e3.y + e3.height, zLayers: t2.zLayers });
function Hn(e3, t2) {
const n2 = e3.placed[t2], { rect: o2, zLayers: i2 } = n2, r2 = e3.layerCount, s2 = [], a2 = [];
for (let n3 = 0;n3 < e3.placed.length; n3++) {
if (n3 === t2)
continue;
const c3 = e3.placed[n3];
if (c3.zLayers.length >= r2)
continue;
const l2 = c3.zLayers.filter((e4) => i2.includes(e4));
if (l2.length === 0)
continue;
if (!an(c3.rect, o2))
continue;
const h2 = hn(c3.rect, o2);
s2.push(n3);
const d2 = c3.zLayers.filter((e4) => !i2.includes(e4));
d2.length > 0 && a2.push({ rect: c3.rect, zLayers: d2 });
const u2 = Math.min(e3.options.minSingle.width, e3.options.minMulti.width), p2 = Math.min(e3.options.minSingle.height, e3.options.minMulti.height);
for (const e4 of h2)
e4.width + tn >= u2 && e4.height + tn >= p2 && a2.push({ rect: e4, zLayers: l2.slice() });
}
const c2 = (e4, t3) => e4.minX === t3.minX && e4.minY === t3.minY && e4.maxX === t3.maxX && e4.maxY === t3.maxY;
s2.sort((e4, t3) => t3 - e4).forEach((t3) => {
const n3 = e3.placed.splice(t3, 1)[0];
if (e3.placedIndexByLayer)
for (const t4 of n3.zLayers) {
const o3 = e3.placedIndexByLayer[t4];
o3 && o3.remove(Vn(n3.rect, { zLayers: n3.zLayers }), c2);
}
});
for (const t3 of a2) {
e3.placed.push(t3);
for (const n3 of t3.zLayers)
if (e3.placedIndexByLayer) {
const o3 = e3.placedIndexByLayer[n3];
o3 && o3.insert(Vn(t3.rect, { zLayers: t3.zLayers.slice() }));
}
}
}
var Gn = class extends De {
constructor(e3) {
super(), this.input = e3;
}
input;
srj;
layerNames;
layerCount;
bounds;
options;
boardVoidRects;
gridIndex;
candidates;
placed;
placedIndexByLayer;
hardPlacedByLayer;
expansionIndex;
edgeAnalysisDone;
totalSeedsThisGrid;
consumedSeedsThisGrid;
_setup() {
const e3 = this.input.simpleRouteJson, t2 = this.input.gridOptions ?? {}, n2 = this.input.layerNames && this.input.zIndexByName, { layerNames: o2} = n2 ? { layerNames: this.input.layerNames, zIndexByName: this.input.zIndexByName } : Jt({ obstacles: e3.obstacles, layerCount: e3.layerCount }), r2 = Math.max(1, o2.length, e3.layerCount || 1), s2 = { x: e3.bounds.minX, y: e3.bounds.minY, width: e3.bounds.maxX - e3.bounds.minX, height: e3.bounds.maxY - e3.bounds.minY }, a2 = Math.max(0.01, e3.minTraceWidth || 0.15), c2 = { ...{ gridSizes: [], initialCellRatio: 0.2, maxAspectRatio: 3, minSingle: { width: 2 * a2, height: 2 * a2 }, minMulti: { width: 4 * a2, height: 4 * a2, minLayers: Math.min(2, Math.max(1, e3.layerCount || 1)) }, preferMultiLayer: true, maxMultiLayerSpan: undefined }, ...t2, gridSizes: t2.gridSizes ?? Ln(s2) };
this.srj = e3, this.layerNames = o2, this.layerCount = r2, this.bounds = s2, this.options = c2, this.boardVoidRects = this.input.boardVoidRects, this.gridIndex = 0, this.candidates = [], this.placed = [], this.placedIndexByLayer = Array.from({ length: r2 }, () => new tt), this.hardPlacedByLayer = Array.from({ length: r2 }, () => []), this.expansionIndex = 0, this.edgeAnalysisDone = false, 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: e3, initialCellRatio: t2, maxAspectRatio: n2, minSingle: o2, minMulti: i2, preferMultiLayer: r2, maxMultiLayerSpan: s2 } = this.options, a2 = e3[this.gridIndex];
if (this.candidates.length === 0 && this.consumedSeedsThisGrid === 0 && (this.candidates = function(e4) {
const { bounds: t3, gridSize: n3, layerCount: o3, obstacleIndexByLayer: i3, placedIndexByLayer: r3, hardPlacedByLayer: s3 } = e4, a3 = new Map, c3 = Array.from({ length: o3 }, (e5, t4) => [...i3[t4]?.all() ?? [], ...s3[t4] ?? []]);
for (let e5 = t3.x;e5 < t3.x + t3.width; e5 += n3)
for (let l4 = t3.y;l4 < t3.y + t3.height; l4 += n3) {
if (Math.abs(e5 - t3.x) < tn || Math.abs(l4 - t3.y) < tn || e5 > t3.x + t3.width - n3 - tn || l4 > t3.y + t3.height - n3 - tn)
continue;
if (zn({ layerCount: o3, obstacleIndexByLayer: i3, placedIndexByLayer: r3, point: { x: e5, y: l4 } }))
continue;
let h3 = [], d3 = 0;
for (let t4 = 0;t4 < o3; t4++) {
const n4 = Bn({ x: e5, y: l4, z: t4, layerCount: o3, minSpan: 1, maxSpan: undefined, obstacleIndexByLayer: i3, additionalBlockersByLayer: s3 });
n4.length > h3.length && (h3 = n4, d3 = t4);
}
const u2 = h3.length ? h3[Math.floor(h3.length / 2)] : d3, p2 = c3[u2] ?? [];
let m2 = cn({ x: e5, y: l4 }, t3);
for (const t4 of p2)
m2 = Math.min(m2, cn({ x: e5, y: l4 }, t4));
const g2 = Fn(m2), f2 = `${e5.toFixed(6)}|${l4.toFixed(6)}`, _2 = { x: e5, y: l4, z: u2, distance: g2, zSpanLen: h3.length }, y2 = a3.get(f2);
(!y2 || _2.zSpanLen > (y2.zSpanLen ?? 0) || _2.zSpanLen === y2.zSpanLen && _2.distance > y2.distance) && a3.set(f2, _2);
}
const l3 = Array.from(a3.values());
return l3.sort((e5, t4) => t4.zSpanLen - e5.zSpanLen || t4.distance - e5.distance || e5.z - t4.z || e5.x - t4.x || e5.y - t4.y), l3;
}({ bounds: this.bounds, gridSize: a2, 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 < e3.length)
return this.gridIndex += 1, this.candidates = [], this.totalSeedsThisGrid = 0, void (this.consumedSeedsThisGrid = 0);
if (!this.edgeAnalysisDone) {
const e4 = Math.min(o2.width, o2.height);
return this.candidates = Xn({ bounds: this.bounds, minSize: e4, layerCount: this.layerCount, obstacleIndexByLayer: this.input.obstacleIndexByLayer, placedIndexByLayer: this.placedIndexByLayer, hardPlacedByLayer: this.hardPlacedByLayer }), this.edgeAnalysisDone = true, this.totalSeedsThisGrid = this.candidates.length, void (this.consumedSeedsThisGrid = 0);
}
return this.candidates = [], this.solved = true, void (this.expansionIndex = 0);
}
const c2 = this.candidates[this.consumedSeedsThisGrid++];
if (zn({ layerCount: this.layerCount, obstacleIndexByLayer: this.input.obstacleIndexByLayer, placedIndexByLayer: this.placedIndexByLayer, point: { x: c2.x, y: c2.y } }))
return;
const l2 = Bn({ x: c2.x, y: c2.y, z: c2.z, layerCount: this.layerCount, minSpan: i2.minLayers, maxSpan: s2, obstacleIndexByLayer: this.input.obstacleIndexByLayer, additionalBlockersByLayer: this.hardPlacedByLayer }), h2 = [];
l2.length >= i2.minLayers && h2.push({ kind: "multi", layers: l2, minReq: { width: i2.width, height: i2.height } }), h2.push({ kind: "single", layers: [c2.z], minReq: { width: o2.width, height: o2.height } });
const d2 = r2 ? h2 : h2.reverse();
for (const e4 of d2) {
const o3 = Dn({ startX: c2.x, startY: c2.y, gridSize: a2, bounds: this.bounds, obsticalIndexByLayer: this.input.obstacleIndexByLayer, placedIndexByLayer: this.placedIndexByLayer, initialCellRatio: t2, maxAspectRatio: n2, minReq: e4.minReq, zLayers: e4.layers });
if (!o3)
continue;
const i3 = { rect: o3, zLayers: [...e4.layers] }, r3 = this.placed.push(i3) - 1;
for (const t3 of e4.layers) {
const e5 = this.placedIndexByLayer[t3];
e5 && e5.insert(Vn(o3, { zLayers: i3.zLayers }));
}
return Hn({ layerCount: this.layerCount, placed: this.placed, options: this.options, placedIndexByLayer: this.placedIndexByLayer }, r3), void (this.hardPlacedByLayer = Wn({ layerCount: this.layerCount, placed: this.placed }));
}
}
computeProgress() {
if (this.solved)
return 1;
const e3 = this.options.gridSizes.length, t2 = this.gridIndex / (e3 + 1), n2 = Math.max(1, this.totalSeedsThisGrid), o2 = n2 ? this.consumedSeedsThisGrid / n2 : 1;
return Math.min(0.999, t2 + o2 * (1 / (e3 + 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 e3 = [], t2 = [], n2 = [], o2 = this.srj ?? this.input.simpleRouteJson, i2 = o2.bounds.minX, r2 = o2.bounds.maxX, s2 = o2.bounds.minY, a2 = o2.bounds.maxY;
o2.outline && o2.outline.length > 1 ? n2.push({ points: [...o2.outline, o2.outline[0]], strokeColor: "#111827", strokeWidth: 0.01, label: "outline" }) : e3.push({ center: { x: (i2 + r2) / 2, y: (s2 + a2) / 2 }, width: r2 - i2, height: a2 - s2, fill: "none", stroke: "#111827", label: "board" });
for (const t3 of o2.obstacles ?? [])
t3.type !== "rect" && t3.type !== "oval" || e3.push({ center: { x: t3.center.x, y: t3.center.y }, width: t3.width, height: t3.height, fill: "#fee2e2", stroke: "#ef4444", layer: "obstacle", label: "obstacle" });
if (this.boardVoidRects) {
let t3 = null;
if (o2.outline && o2.outline.length > 0) {
const e4 = o2.outline.map((e5) => e5.x), n3 = o2.outline.map((e5) => e5.y), i3 = Math.min(...e4), r3 = Math.min(...n3);
t3 = { x: i3, y: r3, width: Math.max(...e4) - i3, height: Math.max(...n3) - r3 };
}
for (const n3 of this.boardVoidRects)
t3 && !an(n3, t3) || e3.push({ center: { x: n3.x + n3.width / 2, y: n3.y + n3.height / 2 }, width: n3.width, height: n3.height, fill: "rgba(0, 0, 0, 0.5)", stroke: "none", label: "void" });
}
if (this.candidates?.length)
for (const e4 of this.candidates)
t2.push({ x: e4.x, y: e4.y, label: `z:${e4.z}` });
if (this.placed?.length)
for (const t3 of this.placed) {
const n3 = en(t3.zLayers);
e3.push({ center: { x: t3.rect.x + t3.rect.width / 2, y: t3.rect.y + t3.rect.height / 2 }, width: t3.rect.width, height: t3.rect.height, fill: n3.fill, stroke: n3.stroke, layer: `z${t3.zLayers.join(",")}`, label: `free
z:${t3.zLayers.join(",")}` });
}
return { title: "RectDiff Grid", coordinateSystem: "cartesian", rects: e3, points: t2, lines: n2 };
}
};
var Un = (e3, t2) => e3.minX === t2.minX && e3.minY === t2.minY && e3.maxX === t2.maxX && e3.maxY === t2.maxY;
var Zn = class extends De {
constructor(e3) {
super(), this.input = e3;
}
input;
placedIndexByLayer = [];
_meshNodes = [];
_setup() {
this.stats = { gridIndex: this.input.gridIndex }, this.placedIndexByLayer = Array.from({ length: this.input.layerCount }, () => new tt);
for (const e3 of this.input.placed)
for (const t2 of e3.zLayers) {
const n2 = this.placedIndexByLayer[t2];
n2 && n2.insert(Vn(e3.rect, { zLayers: e3.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 e3 = this.input.expansionIndex, t2 = this.input.placed[e3], n2 = this.input.options.gridSizes[this.input.options.gridSizes.length - 1], o2 = t2.rect, i2 = Dn({ startX: t2.rect.x + t2.rect.width / 2, startY: t2.rect.y + t2.rect.height / 2, gridSize: n2, bounds: this.input.bounds, obsticalIndexByLayer: this.input.obstacleIndexByLayer, placedIndexByLayer: this.placedIndexByLayer, initialCellRatio: 0, maxAspectRatio: null, minReq: { width: t2.rect.width, height: t2.rect.height }, zLayers: t2.zLayers });
if (i2) {
this.input.placed[e3] = { rect: i2, zLayers: t2.zLayers };
for (const e4 of t2.zLayers) {
const n3 = this.placedIndexByLayer[e4];
n3 && (n3.remove(Vn(o2, { zLayers: t2.zLayers }), Un), n3.insert(Vn(i2, { zLayers: t2.zLayers })));
}
Hn({ layerCount: this.input.layerCount, placed: this.input.placed, options: this.input.options, placedIndexByLayer: this.placedIndexByLayer }, e3);
}
this.input.expansionIndex += 1;
}
finalizeIfNeeded() {
if (this.solved)
return;
const e3 = function(e4) {
const t2 = e4.placed.map((e5) => ({ minX: e5.rect.x, minY: e5.rect.y, maxX: e5.rect.x + e5.rect.width, maxY: e5.rect.y + e5.rect.height, zLayers: [...e5.zLayers].sort((e6, t3) => e6 - t3) }));
for (const n2 of e4.obstacles ?? []) {
const o2 = Kt(n2);
if (!o2)
continue;
const i2 = e4.obstacleClearance ? { x: o2.x - e4.obstacleClearance, y: o2.y - e4.obstacleClearance, width: o2.width + 2 * e4.obstacleClearance, height: o2.height + 2 * e4.obstacleClearance } : o2, r2 = n2.zLayers?.length && n2.zLayers.length > 0 ? n2.zLayers : Qt(n2, e4.zIndexByName);
t2.push({ minX: i2.x, minY: i2.y, maxX: i2.x + i2.width, maxY: i2.y + i2.height, zLayers: [...new Set(r2)].sort((e5, t3) => e5 - t3), isObstacle: true, connectedTo: [...n2.connectedTo] });
}
return t2;
}({ placed: this.input.placed, obstacles: this.input.obstacles, zIndexByName: this.input.zIndexByName, boardVoidRects: this.input.boardVoidRects, obstacleClearance: this.input.obstacleClearance });
this._meshNodes = function(e4) {
let t2 = 0;
const n2 = [];
for (const o2 of e4) {
const e5 = Math.max(0, o2.maxX - o2.minX), i2 = Math.max(0, o2.maxY - o2.minY);
e5 <= 0 || i2 <= 0 || o2.zLayers.length === 0 || n2.push({ capacityMeshNodeId: "cmn_" + t2++, center: { x: (o2.minX + o2.maxX) / 2, y: (o2.minY + o2.maxY) / 2 }, width: e5, height: i2, layer: "top", availableZ: o2.zLayers.slice(), _containsObstacle: o2.isObstacle, _containsTarget: o2.isObstacle, ...o2.connectedTo?.length ? { _connectedTo: [...o2.connectedTo] } : {} });
}
return n2;
}(e3), this.solved = true;
}
computeProgress() {
if (this.solved)
return 1;
const e3 = this.input.options.gridSizes.length, t2 = e3 / (e3 + 1), n2 = Math.max(1, this.input.placed.length), o2 = n2 ? this.input.expansionIndex / n2 : 1;
return Math.min(0.999, t2 + o2 * (1 / (e3 + 1)));
}
getOutput() {
if (this.solved)
return { meshNodes: this._meshNodes };
return { meshNodes: this.input.placed.map((e3, t2) => ({ capacityMeshNodeId: `expand-preview-${t2}`, center: { x: e3.rect.x + e3.rect.width / 2, y: e3.rect.y + e3.rect.height / 2 }, width: e3.rect.width, height: e3.rect.height, availableZ: e3.zLayers.slice(), layer: `z${e3.zLayers.join(",")}` })) };
}
visualize() {
const e3 = [];
for (const t2 of this.input.placed ?? [])
e3.push({ center: { x: t2.rect.x + t2.rect.width / 2, y: t2.rect.y + t2.rect.height / 2 }, width: t2.rect.width, height: t2.rect.height, stroke: "rgba(37, 99, 235, 0.9)", fill: "rgba(191, 219, 254, 0.5)", layer: `z${t2.zLayers.join(",")}`, label: `expanded
z:${t2.zLayers.join(",")}` });
return { title: "RectDiff Expansion", coordinateSystem: "cartesian", rects: e3, points: [], lines: [] };
}
};
var qn = class extends ze {
rectDiffSeedingSolver;
rectDiffExpansionSolver;
obstacleIndexByLayer;
layerNames;
zIndexByName;
constructor(e3) {
super(e3);
const { obstacleIndexByLayer: t2, layerNames: n2, zIndexByName: o2 } = ((e4) => {
const { srj: t3, boardVoidRects: n3, obstacleClearance: o3 } = e4, { layerNames: i2, zIndexByName: r2 } = Jt({ obstacles: t3.obstacles, layerCount: t3.layerCount }), s2 = Math.max(1, i2.length, t3.layerCount || 1), a2 = (t3.bounds.minX, t3.bounds.minY, t3.bounds.maxX, t3.bounds.minX, t3.bounds.maxY, t3.bounds.minY, Array.from({ length: s2 }, () => new tt)), c2 = (e5, t4) => {
const n4 = { ...e5, minX: e5.x, minY: e5.y, maxX: e5.x + e5.width, maxY: e5.y + e5.height, zLayers: [t4] };
a2[t4]?.insert(n4);
};
if (t3.outline && t3.outline.length > 2)
for (const e5 of n3 ?? [])
for (let t4 = 0;t4 < s2; t4++)
c2(e5, t4);
for (const e5 of t3.obstacles ?? []) {
const t4 = Kt(e5);
if (!t4)
continue;
const n4 = dn(t4, o3 ?? 0), i3 = Qt(e5, r2), a3 = i3.filter((e6) => e6 < 0 || e6 >= s2);
if (a3.length)
throw new Error(`RectDiff: obstacle uses z-layer indices ${a3.join(",")} outside 0-${s2 - 1}`);
e5.zLayers && e5.zLayers.length !== 0 || !i3.length || (e5.zLayers = i3);
for (const e6 of i3)
c2(n4, e6);
}
return { obstacleIndexByLayer: a2, layerNames: i2, zIndexByName: r2 };
})({ srj: { bounds: e3.bounds, obstacles: e3.obstacles, connections: e3.connections, outline: e3.outline?.outline, layerCount: e3.layerCount, minTraceWidth: e3.minTraceWidth }, boardVoidRects: e3.boardVoidRects, obstacleClearance: e3.obstacleClearance });
this.obstacleIndexByLayer = t2, this.layerNames = e3.layerNames ?? n2, this.zIndexByName = e3.zIndexByName ?? o2;
}
pipelineDef = [Le("rectDiffSeedingSolver", Gn, (e3) => [{ simpleRouteJson: { bounds: e3.inputProblem.bounds, obstacles: e3.inputProblem.obstacles, connections: e3.inputProblem.connections, outline: e3.inputProblem.outline?.outline, layerCount: e3.inputProblem.layerCount, minTraceWidth: e3.inputProblem.minTraceWidth }, gridOptions: e3.inputProblem.gridOptions, obstacleIndexByLayer: e3.obstacleIndexByLayer, boardVoidRects: e3.inputProblem.boardVoidRects, layerNames: e3.layerNames, zIndexByName: e3.zIndexByName, obstacleClearance: e3.inputProblem.obstacleClearance }]), Le("rectDiffExpansionSolver", Zn, (e3) => {
const t2 = e3.rectDiffSeedingSolver?.getOutput();
if (!t2)
throw new Error("RectDiffSeedingSolver did not produce output");
return [{ layerNames: t2.layerNames ?? [], boardVoidRects: e3.inputProblem.boardVoidRects ?? [], layerCount: e3.inputProblem.layerCount, bounds: t2.bounds, candidates: t2.candidates, consumedSeedsThisGrid: t2.placed.length, totalSeedsThisGrid: t2.candidates.length, placed: t2.placed, edgeAnalysisDone: t2.edgeAnalysisDone, gridIndex: t2.gridIndex, expansionIndex: t2.expansionIndex, obstacleIndexByLayer: e3.obstacleIndexByLayer, options: t2.options, zIndexByName: e3.zIndexByName, layerNamesCanonical: e3.layerNames, obstacles: e3.inputProblem.obstacles, obstacleClearance: e3.inputProblem.obstacleClearance }];
})];
getConstructorParams() {
return [this.inputProblem];
}
getOutput() {
if (this.rectDiffExpansionSolver)
return this.rectDiffExpansionSolver.getOutput();
if (this.rectDiffSeedingSolver) {
return { meshNodes: this.rectDiffSeedingSolver.getOutput().placed.map((e3, t2) => ({ capacityMeshNodeId: `grid-${t2}`, center: { x: e3.rect.x + e3.rect.width / 2, y: e3.rect.y + e3.rect.height / 2 }, width: e3.rect.width, height: e3.rect.height, availableZ: e3.zLayers, layer: `z${e3.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 Jn = (e3) => {
const { srj: t2, clearance: n2 } = e3, o2 = n2 ?? 0;
if (o2 <= 0)
return { title: "Obstacle Clearance", coordinateSystem: "cartesian", rects: [] };
const i2 = [];
for (const e4 of t2.obstacles ?? []) {
if (e4.type !== "rect" && e4.type !== "oval")
continue;
const t3 = { x: e4.center.x - e4.width / 2 - o2, y: e4.center.y - e4.height / 2 - o2, width: e4.width + 2 * o2, height: e4.height + 2 * o2 };
i2.push({ center: { x: t3.x + t3.width / 2, y: t3.y + t3.height / 2 }, width: t3.width, height: t3.height, stroke: "rgba(202, 138, 4, 0.9)", fill: "rgba(234, 179, 8, 0.15)", layer: "obstacle-clearance", label: `clearance
z:${(e4.zLayers ?? []).join(",") || "all"}` });
}
return { title: "Obstacle Clearance", coordinateSystem: "cartesian", rects: i2 };
};
function Qn(e3, t2, n2 = {}) {
if (!t2 || t2.length < 3)
return [];
const o2 = t2.length > 120, i2 = o2 ? function(e4, t3) {
const n3 = (e5) => Math.round(e5 / t3) * t3, o3 = new Set, i3 = [];
for (const t4 of e4) {
const e5 = n3(t4.x), r3 = n3(t4.y), s3 = `${e5},${r3}`;
o3.has(s3) || (o3.add(s3), i3.push({ x: e5, y: r3 }));
}
return i3;
}(t2, Math.max(e3.width, e3.height) / 120) : t2, r2 = new Set([e3.x, e3.x + e3.width]), s2 = new Set([e3.y, e3.y + e3.height]);
for (const e4 of i2)
r2.add(e4.x), s2.add(e4.y);
(function({ polygon: e4, xs: t3, ys: n3, minGridSize: o3 }) {
const i3 = [];
let r3 = 0;
for (let t4 = 0;t4 < e4.length; t4++) {
const n4 = e4[t4], o4 = e4[(t4 + 1) % e4.length], s4 = Math.abs(o4.x - n4.x), a3 = Math.abs(o4.y - n4.y);
if (s4 <= tn || a3 <= tn)
continue;
const c3 = Math.max(s4, a3);
i3.push({ start: n4, end: o4, span: c3 }), r3 += c3;
}
if (i3.length === 0)
return;
const s3 = Math.max(o3, r3 / 256);
for (const { start: e5, end: o4, span: r4 } of i3) {
const i4 = Math.max(1, Math.ceil(r4 / s3));
for (let r5 = 1;r5 < i4; r5++) {
const s4 = r5 / i4;
t3.add(e5.x + (o4.x - e5.x) * s4), n3.add(e5.y + (o4.y - e5.y) * s4);
}
}
})({ polygon: i2, xs: r2, ys: s2, minGridSize: Math.max(tn, n2.minGridSize ?? Math.max(e3.width, e3.height) / 256) });
const a2 = Array.from(r2).sort((e4, t3) => e4 - t3), c2 = Array.from(s2).sort((e4, t3) => e4 - t3), l2 = [];
for (let n3 = 0;n3 < a2.length - 1; n3++)
for (let i3 = 0;i3 < c2.length - 1; i3++) {
const r3 = a2[n3], s3 = a2[n3 + 1], h3 = c2[i3], d3 = c2[i3 + 1], u3 = (r3 + s3) / 2, p2 = (h3 + d3) / 2;
if (u3 >= e3.x && u3 <= e3.x + e3.width && p2 >= e3.y && p2 <= e3.y + e3.height) {
(o2 ? [{ x: u3, y: p2 }] : [{ x: u3, y: p2 }, { x: r3, y: h3 }, { x: s3, y: h3 }, { x: r3, y: d3 }, { x: s3, y: d3 }]).every((e4) => Nt(e4, t2)) || l2.push({ x: r3, y: h3, width: s3 - r3, height: d3 - h3 });
}
}
const h2 = [];
l2.sort((e4, t3) => Math.abs(e4.y - t3.y) > tn ? e4.y - t3.y : e4.x - t3.x);
let d2 = null;
for (const e4 of l2) {
if (!d2) {
d2 = e4;
continue;
}
const t3 = Math.abs(d2.y - e4.y) < tn, n3 = Math.abs(d2.height - e4.height) < tn, o3 = Math.abs(d2.x + d2.width - e4.x) < tn;
t3 && n3 && o3 ? d2.width += e4.width : (h2.push(d2), d2 = e4);
}
d2 && h2.push(d2), h2.sort((e4, t3) => Math.abs(e4.x - t3.x) > tn ? e4.x - t3.x : e4.y - t3.y);
const u2 = [];
d2 = null;
for (const e4 of h2) {
if (!d2) {
d2 = e4;
continue;
}
const t3 = Math.abs(d2.x - e4.x) < tn, n3 = Math.abs(d2.width - e4.width) < tn, o3 = Math.abs(d2.y + d2.height - e4.y) < tn;
t3 && n3 && o3 ? d2.height += e4.height : (u2.push(d2), d2 = e4);
}
return d2 && u2.push(d2), u2;
}
var Kn = class extends ze {
rectDiffGridSolverPipeline;
gapFillSolver;
outerLayerContainmentMergeSolver;
boardVoidRects;
zIndexByName;
layerNames;
pipelineDef = [Le("rectDiffGridSolverPipeline", qn, (e3) => [{ bounds: e3.inputProblem.simpleRouteJson.bounds, obstacles: e3.inputProblem.simpleRouteJson.obstacles, connections: e3.inputProblem.simpleRouteJson.connections, outline: e3.inputProblem.simpleRouteJson.outline ? { outline: e3.inputProblem.simpleRouteJson.outline } : undefined, layerCount: e3.inputProblem.simpleRouteJson.layerCount, gridOptions: e3.inputProblem.gridOptions, boardVoidRects: e3.boardVoidRects, layerNames: e3.layerNames, zIndexByName: e3.zIndexByName, minTraceWidth: e3.inputProblem.simpleRouteJson.minTraceWidth, obstacleClearance: e3.inputProblem.obstacleClearance }]), Le("gapFillSolver", Zt, (e3) => [{ meshNodes: e3.rectDiffGridSolverPipeline?.getOutput().meshNodes ?? [], bounds: e3.inputProblem.simpleRouteJson.bounds, boardVoid: { boardVoidRects: e3.boardVoidRects || [], layerCount: e3.inputProblem.simpleRouteJson.layerCount || 0 }, maxGapFillPasses: e3.inputProblem.maxGapFillPasses }]), Le("outerLayerContainmentMergeSolver", vn, (e3) => [{ meshNodes: e3.gapFillSolver?.getOutput().outputNodes ?? e3.rectDiffGridSolverPipeline?.getOutput().meshNodes ?? [], simpleRouteJson: e3.inputProblem.simpleRouteJson, zIndexByName: e3.zIndexByName ?? new Map, obstacleClearance: e3.inputProblem.obstacleClearance }])];
_setup() {
const { zIndexByName: e3, layerNames: t2 } = Jt({ obstacles: this.inputProblem.simpleRouteJson.obstacles, layerCount: this.inputProblem.simpleRouteJson.layerCount });
if (this.zIndexByName = e3, this.layerNames = t2, this.inputProblem.simpleRouteJson.outline) {
const e4 = Math.max(0, this.inputProblem.simpleRouteJson.minBoardEdgeClearance ?? 0);
this.boardVoidRects = Qn({ x: this.inputProblem.simpleRouteJson.bounds.minX - e4, y: this.inputProblem.simpleRouteJson.bounds.minY - e4, width: this.inputProblem.simpleRouteJson.bounds.maxX - this.inputProblem.simpleRouteJson.bounds.minX + 2 * e4, height: this.inputProblem.simpleRouteJson.bounds.maxY - this.inputProblem.simpleRouteJson.bounds.minY + 2 * e4 }, this.inputProblem.simpleRouteJson.outline ?? [], { minGridSize: this.inputProblem.simpleRouteJson.minTraceWidth }).map((t3) => dn(t3, e4));
}
}
getConstructorParams() {
return [this.inputProblem];
}
getOutput() {
const e3 = this.outerLayerContainmentMergeSolver?.getOutput();
if (e3)
return { meshNodes: e3.outputNodes };
const t2 = this.gapFillSolver?.getOutput();
return t2 ? { meshNodes: t2.outputNodes } : this.rectDiffGridSolverPipeline ? this.rectDiffGridSolverPipeline.getOutput() : { meshNodes: [] };
}
initialVisualize() {
const e3 = function(e4, t3 = "RectDiff") {
const n3 = [], o2 = [], i2 = e4.bounds.minX, r2 = e4.bounds.maxX, s2 = e4.bounds.minY, a2 = e4.bounds.maxY;
e4.outline && e4.outline.length > 1 ? o2.push({ points: [...e4.outline, e4.outline[0]], strokeColor: "#111827", strokeWidth: 0.01, label: "outline" }) : n3.push({ center: { x: (i2 + r2) / 2, y: (s2 + a2) / 2 }, width: r2 - i2, height: a2 - s2, fill: "none", stroke: "#111827", label: "board" });
for (const t4 of e4.obstacles ?? [])
if (t4.type === "rect" || t4.type === "oval") {
const e5 = (t4.zLayers ?? []).join(",") || "all";
n3.push({ center: { x: t4.center.x, y: t4.center.y }, width: t4.width, height: t4.height, fill: "#fee2e2", stroke: "#ef4444", layer: "obstacle", label: `obstacle
z:${e5}` });
}
return { title: t3, coordinateSystem: "cartesian", rects: n3, points: [], lines: o2 };
}(this.inputProblem.simpleRouteJson, "RectDiffPipeline - Initial"), t2 = Jn({ srj: this.inputProblem.simpleRouteJson, clearance: this.inputProblem.obstacleClearance }), n2 = { rects: (this.rectDiffGridSolverPipeline?.getOutput().meshNodes ?? []).map((e4) => ({ center: e4.center, width: e4.width, height: e4.height, stroke: "rgba(0, 0, 0, 0.3)", fill: "rgba(100, 100, 100, 0.1)", layer: `z${e4.availableZ.join(",")}`, label: [`node ${e4.capacityMeshNodeId}`, `z:${e4.availableZ.join(",")}`].join(`
`) })) };
return Oe(Oe(e3, t2), n2);
}
finalVisualize() {
return (({ srj: e3, meshNodes: t2, obstacleClearance: n2 }) => {
const o2 = (({ srj: e4 }) => ({ title: "SimpleRoute Outline", coordinateSystem: "cartesian", lines: e4.outline && e4.outline.length > 1 ? [{ points: [...e4.outline, e4.outline[0]], strokeColor: "#111827", strokeWidth: 0.1, label: "outline" }] : [{ points: [{ x: e4.bounds.minX, y: e4.bounds.minY }, { x: e4.bounds.maxX, y: e4.bounds.minY }, { x: e4.bounds.maxX, y: e4.bounds.maxY }, { x: e4.bounds.minX, y: e4.bounds.maxY }, { x: e4.bounds.minX, y: e4.bounds.minY }], strokeColor: "#111827", strokeWidth: 0.1, label: "bounds" }] }))({ srj: e3 }), i2 = Jn({ srj: e3, clearance: n2 }), r2 = t2.map((e4) => ({ center: e4.center, width: e4.width, height: e4.height, stroke: en(e4.availableZ).stroke, fill: e4._containsObstacle ? "#fca5a5" : en(e4.availableZ).fill, layer: `z${e4.availableZ.join(",")}`, label: `node ${e4.capacityMeshNodeId}
z:${e4.availableZ.join(",")}` }));
return Oe(Oe({ title: "RectDiffPipeline - Final", coordinateSystem: "cartesian", rects: r2, lines: [], points: [], texts: [] }, o2), i2);
})({ srj: this.inputProblem.simpleRouteJson, meshNodes: this.getOutput().meshNodes, obstacleClearance: this.inputProblem.obstacleClearance });
}
};
var eo = class {
cacheHitsByPrefix = {};
cacheMissesByPrefix = {};
isSyncCache = true;
cacheHits = 0;
cacheMisses = 0;
cache = new Map;
getCachedSolutionSync(e3) {
const t2 = this.cache.get(e3);
if (t2 !== undefined) {
this.cacheHits++;
const n2 = e3.split(":")[0];
return this.cacheHitsByPrefix[n2] = (this.cacheHitsByPrefix[n2] || 0) + 1, structuredClone(t2);
}
{
this.cacheMisses++;
const t3 = e3.split(":")[0];
return void (this.cacheMissesByPrefix[t3] = (this.cacheMissesByPrefix[t3] || 0) + 1);
}
}
async getCachedSolution(e3) {
return this.getCachedSolutionSync(e3);
}
setCachedSolutionSync(e3, t2) {
this.cache.set(e3, structuredClone(t2));
}
async setCachedSolution(e3, t2) {
this.setCachedSolutionSync(e3, t2);
}
clearCache() {
this.cache.clear(), this.cacheHits = 0, this.cacheMisses = 0, this.cacheHitsByPrefix = {}, this.cacheMissesByPrefix = {};
}
getAllCacheKeys() {
return Array.from(this.cache.keys());
}
};
var to = "tscircuit_autorouter_cache_";
var no = class {
isSyncCache = true;
cacheHits = 0;
cacheMisses = 0;
cacheHitsByPrefix = {};
cacheMissesByPrefix = {};
constructor() {}
getKey(e3) {
return `${to}${e3}`;
}
getCachedSolutionSync(e3) {
if (typeof localStorage == "undefined")
return;
const t2 = this.getKey(e3);
try {
const n2 = localStorage.getItem(t2);
if (n2 !== null) {
const t3 = JSON.parse(n2);
this.cacheHits++;
const o2 = e3.split(":")[0];
return this.cacheHitsByPrefix[o2] = (this.cacheHitsByPrefix[o2] || 0) + 1, t3;
}
{
this.cacheMisses++;
const t3 = e3.split(":")[0];
return void (this.cacheMissesByPrefix[t3] = (this.cacheMissesByPrefix[t3] || 0) + 1);
}
} catch (n2) {
console.error(`Error getting cached solution sync for ${t2}:`, n2), this.cacheMisses++;
const o2 = e3.split(":")[0];
return void (this.cacheMissesByPrefix[o2] = (this.cacheMissesByPrefix[o2] || 0) + 1);
}
}
async getCachedSolution(e3) {
return this.getCachedSolutionSync(e3);
}
setCachedSolutionSync(e3, t2) {
if (typeof localStorage == "undefined")
return;
const n2 = this.getKey(e3);
try {
const e4 = JSON.stringify(t2);
localStorage.setItem(n2, e4);
} catch (e4) {
console.error(`Error setting cached solution sync for ${n2}:`, e4), e4 instanceof DOMException && (e4.name === "QuotaExceededError" || e4.name === "NS_ERROR_DOM_QUOTA_REACHED") && console.warn(`LocalStorage quota exceeded. Failed to cache solution for ${n2}. Consider clearing the cache.`);
}
}
async setCachedSolution(e3, t2) {
this.setCachedSolutionSync(e3, t2);
}
clearCache() {
if (typeof localStorage != "undefined")
try {
const e3 = [];
for (let t2 = 0;t2 < localStorage.length; t2++) {
const n2 = localStorage.key(t2);
n2?.startsWith(to) && e3.push(n2);
}
e3.forEach((e4) => localStorage.removeItem(e4)), console.log(`Cleared ${e3.length} items from LocalStorage cache.`);
} catch (e3) {
console.error("Error clearing LocalStorage cache:", e3);
} finally {
this.cacheHits = 0, this.cacheMisses = 0, this.cacheHitsByPrefix = {}, this.cacheMissesByPrefix = {};
}
}
getAllCacheKeys() {
const e3 = [];
for (let t2 = 0;t2 < 1e4; t2++) {
const n2 = localStorage.key(t2);
if (!n2)
break;
n2.includes(to) && e3.push(n2);
}
return e3;
}
};
function io() {
return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE || ro(), globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE;
}
function ro() {
globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE ??= new no, globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE ??= new eo;
}
function so(e3) {
const t2 = { minX: e3.center.x - e3.width / 2, maxX: e3.center.x + e3.width / 2, minY: e3.center.y - e3.height / 2, maxY: e3.center.y + e3.height / 2 };
for (const n2 of e3.portPoints)
n2.x < t2.minX && (t2.minX = n2.x), n2.x > t2.maxX && (t2.maxX = n2.x), n2.y < t2.minY && (t2.minY = n2.y), n2.y > t2.maxY && (t2.maxY = n2.y);
return t2;
}
var ao = (e3, t2) => e3 <= t2 ? [e3, t2] : [t2, e3];
var co = (e3) => `${e3[0]}|${e3[1]}`;
var lo = ({ portPointId: e3, currentNodeId: t2, inputNodes: n2, connectionNodeIdsByPortPointId: o2 }) => {
let i2 = e3 ? o2?.get(e3) : undefined;
if (e3 && !o2)
for (const t3 of n2) {
const n3 = t3.portPoints.find((t4) => t4.portPointId === e3);
if (n3?.connectionNodeIds) {
i2 = n3.connectionNodeIds;
break;
}
}
if (!i2 || i2.length !== 2)
return [t2, t2];
const [r2, s2] = i2;
return r2 && s2 ? ao(r2, s2) : [t2, t2];
};
var ho = 0.000001;
var uo = (e3, t2) => Math.abs(e3 - t2) <= ho;
var po = ({ nodeAId: e3, nodeBId: t2, nodeBounds: n2 }) => {
if (e3 === t2)
return null;
const o2 = n2.get(e3), i2 = n2.get(t2);
if (!o2 || !i2)
return null;
const r2 = ao(e3, t2), s2 = co(r2);
if (uo(o2.maxX, i2.minX) || uo(i2.maxX, o2.minX)) {
const n3 = Math.max(o2.minY, i2.minY), a2 = Math.min(o2.maxY, i2.maxY), c2 = a2 - n3;
if (c2 > ho) {
const l2 = uo(o2.maxX, i2.minX) ? o2.maxX : o2.minX;
return { ownerNodeIds: r2, ownerPairKey: s2, orientation: "vertical", x1: l2, y1: n3, x2: l2, y2: a2, center: { x: l2, y: (n3 + a2) / 2 }, length: c2, nodeSideByOwnerId: uo(o2.maxX, i2.minX) ? { [e3]: "right", [t2]: "left" } : { [e3]: "left", [t2]: "right" } };
}
}
if (uo(o2.maxY, i2.minY) || uo(i2.maxY, o2.minY)) {
const n3 = Math.max(o2.minX, i2.minX), a2 = Math.min(o2.maxX, i2.maxX), c2 = a2 - n3;
if (c2 > ho) {
const l2 = uo(o2.maxY, i2.minY) ? o2.maxY : o2.minY;
return { ownerNodeIds: r2, ownerPairKey: s2, orientation: "horizontal", x1: n3, y1: l2, x2: a2, y2: l2, center: { x: (n3 + a2) / 2, y: l2 }, length: c2, nodeSideByOwnerId: uo(o2.maxY, i2.minY) ? { [e3]: "top", [t2]: "bottom" } : { [e3]: "bottom", [t2]: "top" } };
}
}
return null;
};
var mo = ({ portPoint: e3, ownerNodeIds: t2, inputNodes: n2 }) => {
for (const o2 of t2) {
const t3 = n2.find((e4) => e4.capacityMeshNodeId === o2);
if (t3?._containsTarget)
return true;
const i2 = t3?.portPoints.find((t4) => t4.portPointId === e3.portPointId);
if (i2?.connectionNodeIds?.some((e4) => n2.find((t4) => t4.capacityMeshNodeId === e4)?._containsTarget))
return true;
}
return false;
};
var go = (e3, t2) => e3 === "top" ? 0 : e3 === "bottom" ? t2 - 1 : parseInt(e3.slice(5));
function fo(e3, t2) {
return [...new Set(e3)].filter((e4) => Number.isInteger(e4) && e4 >= 0 && e4 < t2).sort((e4, t3) => e4 - t3);
}
function _o(e3, t2) {
return fo(e3.map((e4) => go(e4, t2)), t2);
}
var yo = 0.000001;
var bo = ({ sharedEdge: e3, obstacles: t2, z: n2, layerCount: o2 }) => {
for (const i2 of t2) {
const t3 = i2.zLayers ?? (o2 === undefined ? undefined : i2.layers.map((e4) => go(e4, o2)));
if (n2 !== undefined && t3 && !t3.includes(n2))
continue;
const r2 = i2.center.x - i2.width / 2, s2 = i2.center.x + i2.width / 2, a2 = i2.center.y - i2.height / 2, c2 = i2.center.y + i2.height / 2;
if (e3.orientation !== "vertical") {
if (Math.abs(e3.y1 - a2) < yo || Math.abs(e3.y1 - c2) < yo) {
const t4 = Math.max(e3.x1, r2);
if (Math.min(e3.x2, s2) - t4 > yo)
return true;
}
} else if (Math.abs(e3.x1 - r2) < yo || Math.abs(e3.x1 - s2) < yo) {
const t4 = Math.max(e3.y1, a2);
if (Math.min(e3.y2, c2) - t4 > yo)
return true;
}
}
return false;
};
var xo = class extends De {
constructor(e3) {
super(), this.input = e3;
for (const t3 of e3.nodeWithPortPoints)
this.mapOfNodeIdToBounds.set(t3.capacityMeshNodeId, e3.useLayerAwareGeometry ? { minX: t3.center.x - t3.width / 2, maxX: t3.center.x + t3.width / 2, minY: t3.center.y - t3.height / 2, maxY: t3.center.y + t3.height / 2 } : so(t3));
const t2 = new Map, n2 = ((e4) => {
const t3 = new Map;
for (const n3 of e4) {
const e5 = new Set;
for (const o2 of n3.portPoints) {
const n4 = o2.portPointId;
n4 && !e5.has(n4) && (e5.add(n4), !t3.has(n4) && o2.connectionNodeIds && t3.set(n4, o2.connectionNodeIds));
}
}
return t3;
})(e3.inputNodesWithPortPoints);
for (const o2 of e3.nodeWithPortPoints)
for (const i2 of o2.portPoints) {
if (!i2.portPointId)
continue;
const r2 = lo({ portPointId: i2.portPointId, currentNodeId: o2.capacityMeshNodeId, inputNodes: e3.inputNodesWithPortPoints, connectionNodeIdsByPortPointId: n2 }), s2 = co(r2), a2 = this.mapOfOwnerPairToPortPoints.get(s2) ?? [];
a2.some((e4) => e4.portPointId && e4.portPointId === i2.portPointId) || a2.push({ ...i2, ownerNodeIds: r2, ownerPairKey: s2 }), this.mapOfOwnerPairToPortPoints.set(s2, a2), t2.set(s2, r2);
}
this.mapOfOwnerPairToSharedEdge = (({ ownerPairs: e4, nodeBounds: t3 }) => {
const n3 = new Map;
for (const o2 of e4) {
const [e5, i2] = o2;
if (e5 === i2)
continue;
const r2 = po({ nodeAId: e5, nodeBId: i2, nodeBounds: t3 });
r2 && n3.set(co(o2), r2);
}
return n3;
})({ ownerPairs: Array.from(t2.values()), nodeBounds: this.mapOfNodeIdToBounds }), this.ownerPairsToProcess = Array.from(this.mapOfOwnerPairToSharedEdge.keys()), this.ownerPairsToProcess.sort((e4, t3) => {
const n3 = this.mapOfOwnerPairToSharedEdge.get(e4), o2 = this.mapOfOwnerPairToSharedEdge.get(t3);
return n3.center.x - o2.center.x || n3.center.y - o2.center.y;
});
}
input;
getSolverName() {
return "UniformPortDistributionSolver";
}
mapOfNodeIdToBounds = new Map;
mapOfOwnerPairToPortPoints = new Map;
mapOfOwnerPairToSharedEdge = new Map;
ownerPairsToProcess = [];
currentOwnerPairBeingProcessed = null;
redistributedNodes = [];
step() {
if (this.ownerPairsToProcess.length === 0)
return this.rebuildNodes(), void (this.solved = true);
this.currentOwnerPairBeingProcessed = this.ownerPairsToProcess.shift();
const e3 = this.currentOwnerPairBeingProcessed, t2 = this.mapOfOwnerPairToSharedEdge.get(e3);
if (!t2)
return;
const n2 = this.mapOfOwnerPairToPortPoints.get(e3) ?? [], o2 = bo({ sharedEdge: t2, obstacles: this.input.obstacles });
if (!this.input.useLayerAwareGeometry && o2)
return;
const i2 = new Map;
for (const e4 of n2)
i2.set(e4.z, (i2.get(e4.z) ?? 0) + 1);
const r2 = [];
for (const e4 of n2)
this.input.preserveSolitaryPorts && o2 && i2.get(e4.z) === 1 || bo({ sharedEdge: t2, obstacles: this.input.obstacles, z: this.input.useLayerAwareGeometry ? e4.z : undefined, layerCount: this.input.layerCount }) || mo({ portPoint: e4, ownerNodeIds: e4.ownerNodeIds, inputNodes: this.input.inputNodesWithPortPoints }) || r2.push(e4);
const s2 = (({ sharedEdge: e4, portPoints: t3 }) => {
if (t3.length === 0)
return [];
const n3 = new Map;
for (const e5 of t3) {
const t4 = e5.z ?? 0, o4 = n3.get(t4) ?? [];
o4.push(e5), n3.set(t4, o4);
}
const o3 = [], i3 = Array.from(n3.keys()).sort((e5, t4) => e5 - t4);
for (const t4 of i3) {
const i4 = n3.get(t4), r3 = i4.length;
i4.sort((t5, n4) => e4.orientation === "horizontal" ? t5.x - n4.x : t5.y - n4.y);
for (let t5 = 0;t5 < r3; t5++) {
const n4 = (2 * t5 + 1) / (2 * r3), s3 = e4.orientation === "horizontal" ? e4.x1 + e4.length * n4 : e4.x1, a2 = e4.orientation === "horizontal" ? e4.y1 : e4.y1 + e4.length * n4;
o3.push({ ...i4[t5], x: s3, y: a2 });
}
}
return o3;
})({ sharedEdge: t2, portPoints: r2 });
this.mapOfOwnerPairToPortPoints.set(e3, s2);
}
rebuildNodes() {
const e3 = new Map;
for (const t3 of this.mapOfOwnerPairToPortPoints.values())
for (const n2 of t3)
n2.portPointId && e3.set(n2.portPointId, { x: n2.x, y: n2.y });
const t2 = (t3) => {
if (t3.portPointId && e3.has(t3.portPointId)) {
const n2 = e3.get(t3.portPointId);
return { ...t3, x: n2.x, y: n2.y };
}
return t3;
};
this.redistributedNodes = this.input.nodeWithPortPoints.map((e4) => ({ ...e4, portPoints: e4.portPoints.map(t2), portPointsInPairs: e4.portPointsInPairs?.map(([e5, n2]) => [t2(e5), t2(n2)]) }));
}
getOutput = () => this.redistributedNodes;
visualize() {
return (({ obstacles: e3, nodeWithPortPoints: t2, mapOfOwnerPairToPortPoints: n2, mapOfOwnerPairToSharedEdge: o2, ownerPairsToProcess: i2, currentOwnerPairBeingProcessed: r2, mapOfNodeIdToBounds: s2 }) => {
const a2 = e3.filter((e4) => !e4.isCopperPour).map((e4) => ({ ...e4, fill: "#ec000070" })), c2 = [], l2 = [], h2 = new Map, d2 = new Map, u2 = new Map, p2 = (e4) => e4.portPointId ? h2.get(e4.portPointId) ?? { x: e4.x, y: e4.y } : { x: e4.x, y: e4.y };
for (const e4 of t2)
for (const t3 of e4.portPoints)
t3.portPointId && (h2.set(t3.portPointId, { x: t3.x, y: t3.y }), d2.set(t3.portPointId, t3.z ?? 0));
for (const e4 of n2.values())
for (const t3 of e4)
t3.portPointId && (h2.set(t3.portPointId, { x: t3.x, y: t3.y }), d2.set(t3.portPointId, t3.z ?? 0), u2.set(t3.portPointId, `${t3.ownerNodeIds[0]}&${t3.ownerNodeIds[1]}`));
t2.forEach((e4) => {
const t3 = s2.get(e4.capacityMeshNodeId);
if (t3) {
const n3 = (t3.minX + t3.maxX) / 2, o3 = (t3.minY + t3.maxY) / 2, i3 = t3.maxX - t3.minX, r3 = t3.maxY - t3.minY;
a2.push({ center: { x: n3, y: o3 }, width: i3, height: r3, fill: "#00000030", label: `${e4.capacityMeshNodeId}` });
}
e4.portPoints.forEach((t4) => {
if (!t4.portPointId)
return;
const n3 = h2.get(t4.portPointId), o3 = d2.get(t4.portPointId) ?? 0, i3 = u2.get(t4.portPointId) ?? `${e4.capacityMeshNodeId}&${e4.capacityMeshNodeId}`;
c2.push({ x: n3.x, y: n3.y, label: `z:${o3}
o:${i3}` }), e4.portPointsInPairs?.length || e4.portPoints.forEach((e5) => {
if (e5.portPointId && t4 !== e5 && t4.connectionName === e5.connectionName) {
const t5 = h2.get(e5.portPointId);
l2.push({ points: [n3, t5], strokeColor: "#fff822c9" });
}
});
}), e4.portPointsInPairs?.forEach(([e5, t4]) => {
l2.push({ points: [p2(e5), p2(t4)], strokeColor: "#fff822c9" });
});
});
for (const e4 of i2) {
const t3 = o2.get(e4);
t3 && l2.push({ points: [{ x: t3.x1, y: t3.y1 }, { x: t3.x2, y: t3.y2 }], strokeColor: "orange", strokeWidth: 0.01 });
}
if (r2) {
const e4 = o2.get(r2);
e4 && (l2.push({ points: [{ x: e4.x1, y: e4.y1 }, { x: e4.x2, y: e4.y2 }], strokeColor: "red", strokeWidth: 0.03 }), c2.push({ x: e4.center.x, y: e4.center.y, label: e4.ownerPairKey }));
}
for (const e4 of o2.values())
l2.push({ points: [{ x: e4.x1, y: e4.y1 }, { x: e4.x2, y: e4.y2 }], strokeColor: "#33b5ff80", strokeWidth: 0.006 });
return { rects: a2, lines: l2, points: c2 };
})({ obstacles: this.input.obstacles, nodeWithPortPoints: this.input.nodeWithPortPoints, mapOfOwnerPairToPortPoints: this.mapOfOwnerPairToPortPoints, mapOfOwnerPairToSharedEdge: this.mapOfOwnerPairToSharedEdge, ownerPairsToProcess: this.ownerPairsToProcess, currentOwnerPairBeingProcessed: this.currentOwnerPairBeingProcessed, mapOfNodeIdToBounds: this.mapOfNodeIdToBounds });
}
};
var vo = (e3, t2, n2) => e3.connectedTo.some((e4) => e4 === t2.connectionName || e4 === t2.rootConnectionName || (n2?.areIdsConnected(t2.connectionName, e4) ?? false) || t2.rootConnectionName !== undefined && (n2?.areIdsConnected(t2.rootConnectionName, e4) ?? false));
function Io(e3) {
return !("layers" in e3) && typeof e3.layer == "string";
}
function So(e3) {
return Co(e3)[0];
}
function Co(e3) {
if (function(e4) {
return !("layer" in e4) && Array.isArray(e4.layers);
}(e3))
return e3.layers;
if (Io(e3))
return [e3.layer];
throw new Error("Connection point must specify either layer or layers, never both");
}
var Po = (e3, t2) => {
if (e3 === 1 && t2 === 1)
return "inner1";
if (e3 < 0 || e3 >= t2)
throw new Error(`Invalid z "${e3}" for layer count: ${t2}`);
return e3 === 0 ? "top" : e3 === t2 - 1 ? "bottom" : `inner${e3}`;
};
var Mo = (e3, t2) => !!e3 && !!t2 && Math.abs(e3.x - t2.x) <= 0.000000000001 && Math.abs(e3.y - t2.y) <= 0.000000000001;
var wo = (e3, t2) => jt(e3, t2) <= 0.000001;
var No = (e3, t2, n2, o2) => t2.toNextSegmentType === "through_obstacle" || (o2.connectedMultilayerObstacles ? o2.connectedMultilayerObstacles.some((e4) => wo(t2, e4) && wo(n2, e4)) : o2.obstacles?.some((i2) => ((e4) => (e4.__zLayers?.length ?? e4.layers?.length ?? 0) > 1)(i2) && wo(t2, i2) && wo(n2, i2) && vo(i2, e3, o2.connMap)) ?? false);
var To = ({ endpoint: e3, endpointLayer: t2, connectionPoints: n2, tolerance: o2 }) => {
let i2;
for (const r2 of n2) {
if (!Io(r2) || !r2.terminalVia)
continue;
if (r2.layer !== t2)
continue;
const n3 = vt(r2, e3);
n3 > o2 || (!i2 || n3 < i2.distance) && (i2 = { point: r2, distance: n3 });
}
return i2?.point;
};
var Ro = (e3, t2, n2 = {}) => {
const o2 = [];
if (e3.route.length === 0)
return o2;
let i2 = [], r2 = e3.route[0].z;
for (let s3 = 0;s3 < e3.route.length; s3++) {
const a2 = e3.route[s3];
if (a2.z !== r2) {
const s4 = i2[i2.length - 1], c2 = Po(r2, t2);
for (const t3 of i2)
o2.push({ route_type: "wire", x: t3.x, y: t3.y, width: t3.traceThickness ?? e3.traceThickness, layer: c2 });
const l2 = Po(a2.z, t2);
if (s4 && No(e3, s4, a2, n2))
o2.push({ route_type: "through_obstacle", start: { x: s4.x, y: s4.y }, end: { x: a2.x, y: a2.y }, from_layer: c2, to_layer: l2, width: s4.traceThickness ?? e3.traceThickness, ...s4.toNextSegmentCircuitJsonMetadata ? { circuitJsonMetadata: s4.toNextSegmentCircuitJsonMetadata } : {} });
else {
e3.vias.some((e4) => Math.abs(e4.x - a2.x) < 0.001 && Math.abs(e4.y - a2.y) < 0.001) && o2.push({ route_type: "via", x: a2.x, y: a2.y, from_layer: c2, to_layer: l2, via_diameter: e3.viaDiameter, ...n2.defaultViaHoleDiameter !== undefined ? { via_hole_diameter: n2.defaultViaHoleDiameter } : {} });
}
i2 = [a2], r2 = a2.z;
} else
Mo(i2[i2.length - 1], a2) || i2.push(a2);
}
const s2 = Po(r2, t2);
for (const t3 of i2)
o2.push({ route_type: "wire", x: t3.x, y: t3.y, width: t3.traceThickness ?? e3.traceThickness, layer: s2 });
if (e3.jumpers && e3.jumpers.length > 0) {
const n3 = Po(e3.route[0]?.z ?? 0, t2);
for (const t3 of e3.jumpers)
o2.push({ route_type: "jumper", start: t3.start, end: t3.end, footprint: t3.footprint, layer: n3 });
}
return (({ route: e4, hdRoute: t3, layerCount: n3, connectionPoints: o3 = [], tolerance: i3 = 0.25, defaultViaHoleDiameter: r3 }) => {
if (e4.length === 0 || t3.route.length === 0 || !o3.length)
return e4;
if (!o3.some((e5) => Io(e5) && e5.terminalVia))
return e4;
const s3 = e4.filter((e5) => e5.route_type !== "jumper"), a2 = e4.filter((e5) => e5.route_type === "jumper");
if (s3.length === 0)
return e4;
const c2 = t3.route[0], l2 = t3.route[t3.route.length - 1], h2 = Po(c2.z, n3), d2 = Po(l2.z, n3), u2 = To({ endpoint: c2, endpointLayer: h2, connectionPoints: o3, tolerance: i3 }), p2 = To({ endpoint: l2, endpointLayer: d2, connectionPoints: o3, tolerance: i3 }), m2 = [], g2 = [], f2 = s3[0], _2 = s3[s3.length - 1], y2 = c2.traceThickness ?? t3.traceThickness, b2 = l2.traceThickness ?? t3.traceThickness;
return u2?.terminalVia && (m2.push({ route_type: "via", x: u2.x, y: u2.y, from_layer: u2.layer, to_layer: u2.terminalVia.toLayer, via_diameter: u2.terminalVia.viaDiameter ?? t3.viaDiameter, ...r3 !== undefined ? { via_hole_diameter: r3 } : {} }), f2?.route_type === "wire" && f2.layer === u2.layer && Mo(f2, u2) || m2.push({ route_type: "wire", x: u2.x, y: u2.y, width: y2, layer: u2.layer })), p2?.terminalVia && (_2?.route_type === "wire" && _2.layer === p2.layer && Mo(_2, p2) || g2.push({ route_type: "wire", x: p2.x, y: p2.y, width: b2, layer: p2.layer }), g2.push({ route_type: "via", x: p2.x, y: p2.y, from_layer: p2.layer, to_layer: p2.terminalVia.toLayer, via_diameter: p2.terminalVia.viaDiameter ?? t3.viaDiameter, ...r3 !== undefined ? { via_hole_diameter: r3 } : {} })), [...m2, ...s3, ...g2, ...a2];
})({ route: o2, hdRoute: e3, layerCount: t2, connectionPoints: n2.connectionPoints, tolerance: n2.terminalViaAttachTolerance, defaultViaHoleDiameter: n2.defaultViaHoleDiameter });
};
var Ao = (e3, t2) => {
const n2 = {};
for (let o2 = 0;o2 < e3.connections.length; o2++) {
const i2 = e3.connections[o2], r2 = t2?.getNetConnectedToId(i2.name);
r2 && !n2[r2] && (n2[r2] = `hsl(${300 * o2 / e3.connections.length}, 100%, 50%)`), n2[i2.name] = (r2 ? n2[r2] : null) ?? `hsl(${340 * o2 / e3.connections.length}, 100%, 50%)`;
}
return n2;
};
var Oo = (e3, t2) => {
try {
return Re(t2, e3);
} catch (t3) {
return console.error(t3), e3;
}
};
var ko = (e3, t2 = 1) => {
if (!e3)
return "rgba(0, 0, 0, 0.5)";
const n2 = 300 * e3.split("").reduce((e4, t3) => e4 + t3.charCodeAt(0), 0) / e3.length % 360;
return t2 < 1 ? `hsla(${n2}, 100%, 50%, ${t2})` : `hsl(${n2}, 100%, 50%)`;
};
var Do = (e3) => {
const t2 = new Set;
return e3.filter((e4) => !t2.has(e4) && (t2.add(e4), true));
};
var Lo = (e3, t2, n2) => {
if (!t2)
return;
const o2 = e3.get(t2);
o2 ? o2.includes(n2) || o2.push(n2) : e3.set(t2, [n2]);
};
var zo = (e3) => {
const t2 = new Map;
for (const n2 of e3.connections) {
const e4 = n2.__rootConnectionNames ?? [n2.name];
for (const o2 of e4) {
Lo(t2, n2.name, o2), Lo(t2, o2, o2), Lo(t2, n2.__netConnectionName, o2);
for (const e5 of n2.pointsToConnect)
Lo(t2, e5.pointId, o2), Lo(t2, e5.pcb_port_id, o2);
}
}
return (e4) => ((e5, t3 = []) => {
const n2 = Do(t3).join(", ");
return e5.layers.map((e6) => n2 ? `${e6}
${n2}` : e6).join(`
`);
})(e4, ((e5, t3) => Do([...e5.connectedTo.flatMap((e6) => t3.get(e6) ?? []), ...(e5.offBoardConnectsTo ?? []).flatMap((e6) => t3.get(e6) ?? [])]))(e4, t2));
};
var Bo = (e3, t2) => `z${_o(e3, t2).join(",")}`;
var Fo = (e3, t2) => Bo(Co(e3), t2);
var jo = (e3, t2) => e3.__zLayers && e3.__zLayers.length > 0 ? fo(e3.__zLayers, t2) : _o(e3.layers, t2);
var $o = (e3, t2) => `z${jo(e3, t2).join(",")}`;
var Yo = (...e3) => e3.find((e4) => typeof e4 == "number" && Number.isFinite(e4));
var Xo = (e3) => {
const t2 = Yo(e3.min_via_hole_diameter, e3.minViaHoleDiameter), n2 = Yo(e3.min_via_pad_diameter, e3.minViaPadDiameter, e3.minViaDiameter), o2 = Math.max(n2 ?? e3.minViaDiameter ?? 0.3, t2 ?? 0);
return { padDiameter: o2, holeDiameter: t2 ?? 0.5 * o2 };
};
var Wo = { "0603": { length: 1.65, width: 0.95, padLength: 0.8, padWidth: 0.95 }, 1206: { length: 3.2, width: 1.6, padLength: 0.6, padWidth: 1.6 }, "1206x4_pair": { length: 2.7, width: 0.5, padLength: 0.8, padWidth: 0.5 } };
var Vo = { top: "red", bottom: "blue", inner1: "green", inner2: "yellow", inner3: "orange", inner4: "purple", inner5: "cyan", inner6: "magenta", inner7: "lime", inner8: "brown" };
function Ho(e3) {
if (Object.hasOwn(Vo, e3))
return Vo[e3];
const t2 = /^inner([1-9]\d*)$/.exec(e3);
if (t2) {
return `hsl(${137 * Number(t2[1]) % 360}, 70%, 45%)`;
}
throw new Error(`No visualization color for layer "${e3}"`);
}
var Go = (e3, t2 = {}) => {
const n2 = [], o2 = [], i2 = [], r2 = [], s2 = Ao(e3), a2 = t2.traceColorMode ?? "layer", c2 = e3.layerCount, l2 = Xo(e3), h2 = zo(e3);
if (e3.connections)
for (const t3 of e3.connections)
for (const e4 of t3.pointsToConnect) {
const n3 = Co(e4), o3 = t3.__rootConnectionNames ?? [t3.name];
i2.push({ x: e4.x, y: e4.y, color: s2[t3.name], layer: Fo(e4, c2), label: [t3.name, o3.join(", "), n3.join(",")].join(`
`) });
}
if (e3.traces)
for (const t3 of e3.traces) {
let i3 = e3.minTraceWidth;
const h3 = t3.route.filter((e4) => e4.route_type === "jumper"), d2 = (e4, t4) => {
const n3 = 0.01;
for (const o3 of h3) {
const i4 = Math.abs(e4.x - o3.start.x) < n3 && Math.abs(e4.y - o3.start.y) < n3 && Math.abs(t4.x - o3.end.x) < n3 && Math.abs(t4.y - o3.end.y) < n3, r3 = Math.abs(e4.x - o3.end.x) < n3 && Math.abs(e4.y - o3.end.y) < n3 && Math.abs(t4.x - o3.start.x) < n3 && Math.abs(t4.y - o3.start.y) < n3;
if (i4 || r3)
return true;
}
return false;
};
for (const e4 of t3.route)
if (e4.route_type === "via") {
const n3 = go(e4.from_layer, c2), i4 = go(e4.to_layer, c2), r3 = (e4.via_diameter ?? l2.padDiameter) / 2, h4 = Array.from({ length: Math.abs(i4 - n3) + 1 }, (e5, t4) => Math.min(n3, i4) + t4);
o2.push({ center: { x: e4.x, y: e4.y }, radius: r3, fill: a2 === "net" ? s2[t3.connection_name] : "blue", stroke: "none", layer: `z${h4.join(",")}` });
} else if (e4.route_type === "through_obstacle") {
const o3 = s2[t3.connection_name] ?? "purple";
n2.push({ points: [e4.start, e4.end], strokeColor: Oo(o3, 0.35), strokeWidth: e4.width, strokeDash: [0.1, 0.1], layer: Bo([e4.from_layer, e4.to_layer], c2), label: `${t3.connection_name} through_obstacle` });
}
let u2;
for (let e4 = 0;e4 < t3.route.length - 1; e4++) {
const o3 = t3.route[e4], l3 = t3.route[e4 + 1];
if (o3.route_type === "jumper") {
u2 = undefined;
const e5 = s2[t3.connection_name] ?? "rgba(255, 165, 0, 0.8)", i4 = o3.footprint, a3 = Wo[i4 === "1206x4_pair" ? "1206x4_pair" : "0603"] ?? Wo["0603"], l4 = o3.end.x - o3.start.x, h4 = o3.end.y - o3.start.y, d3 = Math.abs(l4) > Math.abs(h4), p2 = d3 ? a3.padLength : a3.padWidth, m2 = d3 ? a3.padWidth : a3.padLength;
r2.push({ center: o3.start, width: p2, height: m2, fill: Oo(e5, 0.5), stroke: "rgba(0, 0, 0, 0.5)", layer: Bo([o3.layer], c2) }), r2.push({ center: o3.end, width: p2, height: m2, fill: Oo(e5, 0.5), stroke: "rgba(0, 0, 0, 0.5)", layer: Bo([o3.layer], c2) }), n2.push({ points: [o3.start, o3.end], strokeColor: "rgba(100, 100, 100, 0.8)", strokeWidth: 0.3 * a3.padWidth, layer: Bo([o3.layer], c2) });
} else if (o3.route_type === "wire" && l3.route_type === "wire" && l3.layer === o3.layer) {
if (d2({ x: o3.x, y: o3.y }, { x: l3.x, y: l3.y })) {
u2 = undefined;
continue;
}
i3 = o3.width;
const e5 = o3.layer === "top", r3 = a2 === "net" ? s2[t3.connection_name] : Ho(o3.layer), h4 = `z${go(o3.layer, c2)}`;
if (u2 && u2.layer === h4 && u2.strokeWidth === i3) {
u2.points.push({ x: l3.x, y: l3.y });
continue;
}
u2 = { points: [{ x: o3.x, y: o3.y }, { x: l3.x, y: l3.y }], layer: h4, strokeWidth: i3, strokeColor: e5 ? r3 : Oo(r3, 0.5), ...a2 === "net" ? { label: t3.connection_name } : {}, ...e5 ? {} : { strokeDash: [0.2, 0.2] } }, n2.push(u2);
} else
u2 = undefined;
}
}
for (const t3 of e3.obstacles) {
if (t3.isCopperPour)
continue;
const e4 = jo(t3, c2);
if (e4.length === 0)
throw new Error(`Cannot visualize obstacle "${t3.obstacleId ?? "unknown"}" without a valid layer: layers=${t3.layers.join(",")}, __zLayers=${t3.__zLayers?.join(",") ?? "unset"}, layerCount=${c2}`);
const n3 = Ho((e4.length === 1 ? Po(e4[0], c2) : null) === "bottom" ? "bottom" : "top"), o3 = 0.5 ** e4.length;
r2.push({ center: t3.center, width: t3.width, height: t3.height, ccwRotationDegrees: t3.ccwRotationDegrees, fill: Oo(n3, o3), layer: $o(t3, c2), label: h2(t3) });
}
if (e3.jumpers)
for (const t3 of e3.jumpers)
for (const e4 of t3.pads)
r2.push({ center: e4.center, width: e4.width, height: e4.height, ccwRotationDegrees: e4.ccwRotationDegrees, fill: "rgba(255, 165, 0, 0.3)", stroke: "rgba(255, 165, 0, 0.8)", layer: $o(e4, c2) });
return { rects: r2, circles: o2, lines: n2, points: i2 };
};
function Uo([e3, t2], [n2, o2], { lineThickness: i2 = 0 } = {}) {
if (i2 === 0)
return Zo(e3, t2, n2, o2);
const r2 = function(e4, t3, n3, o3) {
if (e4.x === t3.x && e4.y === t3.y)
return Qo(e4, n3, o3);
if (n3.x === o3.x && n3.y === o3.y)
return Qo(n3, e4, t3);
if (Zo(e4, t3, n3, o3))
return 0;
const i3 = [Qo(e4, n3, o3), Qo(t3, n3, o3), Qo(n3, e4, t3), Qo(o3, e4, t3)];
return Math.min(...i3);
}(e3, t2, n2, o2);
return r2 <= i2;
}
function Zo(e3, t2, n2, o2) {
const i2 = qo(e3, t2, n2), r2 = qo(e3, t2, o2), s2 = qo(n2, o2, e3), a2 = qo(n2, o2, t2);
return i2 !== r2 && s2 !== a2 || (!(i2 !== 0 || !Jo(e3, n2, t2)) || (!(r2 !== 0 || !Jo(e3, o2, t2)) || (!(s2 !== 0 || !Jo(n2, e3, o2)) || !(a2 !== 0 || !Jo(n2, t2, o2)))));
}
function qo(e3, t2, n2) {
const o2 = (t2.y - e3.y) * (n2.x - t2.x) - (t2.x - e3.x) * (n2.y - t2.y);
return o2 === 0 ? 0 : o2 > 0 ? 1 : 2;
}
function Jo(e3, t2, n2) {
return t2.x <= Math.max(e3.x, n2.x) && t2.x >= Math.min(e3.x, n2.x) && t2.y <= Math.max(e3.y, n2.y) && t2.y >= Math.min(e3.y, n2.y);
}
function Qo(e3, t2, n2) {
const o2 = (n2.x - t2.x) ** 2 + (n2.y - t2.y) ** 2;
if (o2 === 0)
return Ko(e3, t2);
let i2 = ((e3.x - t2.x) * (n2.x - t2.x) + (e3.y - t2.y) * (n2.y - t2.y)) / o2;
i2 = Math.max(0, Math.min(1, i2));
return Ko(e3, { x: t2.x + i2 * (n2.x - t2.x), y: t2.y + i2 * (n2.y - t2.y) });
}
function Ko(e3, t2) {
const n2 = e3.x - t2.x, o2 = e3.y - t2.y;
return Math.sqrt(n2 * n2 + o2 * o2);
}
function ei(e3) {
const t2 = new Map;
let n2 = 0;
function o2(e4) {
for (const [, n3] of t2)
if (n3.has(e4))
return n3;
const o3 = new Set;
return t2.set("connectivity_net" + n2++, o3), o3;
}
for (const n3 of e3) {
let e4 = null;
for (const i2 of n3) {
if (e4) {
if (!e4.has(i2)) {
const n4 = o2(i2);
if (n4 !== e4) {
for (const t3 of n4)
e4.add(t3);
t2.delete(Array.from(t2.entries()).find(([, e5]) => e5 === n4)[0]);
}
}
} else
e4 = o2(i2);
e4.add(i2);
}
}
return Object.fromEntries(Array.from(t2.entries()).map(([e4, t3]) => [e4, Array.from(t3)]));
}
var ti = class {
netMap;
idToNetMap;
constructor(e3) {
this.netMap = e3, this.idToNetMap = {};
for (const [t2, n2] of Object.entries(e3))
for (const e4 of n2)
this.idToNetMap[e4] = t2;
}
addConnections(e3) {
for (const t2 of e3) {
const e4 = new Set;
for (const n3 of t2) {
const t3 = this.idToNetMap[n3];
t3 && e4.add(t3);
}
let n2;
if (e4.size === 0)
n2 = `connectivity_net${Object.keys(this.netMap).length}`, this.netMap[n2] = [];
else if (e4.size === 1)
n2 = e4.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
else {
n2 = e4.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
for (const t3 of e4)
if (t3 !== n2) {
this.netMap[n2].push(...this.netMap[t3]), this.netMap[t3] = this.netMap[n2];
for (const e5 of this.netMap[n2])
this.idToNetMap[e5] = n2;
}
}
for (const e5 of t2)
this.netMap[n2].includes(e5) || this.netMap[n2].push(e5), this.idToNetMap[e5] = n2;
}
}
getIdsConnectedToNet(e3) {
return this.netMap[e3] || [];
}
getNetConnectedToId(e3) {
return this.idToNetMap[e3];
}
areIdsConnected(e3, t2) {
if (e3 === t2)
return true;
const n2 = this.getNetConnectedToId(e3);
if (!n2)
return false;
const o2 = this.getNetConnectedToId(t2);
return !!o2 && (n2 === o2 || o2 === e3 || o2 === e3);
}
areAllIdsConnected(e3) {
const t2 = this.getNetConnectedToId(e3[0]);
for (const n2 of e3) {
const e4 = this.getNetConnectedToId(n2);
if (e4 === undefined)
return false;
if (e4 !== t2)
return false;
}
return true;
}
};
var ni = (e3) => {
const t2 = [];
for (const n3 of e3)
if (n3.type === "source_trace")
t2.push([n3.source_trace_id, ...n3.connected_source_port_ids ?? [], ...n3.connected_source_net_ids ?? []].filter(Boolean));
else if (n3.type === "pcb_port") {
const { pcb_port_id: e4, source_port_id: o2 } = n3;
o2 && e4 && t2.push([o2, e4]);
} else if (n3.type === "pcb_smtpad") {
const { pcb_smtpad_id: e4, pcb_port_id: o2 } = n3;
o2 && e4 && t2.push([e4, o2]);
} else if (n3.type === "pcb_plated_hole") {
const { pcb_plated_hole_id: e4, pcb_port_id: o2 } = n3;
o2 && e4 && t2.push([e4, o2]);
} else if (n3.type === "pcb_trace") {
const { pcb_trace_id: e4, source_trace_id: o2 } = n3;
o2 && e4 && t2.push([e4, o2]);
}
const n2 = ei(t2);
return new ti(n2);
};
var oi = class {
circuitJson;
traceIdToElm;
portIdToElm;
connMap;
constructor(e3) {
this.circuitJson = e3 || [], this.traceIdToElm = new Map, this.portIdToElm = new Map, e3 ? (this._buildTraceMap(), this._buildPortMap(), this.connMap = this._buildTraceConnectivityMap()) : this.connMap = new ti({});
}
_buildPortMap() {
for (const e3 of this.circuitJson)
e3.type === "pcb_port" && this.portIdToElm.set(e3.pcb_port_id, e3);
}
_buildTraceMap() {
for (const e3 of this.circuitJson)
e3.type === "pcb_trace" && this.traceIdToElm.set(e3.pcb_trace_id, e3);
}
_buildTraceConnectivityMap() {
const e3 = [], t2 = Array.from(this.traceIdToElm.keys());
for (let n2 = 0;n2 < t2.length; n2++)
for (let o2 = n2 + 1;o2 < t2.length; o2++) {
const i2 = this.traceIdToElm.get(t2[n2]), r2 = this.traceIdToElm.get(t2[o2]);
this._arePcbTracesConnected(i2, r2) && e3.push([t2[n2], t2[o2]]);
}
for (const t3 of this.portIdToElm.values())
for (const n2 of this.traceIdToElm.values())
for (const o2 of n2.route)
o2.route_type === "wire" && (o2.start_pcb_port_id === t3.pcb_port_id ? e3.push([t3.pcb_port_id, n2.pcb_trace_id]) : o2.end_pcb_port_id === t3.pcb_port_id && e3.push([n2.pcb_trace_id, t3.pcb_port_id]));
return new ti(ei(e3));
}
addTrace(e3) {
this.traceIdToElm.set(e3.pcb_trace_id, e3);
const t2 = [];
for (const n2 of e3.route)
n2.route_type === "wire" && (n2.start_pcb_port_id && t2.push([n2.start_pcb_port_id, e3.pcb_trace_id]), n2.end_pcb_port_id && t2.push([n2.end_pcb_port_id, e3.pcb_trace_id]));
this.connMap.addConnections(t2);
}
_arePcbTracesConnected(e3, t2) {
for (let n2 = 0;n2 < e3.route.length - 1; n2++) {
const o2 = e3.route[n2], i2 = e3.route[n2 + 1];
if (o2.route_type === "wire" && i2.route_type === "wire")
for (let e4 = 0;e4 < t2.route.length - 1; e4++) {
const n3 = t2.route[e4], r2 = t2.route[e4 + 1];
if (n3.route_type !== "wire")
continue;
if (r2.route_type !== "wire")
continue;
if (Uo([o2, i2], [n3, r2], { lineThickness: (o2.width + n3.width) / 2 }))
return true;
}
}
return false;
}
areTracesConnected(e3, t2) {
return this.connMap.areIdsConnected(e3, t2);
}
getAllTracesConnectedToTrace(e3) {
const t2 = this.connMap.getNetConnectedToId(e3);
return t2 ? this.connMap.getIdsConnectedToNet(t2).filter((e4) => this.traceIdToElm.has(e4)).map((e4) => this.traceIdToElm.get(e4)) : [];
}
getAllTracesConnectedToPort(e3) {
const t2 = this.connMap.getNetConnectedToId(e3);
return t2 ? this.connMap.getIdsConnectedToNet(t2).filter((e4) => this.traceIdToElm.has(e4)).map((e4) => this.traceIdToElm.get(e4)) : [];
}
};
var ii = (e3) => `${Math.round(100 * e3.x)},${Math.round(100 * e3.y)}`;
var ri = (e3) => {
const t2 = new ti({});
for (const n2 of e3.connections) {
for (const e4 of n2.__rootConnectionNames ?? [])
t2.addConnections([[n2.name, e4]]);
n2.__netConnectionName && t2.addConnections([[n2.name, n2.__netConnectionName]]);
for (const o2 of n2.pointsToConnect)
t2.addConnections([[n2.name, `${ii(o2)}:${Co(o2).map((t3) => go(t3, e3.layerCount)).sort().join("-")}`]]), "pcb_port_id" in o2 && o2.pcb_port_id && t2.addConnections([[n2.name, o2.pcb_port_id]]), o2.pointId && t2.addConnections([[n2.name, o2.pointId]]);
}
for (const n2 of e3.obstacles) {
const o2 = n2.offBoardConnectsTo ?? [], i2 = Array.from(new Set([n2.obstacleId, ...n2.connectedTo, ...o2, `${ii(n2.center)}:${n2.layers.map((t3) => go(t3, e3.layerCount)).sort().join("-")}`].filter(Boolean)));
i2.length > 0 && t2.addConnections([i2]);
}
for (const n2 of e3.traces ?? []) {
const e4 = Array.from(new Set([n2.pcb_trace_id, n2.connection_name, ...n2.connectsTo ?? []].filter(Boolean)));
e4.length > 0 && t2.addConnections([e4]);
}
return t2;
};
var si = (e3) => {
const t2 = new ti({});
for (const n2 of e3.connections) {
const e4 = n2.externallyConnectedPointIds ?? [];
t2.addConnections(e4);
}
for (const n2 of e3.traces ?? []) {
const e4 = n2.connectsTo ?? [];
e4.length !== 0 && t2.addConnections([[n2.pcb_trace_id, ...e4]]);
}
return t2;
};
var ai = class {
MAX_ITERATIONS = 1000;
solved = false;
failed = false;
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 (e3) {
throw this.error = `${this.getSolverName()} error: ${e3}`, console.error(this.error), this.failed = true, e3;
}
!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 = true), "computeProgress" in this && (this.progress = this.computeProgress());
}
}
_step() {}
getConstructorParams() {
throw new Error("getConstructorParams not implemented");
}
solve() {
const e3 = Date.now();
for (;!this.solved && !this.failed; )
this.step();
const t2 = Date.now();
this.timeToSolve = t2 - e3;
}
visualize() {
return { lines: [], points: [], rects: [], circles: [] };
}
tryFinalAcceptance() {}
preview() {
return { lines: [], points: [], rects: [], circles: [] };
}
};
function ci(e3) {
const t2 = new Map;
for (const n2 of e3)
for (const e4 of n2.nodeIds)
t2.set(e4, [...t2.get(e4) ?? [], n2]);
return t2;
}
var li = class extends ai {
getSolverName() {
return "AvailableSegmentPointSolver";
}
nodes;
edges;
traceWidth;
obstacleMargin;
minPortSpacing;
nodeMap;
nodeEdgeMap;
sharedEdgeSegments = [];
edgeSegmentMap = new Map;
portPointMap = new Map;
colorMap;
shouldReturnCrampedPortPoints;
constructor({ nodes: e3, edges: t2, traceWidth: n2, obstacleMargin: o2, colorMap: i2, shouldReturnCrampedPortPoints: r2 }) {
super(), this.nodes = e3, this.edges = t2, this.traceWidth = n2, this.obstacleMargin = o2 ?? 0.15, this.shouldReturnCrampedPortPoints = r2, this.minPortSpacing = this.traceWidth + this.obstacleMargin, this.colorMap = i2 ?? {}, this.nodeMap = new Map(e3.map((e4) => [e4.capacityMeshNodeId, e4])), this.nodeEdgeMap = ci(t2), this.MAX_ITERATIONS = 1;
}
_step() {
this.computeAllSharedEdgeSegments(), this.solved = true;
}
computeAllSharedEdgeSegments() {
for (const e3 of this.edges) {
const [t2, n2] = e3.nodeIds, o2 = this.nodeMap.get(t2), i2 = this.nodeMap.get(n2);
if (!o2 || !i2)
continue;
const r2 = this.computeSharedEdgeSegment(e3, o2, i2);
if (r2) {
this.sharedEdgeSegments.push(r2), this.edgeSegmentMap.set(e3.capacityMeshEdgeId, r2);
for (const e4 of r2.portPoints)
this.portPointMap.set(e4.segmentPortPointId, e4);
}
}
}
computeSharedEdgeSegment(e3, t2, n2) {
const o2 = this.findOverlappingSegment(t2, n2);
if (!o2)
return null;
const i2 = t2.availableZ.filter((e4) => n2.availableZ.includes(e4));
if (i2.length === 0)
return null;
const r2 = Math.sqrt((o2.end.x - o2.start.x) ** 2 + (o2.end.y - o2.start.y) ** 2), s2 = Boolean(t2._isNarrowQfpPadGap || n2._isNarrowQfpPadGap), a2 = 3 * this.minPortSpacing / 4, c2 = Math.max(0, r2 - 2 * a2);
if (c2 <= 0 && !t2._containsTarget && !n2._containsTarget) {
if (!this.shouldReturnCrampedPortPoints)
return null;
const r3 = [];
for (const s3 of i2)
r3.push({ segmentPortPointId: `${e3.capacityMeshEdgeId}_pp0_z${s3}_cramped`, x: (o2.start.x + o2.end.x) / 2, y: (o2.start.y + o2.end.y) / 2, availableZ: [s3], nodeIds: [t2.capacityMeshNodeId, n2.capacityMeshNodeId], edgeId: e3.capacityMeshEdgeId, connectionName: null, distToCentermostPortOnZ: 0, cramped: true });
return { edgeId: e3.capacityMeshEdgeId, nodeIds: [t2.capacityMeshNodeId, n2.capacityMeshNodeId], start: o2.start, end: o2.end, availableZ: i2, portPoints: r3 };
}
let l2 = Math.max(1, Math.floor(c2 / this.minPortSpacing) + 1);
if (t2._offBoardConnectionId || n2._offBoardConnectionId) {
if (t2._offBoardConnectionId && !n2._offBoardConnectionId) {
if (this.shouldSkipOffBoardPortPoint(t2, n2))
return null;
} else if (n2._offBoardConnectionId && !t2._offBoardConnectionId && this.shouldSkipOffBoardPortPoint(n2, t2))
return null;
l2 = 1;
}
const h2 = [], d2 = o2.end.x - o2.start.x, u2 = o2.end.y - o2.start.y, p2 = (o2.start.x + o2.end.x) / 2, m2 = (o2.start.y + o2.end.y) / 2;
l2 > 5 && (l2 = 5 + Math.floor(l2 / 4));
const g2 = [];
for (let e4 = 0;e4 < l2; e4++) {
let t3;
t3 = r2 === 0 || l2 === 1 ? 0.5 : (a2 + c2 * e4 / (l2 - 1)) / r2;
const n3 = o2.start.x + d2 * t3, i3 = o2.start.y + u2 * t3, s3 = Math.sqrt((n3 - p2) ** 2 + (i3 - m2) ** 2);
g2.push({ x: n3, y: i3, distToCenter: s3 });
}
const f2 = g2.reduce((e4, t3) => t3.distToCenter < e4.distToCenter ? t3 : e4);
for (let o3 = 0;o3 < l2; o3++) {
const { x: r3, y: a3 } = g2[o3], c3 = Math.sqrt((r3 - f2.x) ** 2 + (a3 - f2.y) ** 2);
for (const l3 of i2) {
const i3 = { segmentPortPointId: `${e3.capacityMeshEdgeId}_pp${o3}_z${l3}`, x: r3, y: a3, availableZ: [l3], nodeIds: [t2.capacityMeshNodeId, n2.capacityMeshNodeId], edgeId: e3.capacityMeshEdgeId, connectionName: null, distToCentermostPortOnZ: c3, cramped: s2 };
h2.push(i3);
}
}
return { edgeId: e3.capacityMeshEdgeId, nodeIds: [t2.capacityMeshNodeId, n2.capacityMeshNodeId], start: o2.start, end: o2.end, availableZ: i2, portPoints: h2 };
}
shouldSkipOffBoardPortPoint(e3, t2) {
const n2 = this.nodeEdgeMap.get(t2.capacityMeshNodeId) ?? [];
for (const o2 of n2) {
const n3 = o2.nodeIds[0] === t2.capacityMeshNodeId ? o2.nodeIds[1] : o2.nodeIds[0];
if (n3 === e3.capacityMeshNodeId)
continue;
const i2 = this.nodeMap.get(n3);
if (i2?._offBoardConnectionId !== e3._offBoardConnectionId)
continue;
if (this.nodes.filter((t3) => t3._offBoardConnectionId === e3._offBoardConnectionId).length !== 2)
continue;
const r2 = { x: (e3.center.x + i2.center.x) / 2, y: (e3.center.y + i2.center.y) / 2 };
if (r2.x >= t2.center.x - t2.width / 2 && r2.x <= t2.center.x + t2.width / 2 && r2.y >= t2.center.y - t2.height / 2 && r2.y <= t2.center.y + t2.height / 2)
return true;
}
return false;
}
findOverlappingSegment(e3, t2) {
const n2 = { start: Math.max(e3.center.x - e3.width / 2, t2.center.x - t2.width / 2), end: Math.min(e3.center.x + e3.width / 2, t2.center.x + t2.width / 2) }, o2 = { start: Math.max(e3.center.y - e3.height / 2, t2.center.y - t2.height / 2), end: Math.min(e3.center.y + e3.height / 2, t2.center.y + t2.height / 2) }, i2 = n2.end - n2.start, r2 = o2.end - o2.start;
if (i2 < -1e-4 || r2 < -1e-4)
return null;
if (i2 < r2) {
const e4 = (n2.start + n2.end) / 2;
return { start: { x: e4, y: o2.start }, end: { x: e4, y: o2.end } };
}
{
const e4 = (o2.start + o2.end) / 2;
return { start: { x: n2.start, y: e4 }, end: { x: n2.end, y: e4 } };
}
}
getAvailablePortPointsBetweenNodes(e3, t2) {
const n2 = this.edges.find((n3) => n3.nodeIds[0] === e3 && n3.nodeIds[1] === t2 || n3.nodeIds[0] === t2 && n3.nodeIds[1] === e3);
if (!n2)
return [];
const o2 = this.edgeSegmentMap.get(n2.capacityMeshEdgeId);
return o2 ? o2.portPoints.filter((e4) => e4.connectionName === null) : [];
}
getPortPointsForEdge(e3, t2) {
const n2 = this.edges.find((n3) => n3.nodeIds[0] === e3 && n3.nodeIds[1] === t2 || n3.nodeIds[0] === t2 && n3.nodeIds[1] === e3);
if (!n2)
return [];
const o2 = this.edgeSegmentMap.get(n2.capacityMeshEdgeId);
return o2?.portPoints ?? [];
}
assignPortPoint(e3, t2, n2) {
const o2 = this.portPointMap.get(e3);
return !!o2 && (o2.connectionName === null && (o2.connectionName = t2, o2.rootConnectionName = n2, true));
}
releasePortPoint(e3) {
const t2 = this.portPointMap.get(e3);
return !!t2 && (t2.connectionName = null, t2.rootConnectionName = undefined, true);
}
getAvailablePortCountForEdge(e3, t2) {
return this.getAvailablePortPointsBetweenNodes(e3, t2).length;
}
getOutput() {
return this.sharedEdgeSegments;
}
visualize() {
const e3 = { lines: [], points: [], rects: [], circles: [] };
for (const t2 of this.sharedEdgeSegments) {
e3.lines.push({ points: [t2.start, t2.end], strokeColor: "rgba(100, 100, 100, 0.5)" });
for (const n2 of t2.portPoints) {
const t3 = n2.connectionName ? this.colorMap[n2.connectionName] ?? "blue" : "rgba(0, 200, 0, 0.7)";
n2.cramped ? e3.rects.push({ center: { x: n2.x, y: n2.y }, width: 0.1, height: 0.1, fill: t3, layer: `z${n2.availableZ.join(",")}`, label: `cramped ${n2.segmentPortPointId}` }) : e3.circles.push({ center: { x: n2.x, y: n2.y }, radius: this.traceWidth / 2, fill: t3, layer: `z${n2.availableZ.join(",")}`, label: [n2.segmentPortPointId, n2.connectionName, n2.availableZ.join(","), `cd: ${n2.distToCentermostPortOnZ}`, `connects: ${n2.nodeIds.join(",")}`].filter(Boolean).join(`
`) });
}
}
return e3;
}
};
function hi(e3, t2) {
const n2 = e3.center.x - e3.width / 2, o2 = e3.center.x + e3.width / 2, i2 = e3.center.y - e3.height / 2, r2 = e3.center.y + e3.height / 2, s2 = t2.center.x - t2.width / 2, a2 = t2.center.x + t2.width / 2, c2 = t2.center.y - t2.height / 2, l2 = t2.center.y + t2.height / 2, h2 = 0.001, d2 = (Math.abs(o2 - s2) < h2 || Math.abs(n2 - a2) < h2) && Math.min(r2, l2) - Math.max(i2, c2) >= h2, u2 = (Math.abs(r2 - c2) < h2 || Math.abs(i2 - l2) < h2) && Math.min(o2, a2) - Math.max(n2, s2) >= h2;
return d2 || u2;
}
var di = class extends ai {
constructor(e3) {
super(), this.nodes = e3, this.edges = [];
}
nodes;
getSolverName() {
return "CapacityMeshEdgeSolver";
}
edges;
nodeMap;
getNextCapacityMeshEdgeId() {
return `ce${this.edges.length}`;
}
_step() {
this.edges = [];
for (let e3 = 0;e3 < this.nodes.length; e3++)
for (let t2 = e3 + 1;t2 < this.nodes.length; t2++) {
!(this.nodes[e3]._strawNode && this.nodes[t2]._strawNode && this.nodes[e3]._strawParentCapacityMeshNodeId === this.nodes[t2]._strawParentCapacityMeshNodeId) && hi(this.nodes[e3], this.nodes[t2]) && this.doNodesHaveSharedLayer(this.nodes[e3], this.nodes[t2]) && this.edges.push({ capacityMeshEdgeId: this.getNextCapacityMeshEdgeId(), nodeIds: [this.nodes[e3].capacityMeshNodeId, this.nodes[t2].capacityMeshNodeId] });
}
this.handleTargetNodes(), this.solved = true;
}
handleTargetNodes() {
const e3 = this.nodes.filter((e4) => e4._containsTarget), t2 = new Map(this.nodes.map((e4) => [e4.capacityMeshNodeId, e4]));
for (let t3 = 0;t3 < e3.length; t3++)
for (let n2 = t3 + 1;n2 < e3.length; n2++) {
const o2 = e3[t3], i2 = e3[n2];
this.doNodesHaveSharedLayer(o2, i2) && (this.doNodesTouchOrOverlap(o2, i2) && (this.hasEdgeBetween(o2, i2) || this.edges.push({ capacityMeshEdgeId: this.getNextCapacityMeshEdgeId(), nodeIds: [o2.capacityMeshNodeId, i2.capacityMeshNodeId] })));
}
for (const n2 of e3) {
if (!n2._containsObstacle || !n2._targetConnectionName)
continue;
if (!this.edges.some((e4) => {
if (!e4.nodeIds.includes(n2.capacityMeshNodeId))
return false;
const o2 = e4.nodeIds[0] === n2.capacityMeshNodeId ? e4.nodeIds[1] : e4.nodeIds[0], i2 = t2.get(o2);
return !!i2 && (!i2._containsObstacle && !i2._containsTarget && this.doNodesHaveSharedLayer(n2, i2));
}))
throw new Error(`Target obstacle region "${n2.capacityMeshNodeId}" for connection "${n2._targetConnectionName}" has no bordering routing edge`);
}
}
doNodesHaveSharedLayer(e3, t2) {
return e3.availableZ.some((e4) => t2.availableZ.includes(e4));
}
hasEdgeBetween(e3, t2) {
return this.edges.some((n2) => n2.nodeIds.includes(e3.capacityMeshNodeId) && n2.nodeIds.includes(t2.capacityMeshNodeId));
}
doNodesTouchOrOverlap(e3, t2) {
const n2 = 0.001, o2 = e3.center.x - e3.width / 2, i2 = e3.center.x + e3.width / 2, r2 = e3.center.y - e3.height / 2, s2 = e3.center.y + e3.height / 2, a2 = t2.center.x - t2.width / 2, c2 = t2.center.x + t2.width / 2, l2 = t2.center.y - t2.height / 2, h2 = t2.center.y + t2.height / 2;
return o2 <= c2 + n2 && i2 + n2 >= a2 && r2 <= h2 + n2 && s2 + n2 >= l2;
}
visualize() {
const e3 = new Map;
for (const t3 of this.edges)
for (const n2 of t3.nodeIds)
e3.set(n2, 1 + (e3.get(n2) ?? 0));
const t2 = { lines: [], points: [], rects: this.nodes.map((t3) => {
const n2 = Math.min(...t3.availableZ);
return { width: Math.max(t3.width - 2, 0.8 * t3.width), height: Math.max(t3.height - 2, 0.8 * t3.height), center: { x: t3.center.x + n2 * t3.width * 0.05, y: t3.center.y - n2 * t3.width * 0.05 }, fill: t3._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)" }[t3.availableZ.join(",")] ?? "rgba(0,200,200,0.1)", label: [t3.capacityMeshNodeId, `availableZ: ${t3.availableZ.join(",")}`, `target? ${t3._containsTarget ?? false}`, `obs? ${t3._containsObstacle ?? false}`, `conn: ${e3.get(t3.capacityMeshNodeId) ?? 0}`].join(`
`), layer: `z${t3.availableZ.join(",")}` };
}), circles: [] };
if (!this.nodeMap) {
this.nodeMap = new Map;
for (const e4 of this.nodes)
this.nodeMap.set(e4.capacityMeshNodeId, e4);
}
for (const e4 of this.edges) {
const n2 = this.nodeMap.get(e4.nodeIds[0]), o2 = this.nodeMap.get(e4.nodeIds[1]);
if (n2?.center && o2?.center) {
const e5 = Math.min(...n2.availableZ), i2 = Math.min(...o2.availableZ), r2 = { x: n2.center.x + e5 * n2.width * 0.05, y: n2.center.y - e5 * n2.width * 0.05 }, s2 = { x: o2.center.x + i2 * o2.width * 0.05, y: o2.center.y - i2 * o2.width * 0.05 }, a2 = Array.from(new Set([...n2.availableZ, ...o2.availableZ])).sort();
t2.lines.push({ layer: `z${a2.join(",")}`, points: [r2, s2], strokeDash: n2.availableZ.join(",") === o2.availableZ.join(",") ? undefined : "10 5" });
}
}
return t2;
}
};
var ui = class {
constructor(e3) {
this.nodes = e3, this.buckets = new Map;
for (const t2 of e3) {
const e4 = t2.center.x - t2.width / 2, n2 = t2.center.y - t2.height / 2, o2 = t2.center.x + t2.width / 2, i2 = t2.center.y + t2.height / 2, r2 = Math.floor(e4 / this.CELL_SIZE), s2 = Math.floor(o2 / this.CELL_SIZE), a2 = Math.floor(n2 / this.CELL_SIZE), c2 = Math.floor(i2 / this.CELL_SIZE);
for (let e5 = r2;e5 <= s2; e5++)
for (let n3 = a2;n3 <= c2; n3++) {
const o3 = `${e5}x${n3}`, i3 = this.buckets.get(o3);
i3 ? i3.push(t2) : this.buckets.set(o3, [t2]);
}
}
}
nodes;
buckets;
CELL_SIZE = 0.4;
getBucketKey(e3, t2) {
return `${Math.floor(e3 / this.CELL_SIZE)}x${Math.floor(t2 / this.CELL_SIZE)}`;
}
getNodesInArea(e3, t2, n2, o2) {
const i2 = [], r2 = new Set, s2 = e3 - n2 / 2, a2 = t2 - o2 / 2, c2 = e3 + n2 / 2, l2 = t2 + o2 / 2, h2 = Math.floor(s2 / this.CELL_SIZE), d2 = Math.floor(c2 / this.CELL_SIZE), u2 = Math.floor(a2 / this.CELL_SIZE), p2 = Math.floor(l2 / this.CELL_SIZE);
for (let e4 = h2;e4 <= d2; e4++)
for (let t3 = u2;t3 <= p2; t3++) {
const n3 = `${e4}x${t3}`, o3 = this.buckets.get(n3) || [];
for (const e5 of o3)
r2.has(e5.capacityMeshNodeId) || (r2.add(e5.capacityMeshNodeId), i2.push(e5));
}
return i2;
}
};
var pi = class extends di {
constructor(e3) {
super(e3), this.nodes = e3, this.MAX_ITERATIONS = 1e7, this.nodeTree = new ui(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 = true);
const e3 = this.nodes[this.currentNodeIndex], t2 = this.nodeTree.getNodesInArea(e3.center.x, e3.center.y, 2 * e3.width, 2 * e3.height);
for (const n2 of t2) {
if (!hi(e3, n2))
continue;
const t3 = e3._strawNode && n2._strawNode && e3._strawParentCapacityMeshNodeId === n2._strawParentCapacityMeshNodeId;
e3.capacityMeshNodeId === n2.capacityMeshNodeId || t3 || !this.doNodesHaveSharedLayer(e3, n2) || this.edgeSet.has(`${e3.capacityMeshNodeId}-${n2.capacityMeshNodeId}`) || (this.edgeSet.add(`${e3.capacityMeshNodeId}-${n2.capacityMeshNodeId}`), this.edgeSet.add(`${n2.capacityMeshNodeId}-${e3.capacityMeshNodeId}`), this.edges.push({ capacityMeshEdgeId: this.getNextCapacityMeshEdgeId(), nodeIds: [e3.capacityMeshNodeId, n2.capacityMeshNodeId] }));
}
this.currentNodeIndex++;
}
};
var mi = (...e3) => {
const t2 = { points: [], lines: [], circles: [], rects: [], polygons: [], infiniteLines: [], arrows: [], texts: [] };
return e3.forEach((e4, n2) => {
e4 && (e4.lines && (t2.lines = [...t2.lines || [], ...e4.lines.map((e5) => ({ ...e5, step: n2 }))]), e4.points && (t2.points = [...t2.points || [], ...e4.points.map((e5) => ({ ...e5, step: n2 }))]), e4.circles && (t2.circles = [...t2.circles || [], ...e4.circles.map((e5) => ({ ...e5, step: n2 }))]), e4.rects && (t2.rects = [...t2.rects || [], ...e4.rects.map((e5) => ({ ...e5, step: n2 }))]), e4.polygons && (t2.polygons = [...t2.polygons || [], ...e4.polygons.map((e5) => ({ ...e5, step: n2 }))]), e4.infiniteLines && (t2.infiniteLines = [...t2.infiniteLines || [], ...e4.infiniteLines.map((e5) => ({ ...e5, step: n2 }))]), e4.arrows && (t2.arrows = [...t2.arrows || [], ...e4.arrows.map((e5) => ({ ...e5, step: n2 }))]), e4.texts && (t2.texts = [...t2.texts || [], ...e4.texts.map((e5) => ({ ...e5, step: n2 }))]));
}), t2;
};
function gi(e3, t2, n2) {
const o2 = [];
let i2 = null;
for (let r2 = 0;r2 < e3.length; r2++) {
const s2 = e3[r2];
i2 ? i2.z === s2.z ? i2.points.push({ x: s2.x, y: s2.y }) : (o2.push(i2), i2 = { points: [{ x: s2.x, y: s2.y }], z: s2.z, connectionName: t2, color: n2 }) : i2 = { points: [{ x: s2.x, y: s2.y }], z: s2.z, connectionName: t2, color: n2 }, r2 === e3.length - 1 && i2 && o2.push(i2);
}
return o2;
}
function fi(e3, t2) {
return { x: e3.a * t2.x + e3.b * t2.y + e3.c, y: e3.d * t2.x + e3.e * t2.y + e3.f };
}
var _i = (e3, t2, n2) => {
const [o2, i2] = e3;
if (o2 === i2)
return;
const r2 = ((e4, t3) => {
const n3 = e4.portPointId ?? `${e4.connectionName}:${e4.x}:${e4.y}:${e4.z}`, o3 = t3.portPointId ?? `${t3.connectionName}:${t3.x}:${t3.y}:${t3.z}`;
return n3 < o3 ? `${n3}|${o3}` : `${o3}|${n3}`;
})(o2, i2);
t2.has(r2) || (t2.add(r2), n2.push(e3));
};
var yi = (e3, t2, n2) => {
for (let o2 = 0;o2 < e3.length - 1; o2++)
_i([e3[o2], e3[o2 + 1]], t2, n2);
};
var bi = (e3) => {
const t2 = [], n2 = new Set, o2 = ((e4) => {
const t3 = new Map;
for (const n3 of e4)
n3.portPointId && t3.set(n3.portPointId, n3);
return t3;
})(e3);
for (const i3 of e3) {
if (i3.prevPortPointId) {
const e4 = o2.get(i3.prevPortPointId);
e4 && e4.connectionName === i3.connectionName && _i([e4, i3], n2, t2);
}
if (i3.nextPortPointId) {
const e4 = o2.get(i3.nextPortPointId);
e4 && e4.connectionName === i3.connectionName && _i([i3, e4], n2, t2);
}
}
if (t2.length === 0)
return yi(e3, n2, t2), t2;
const i2 = ((e4) => {
const t3 = new Set;
for (const [n3, o3] of e4)
n3.portPointId && t3.add(n3.portPointId), o3.portPointId && t3.add(o3.portPointId);
return t3;
})(t2), r2 = e3.filter((e4) => !e4.portPointId || !i2.has(e4.portPointId));
return yi(r2, n2, t2), t2;
};
function xi(e3, t2, n2) {
return Math.max(t2, Math.min(n2, e3));
}
function vi(e3) {
const t2 = e3.planeSize * e3.layers, n2 = e3.connectionCount, o2 = Math.sqrt(n2), i2 = Math.max(1, e3.maxIterations), r2 = xi(Math.round(t2 * (8 + 1.2 * o2)), 150000, 12000000), s2 = xi(Math.round(r2 * e3.effort), 150000, 12000000), a2 = xi(Math.round(0.2 * i2), 150000, 2000000);
return { maxIterationsIters: Math.max(1, Math.min(i2, Math.max(a2, s2))), baseSearchBudgetIters: xi(Math.round(t2 * (10 + 0.8 * o2) * e3.effort), 50000, 4000000) };
}
function Ii(e3, t2) {
for (let n2 = e3;n2; n2 = n2.prev)
if (n2.id === t2)
return true;
return false;
}
var Si = class {
f = [];
seq = [];
id = [];
n = 0;
push(e3, t2, n2) {
let o2 = this.n++;
for (this.f[o2] = e3, this.seq[o2] = t2, this.id[o2] = n2;o2 > 0; ) {
const e4 = o2 - 1 >> 1;
if (this.less(e4, o2))
break;
this.swap(o2, e4), o2 = e4;
}
}
pop() {
const e3 = 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)), e3;
}
get size() {
return this.n;
}
clear() {
this.n = 0;
}
siftDown(e3) {
for (;; ) {
const t2 = 2 * e3 + 1, n2 = t2 + 1;
if (t2 >= this.n)
return;
let o2 = t2;
if (n2 < this.n && !this.less(t2, n2) && (o2 = n2), this.less(e3, o2))
return;
this.swap(e3, o2), e3 = o2;
}
}
less(e3, t2) {
const n2 = this.f[e3], o2 = this.f[t2];
return n2 !== o2 ? n2 < o2 : this.seq[e3] < this.seq[t2];
}
swap(e3, t2) {
const n2 = this.f[e3];
this.f[e3] = this.f[t2], this.f[t2] = n2;
const o2 = this.seq[e3];
this.seq[e3] = this.seq[t2], this.seq[t2] = o2;
const i2 = this.id[e3];
this.id[e3] = this.id[t2], this.id[t2] = i2;
}
};
var Ci = [-1, -1, -1, 0, 0, 1, 1, 1];
var Pi = [-1, 0, 1, -1, 1, -1, 0, 1];
var Mi = class extends De {
getSolverName() {
return "HighDensitySolverA01";
}
nodeWithPortPoints;
cellSizeMm;
viaDiameter;
MAX_RIPS;
maxCellCount;
traceThickness;
traceMargin;
viaMinDistFromBorder;
showPenaltyMap;
showUsedCellMap;
effort;
stepMultiplier;
hyperParameters;
initialPenaltyFn;
useExactViaTraceClearance = false;
ripHistoryCostMultiplier = 0;
rows;
cols;
layers;
gridOrigin;
gridToBoundsTransform;
availableZ;
zToLayer;
layerToZ;
connNameToId;
connIdToName;
connIdToRootNet;
overlapFriendlyRootNets;
planeSize;
usedCellsFlat;
portOwnerFlat;
usedDiagFlat;
penalty2d;
visitedStamp;
sharedCrossRootPortCells;
stamp = 0;
viaOccupantScanOffsetsDr;
viaOccupantScanOffsetsDc;
viaOccupantScanOffsetsLen;
viaOwnersByCell;
viaCenterIndicesByConn;
viaTraceClearanceMm;
outputCellStepX;
outputCellStepY;
minViaRow;
maxViaRow;
minViaCol;
maxViaCol;
usedIndicesByConn;
usedDiagIndicesByConn;
unsolvedSegs;
solvedRoutes;
activeConnSeg = null;
activeConnId = -1;
crossLayerSearch = false;
nodePool;
heap;
seqCounter = 0;
_viaOccs = [];
viaOccupantsByCell = new Map;
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 e3 = this.activeConnSeg;
return { connectionName: this.connIdToName[e3.connId] ?? "", start: { row: e3.startRow, col: e3.startCol, z: e3.startZ, x: 0, y: 0 }, end: { row: e3.endRow, col: e3.endCol, z: e3.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(e3) {
super(), this.nodeWithPortPoints = e3.nodeWithPortPoints, this.cellSizeMm = e3.cellSizeMm, this.viaDiameter = e3.viaDiameter, this.maxCellCount = e3.maxCellCount, this.traceThickness = e3.traceThickness ?? 0.1, this.traceMargin = e3.traceMargin ?? 0.15, this.viaMinDistFromBorder = e3.viaMinDistFromBorder ?? 0.15, this.showPenaltyMap = e3.showPenaltyMap ?? false, this.showUsedCellMap = e3.showUsedCellMap ?? false, this.effort = e3.effort ?? 1, this.stepMultiplier = Math.max(1, Math.floor(e3.stepMultiplier ?? 1)), this.hyperParameters = { shuffleSeed: 0, ripCost: 10, ripTracePenalty: 0.5, ripViaPenalty: 0.75, viaBaseCost: 0.1, greedyMultiplier: 1.5, ...e3.hyperParameters }, this.MAX_ITERATIONS = 1e8, this.MAX_RIPS = 200, this.initialPenaltyFn = e3.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: e3, cellSizeMm: t2 } = this, { width: n2, height: o2, center: i2 } = e3;
this.availableZ = e3.availableZ ?? [...new Set(e3.portPoints.map((e4) => e4.z))].sort((e4, t3) => e4 - t3), this.rows = Math.floor(o2 / t2), this.cols = Math.floor(n2 / t2), this.layers = this.availableZ.length, this.planeSize = this.rows * this.cols;
const r2 = this.layers * this.planeSize;
if (this.maxCellCount !== undefined && r2 > this.maxCellCount)
return this.error = `Cell count ${r2} exceeds maxCellCount ${this.maxCellCount}`, void (this.failed = true);
const s2 = 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 e4 = 0;e4 < this.availableZ.length; e4++) {
const t3 = this.availableZ[e4];
this.zToLayer.set(t3, e4), this.layerToZ.set(e4, t3);
}
if (this.gridOrigin = { x: i2.x - n2 / 2, y: i2.y - o2 / 2 }, this.gridToBoundsTransform = function(e4) {
const { originX: t3, originY: n3, rows: o3, cols: i3, cellSizeMm: r3, width: s3, height: a3 } = e4;
let c3, l3, h2, d2;
return i3 > 1 ? (c3 = s3 / ((i3 - 1) * r3), l3 = t3 * (1 - c3) - 0.5 * r3 * c3) : (c3 = 1, l3 = t3 + s3 / 2 - (t3 + 0.5 * r3)), o3 > 1 ? (h2 = a3 / ((o3 - 1) * r3), d2 = n3 * (1 - h2) - 0.5 * r3 * h2) : (h2 = 1, d2 = n3 + a3 / 2 - (n3 + 0.5 * r3)), { a: c3, b: 0, c: l3, d: 0, e: h2, f: d2 };
}({ originX: this.gridOrigin.x, originY: this.gridOrigin.y, rows: this.rows, cols: this.cols, cellSizeMm: t2, width: n2, height: o2 }), this.outputCellStepX = this.cols > 1 ? n2 / (this.cols - 1) : n2, this.outputCellStepY = this.rows > 1 ? o2 / (this.rows - 1) : o2, this.connNameToId = new Map, this.connIdToName = [], this.connIdToRootNet = [], this.overlapFriendlyRootNets = new Set, this.penalty2d = new Float64Array(this.planeSize), this.initialPenaltyFn)
for (let e4 = 0;e4 < this.rows; e4++) {
const n3 = e4 * this.cols;
for (let o3 = 0;o3 < this.cols; o3++) {
const i3 = this.gridOrigin.x + (o3 + 0.5) * t2, r3 = this.gridOrigin.y + (e4 + 0.5) * t2, s3 = (o3 + 0.5) / this.cols, a3 = (e4 + 0.5) / this.rows;
this.penalty2d[n3 + o3] = this.initialPenaltyFn({ x: i3, y: r3, px: s3, py: a3, row: e4, col: o3 });
}
}
this.usedCellsFlat = new Int32Array(r2).fill(-1), this.portOwnerFlat = new Int32Array(r2).fill(-1), this.usedDiagFlat = new Int32Array(s2).fill(-1), this.visitedStamp = new Uint32Array(r2), this.stamp = 0;
const a2 = function(e4) {
const t3 = e4.radiusMm / e4.cellSizeMm, n3 = Math.round(t3), o3 = Math.abs(t3 - n3) <= 0.000000001 ? n3 : Math.ceil(t3), i3 = o3 * o3, r3 = [], s3 = [];
for (let e5 = -o3;e5 <= o3; e5++)
for (let t4 = -o3;t4 <= o3; t4++)
e5 * e5 + t4 * t4 <= i3 && (r3.push(e5), s3.push(t4));
return { rowOffsets: new Int32Array(r3), columnOffsets: new Int32Array(s3), length: r3.length };
}({ radiusMm: this.viaDiameter / 2, cellSizeMm: t2 });
if (this.viaOccupantScanOffsetsLen = a2.length, this.viaOccupantScanOffsetsDr = a2.rowOffsets, this.viaOccupantScanOffsetsDc = a2.columnOffsets, this.viaOwnersByCell = new Map, this.viaCenterIndicesByConn = [], this.viaTraceClearanceMm = this.viaDiameter / 2 + this.traceThickness / 2, this.viaMinDistFromBorder > 0) {
const e4 = Math.ceil(this.viaMinDistFromBorder / t2);
this.minViaRow = e4, this.maxViaRow = this.rows - 1 - e4, this.minViaCol = e4, this.maxViaCol = this.cols - 1 - e4;
} 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 c2 = new Map;
for (const e4 of this.nodeWithPortPoints.portPoints) {
const t3 = this.connNameToId.get(e4.connectionName);
if (t3 === undefined)
continue;
const n3 = this.pointToCell(e4), o3 = (n3.z * this.rows + n3.row) * this.cols + n3.col, i3 = this.connIdToRootNet[t3], r3 = c2.get(o3);
r3 === undefined ? c2.set(o3, i3) : r3 !== i3 && this.sharedCrossRootPortCells.add(o3);
const s3 = this.portOwnerFlat[o3];
this.portOwnerFlat[o3] = s3 === -1 || s3 === t3 ? t3 : -2;
}
this.solvedRoutes = new Map, this.usedIndicesByConn = [], this.usedDiagIndicesByConn = [], this.ripCount = [], this.consecutiveSkips = 0, this.penaltyCap = 0.5 * this.hyperParameters.ripCost, this.shuffleConnections();
const l2 = vi({ planeSize: this.planeSize, layers: this.layers, connectionCount: this.unsolvedSegs.length, effort: this.effort, maxIterations: this.MAX_ITERATIONS });
this.baseSearchBudgetIters = l2.baseSearchBudgetIters, this.MAX_ITERATIONS = l2.maxIterationsIters, this.activeConnSeg = null, this.activeConnId = -1, this.nodePool = [], this.heap = new Si, this.seqCounter = 0;
}
_step() {
for (let e3 = 0;e3 < this.stepMultiplier; e3++) {
if (this.solved || this.failed)
return;
this.stepOnce();
}
}
stepOnce() {
if (!this.activeConnSeg) {
if (this.unsolvedSegs.length === 0)
return void (this.solved = true);
const e4 = this.unsolvedSegs.shift();
this.activeConnSeg = e4, this.activeConnId = e4.connId, this.crossLayerSearch = e4.startZ !== e4.endZ, this.viaOccupantsByCell.clear(), this.nodePool = [], this.heap.clear(), this.seqCounter = 0, this.searchIterations = 0, this.nextStamp();
const t3 = this.computeH(e4.startZ, e4.startRow, e4.startCol, e4.endZ, e4.endRow, e4.endCol) * this.hyperParameters.greedyMultiplier;
return this.nodePool.push({ z: e4.startZ, row: e4.startRow, col: e4.startCol, g: 0, f: t3, parentIdx: -1, ripped: null }), void this.heap.push(t3, this.seqCounter++, 0);
}
this.searchIterations++;
const e3 = this.ripCount[this.activeConnId] ?? 0, t2 = Math.round(this.baseSearchBudgetIters * (1 + 0.25 * Math.min(e3, 10)));
if (this.searchIterations > t2) {
const e4 = this.penalty2d;
for (let t3 = 0;t3 < e4.length; t3++)
e4[t3] = 0.9 * e4[t3];
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 = true));
}
if (this.heap.size === 0)
return this.error = `No path found for ${this.connIdToName[this.activeConnId]}`, void (this.failed = true);
const n2 = this.heap.pop(), o2 = this.nodePool[n2], { z: i2, row: r2, col: s2, g: a2, ripped: c2 } = o2, l2 = (i2 * this.rows + r2) * this.cols + s2;
if (this.visitedStamp[l2] === this.stamp)
return;
this.visitedStamp[l2] = this.stamp;
const h2 = this.activeConnSeg;
if (i2 === h2.endZ && r2 === h2.endRow && s2 === h2.endCol)
return this.finalizeRoute(n2), this.activeConnSeg = null, void (this.activeConnId = -1);
const { endZ: d2, endRow: u2, endCol: p2 } = h2, m2 = this.activeConnId, g2 = this.rows, f2 = this.cols, _2 = (this.cellSizeMm, this.visitedStamp), y2 = this.stamp;
for (let e4 = 0;e4 < 8; e4++) {
const t3 = r2 + Ci[e4], o3 = s2 + Pi[e4];
if (t3 < 0 || t3 >= g2 || o3 < 0 || o3 >= f2)
continue;
if (_2[(i2 * g2 + t3) * f2 + o3] === y2)
continue;
if (this.computeMoveCostAndRips(m2, i2, r2, s2, i2, t3, o3, c2), this._moveCost < 0)
continue;
const l3 = a2 + this._moveCost, h3 = l3 + this.computeH(i2, t3, o3, d2, u2, p2) * this.hyperParameters.greedyMultiplier, b2 = this.nodePool.length;
this.nodePool.push({ z: i2, row: t3, col: o3, g: l3, f: h3, parentIdx: n2, ripped: this._moveRipped }), this.heap.push(h3, this.seqCounter++, b2);
}
if (r2 >= this.minViaRow && r2 <= this.maxViaRow && s2 >= this.minViaCol && s2 <= this.maxViaCol)
for (let e4 = 0;e4 < this.layers; e4++) {
if (e4 === i2)
continue;
if (_2[(e4 * g2 + r2) * f2 + s2] === y2)
continue;
if (this.computeMoveCostAndRips(m2, i2, r2, s2, e4, r2, s2, c2), this._moveCost < 0)
continue;
const t3 = a2 + this._moveCost, o3 = t3 + this.computeH(e4, r2, s2, d2, u2, p2) * this.hyperParameters.greedyMultiplier, l3 = this.nodePool.length;
this.nodePool.push({ z: e4, row: r2, col: s2, g: t3, f: o3, parentIdx: n2, ripped: this._moveRipped }), this.heap.push(o3, this.seqCounter++, l3);
}
}
getRipCost(e3) {
return this.hyperParameters.ripCost * (1 + this.ripHistoryCostMultiplier * (this.ripCount[e3] ?? 0));
}
computeMoveCostAndRips(e3, t2, n2, o2, i2, r2, s2, a2) {
let c2 = 0, l2 = a2;
const h2 = this.cols;
if (t2 !== i2) {
c2 += this.hyperParameters.viaBaseCost, c2 += Math.min(this.penalty2d[r2 * h2 + s2], this.penaltyCap);
const t3 = (i2 * this.rows + r2) * h2 + s2, n3 = this.portOwnerFlat[t3], o3 = this.connIdToRootNet[n3] === this.connIdToRootNet[e3] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[e3]), a3 = this.activeConnSeg, d2 = !!a3 && i2 === a3.endZ && r2 === a3.endRow && s2 === a3.endCol;
if (n3 >= 0 && n3 !== e3 && !o3 && !d2)
return this._moveCost = -1, void (this._moveRipped = l2);
this.fillViaOccupants(r2, s2, e3);
const u2 = this._viaOccs;
for (let e4 = 0;e4 < u2.length; e4++) {
const t4 = u2[e4];
Ii(l2, t4) || (c2 += this.getRipCost(t4), l2 = { id: t4, prev: l2 }), c2 += this.hyperParameters.ripViaPenalty;
}
} else {
const t3 = n2 > r2 ? n2 - r2 : r2 - n2, a3 = o2 > s2 ? o2 - s2 : s2 - o2;
c2 += (t3 + a3 > 1 ? Math.SQRT2 : 1) * this.cellSizeMm, c2 += Math.min(this.penalty2d[r2 * h2 + s2], this.penaltyCap);
const d2 = (i2 * this.rows + r2) * h2 + s2, u2 = this.portOwnerFlat[d2], p2 = this.connIdToRootNet[u2] === this.connIdToRootNet[e3] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[e3]), m2 = this.activeConnSeg, g2 = !!m2 && i2 === m2.endZ && r2 === m2.endRow && s2 === m2.endCol;
if (u2 >= 0 && u2 !== e3 && !p2 && !g2)
return this._moveCost = -1, void (this._moveRipped = l2);
const f2 = this.usedCellsFlat[d2], _2 = this.connIdToRootNet[f2] === this.connIdToRootNet[e3] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[e3]);
if (f2 === -1 || f2 === e3 || _2 || (Ii(l2, f2) || (c2 += this.getRipCost(f2), l2 = { id: f2, prev: l2 }), c2 += this.hyperParameters.ripTracePenalty), this.viaOwnersByCell.size > 0) {
this.fillTraceSegmentViaOccupants(n2, o2, r2, s2, e3);
const t4 = this._viaOccs;
for (let e4 = 0;e4 < t4.length; e4++) {
const n3 = t4[e4];
Ii(l2, n3) || (c2 += this.getRipCost(n3), l2 = { id: n3, prev: l2 }), c2 += this.hyperParameters.ripViaPenalty;
}
}
if (t3 === 1 && a3 === 1) {
const t4 = n2 < r2 ? n2 : r2, a4 = o2 < s2 ? o2 : s2, c3 = 1 ^ (n2 < r2 && o2 < s2 || n2 > r2 && o2 > s2 ? 0 : 1), h3 = this.cols - 1, d3 = 2 * ((i2 * (this.rows - 1) + t4) * h3 + a4), u3 = this.usedDiagFlat[d3 + c3], p3 = this.connIdToRootNet[u3] === this.connIdToRootNet[e3] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[e3]);
if (u3 !== -1 && u3 !== e3 && !p3)
return this._moveCost = -1, void (this._moveRipped = l2);
}
}
this._moveCost = c2, this._moveRipped = l2;
}
fillViaOccupants(e3, t2, n2) {
const o2 = this._viaOccs;
o2.length = 0;
const i2 = e3 * this.cols + t2, r2 = this.viaOccupantsByCell.get(i2);
if (r2) {
for (const e4 of r2)
o2.push(e4);
return;
}
const s2 = this.rows, a2 = this.cols, c2 = this.viaOccupantScanOffsetsDr, l2 = this.viaOccupantScanOffsetsDc, h2 = this.viaOccupantScanOffsetsLen, d2 = this.usedCellsFlat;
for (let i3 = 0;i3 < this.layers; i3++) {
const r3 = i3 * this.planeSize;
for (let i4 = 0;i4 < h2; i4++) {
const h3 = e3 + c2[i4], u2 = t2 + l2[i4];
if (h3 < 0 || u2 < 0 || h3 >= s2 || u2 >= a2)
continue;
const p2 = d2[r3 + h3 * a2 + u2];
if (p2 === -1 || p2 === n2)
continue;
if (this.connIdToRootNet[p2] === this.connIdToRootNet[n2] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[n2]))
continue;
let m2 = false;
for (let e4 = 0;e4 < o2.length; e4++)
if (o2[e4] === p2) {
m2 = true;
break;
}
m2 || o2.push(p2);
}
}
this.viaOccupantsByCell.set(i2, o2.slice());
}
fillTraceSegmentViaOccupants(e3, t2, n2, o2, i2) {
const r2 = this._viaOccs;
r2.length = 0;
const s2 = Math.min(e3, n2), a2 = Math.max(e3, n2), c2 = Math.min(t2, o2), l2 = Math.max(t2, o2), h2 = this.viaTraceClearanceMm / this.outputCellStepY, d2 = this.viaTraceClearanceMm / this.outputCellStepX, u2 = (o2 - t2) * this.outputCellStepX, p2 = (n2 - e3) * this.outputCellStepY, m2 = u2 * u2 + p2 * p2, g2 = this.viaTraceClearanceMm * this.viaTraceClearanceMm;
for (const [n3, o3] of this.viaOwnersByCell) {
const f2 = Math.floor(n3 / this.cols), _2 = n3 - f2 * this.cols;
if (f2 < s2 - h2 || f2 > a2 + h2 || _2 < c2 - d2 || _2 > l2 + d2)
continue;
const y2 = (_2 - t2) * this.outputCellStepX, b2 = (f2 - e3) * this.outputCellStepY, x2 = m2 === 0 ? 0 : Math.max(0, Math.min(1, (y2 * u2 + b2 * p2) / m2)), v2 = y2 - u2 * x2, I2 = b2 - p2 * x2;
if (!(v2 * v2 + I2 * I2 >= g2))
for (const e4 of o3) {
if (e4 === i2)
continue;
this.connIdToRootNet[e4] === this.connIdToRootNet[i2] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[i2]) || (r2.includes(e4) || r2.push(e4));
}
}
}
shouldSkipFixedPortHalo(e3, t2) {
const n2 = this.portOwnerFlat[e3];
if (n2 === t2)
return false;
if (n2 === -2)
return true;
if (n2 < 0)
return false;
return !(this.connIdToRootNet[n2] === this.connIdToRootNet[t2] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[t2]));
}
nextStamp() {
this.stamp = this.stamp + 1 >>> 0, this.stamp === 0 && (this.visitedStamp.fill(0), this.stamp = 1);
}
computeH(e3, t2, n2, o2, i2, r2) {
const s2 = Math.abs(t2 - i2) + Math.abs(n2 - r2);
if (e3 === o2)
return s2 * this.cellSizeMm;
if (!this.crossLayerSearch)
return s2 * this.cellSizeMm + this.hyperParameters.viaBaseCost;
const a2 = Math.max(this.minViaRow, Math.min(this.maxViaRow, t2)), c2 = Math.max(this.minViaCol, Math.min(this.maxViaCol, n2)), l2 = Math.max(this.minViaRow, Math.min(this.maxViaRow, i2)), h2 = Math.max(this.minViaCol, Math.min(this.maxViaCol, r2)), d2 = Math.abs(t2 - a2) + Math.abs(n2 - c2) + Math.abs(a2 - i2) + Math.abs(c2 - r2), u2 = Math.abs(t2 - l2) + Math.abs(n2 - h2) + Math.abs(l2 - i2) + Math.abs(h2 - r2);
return Math.max(Math.min(d2, u2), s2) * this.cellSizeMm + this.hyperParameters.viaBaseCost;
}
internConn(e3, t2) {
const n2 = this.connNameToId.get(e3);
if (n2 !== undefined)
return n2;
const o2 = this.connIdToName.length;
var i2;
return this.connIdToName.push(e3), this.connIdToRootNet.push((i2 = e3, t2 ?? i2.replace(/_mst\d+$/, ""))), this.connNameToId.set(e3, o2), o2;
}
buildConnectionSegs() {
const e3 = new Map;
for (const t3 of this.nodeWithPortPoints.portPoints) {
const n3 = t3.connectionName;
e3.has(n3) || e3.set(n3, { points: [], rootConnectionName: t3.rootConnectionName }), e3.get(n3).points.push(t3);
}
const t2 = [], n2 = new Set;
for (const [o2, i2] of e3) {
const e4 = i2.points, r2 = bi(e4);
if (r2.length === 0)
continue;
const s2 = this.internConn(o2, i2.rootConnectionName);
for (const [e5, a2] of r2) {
const r3 = this.pointToCell(e5), c2 = this.pointToCell(a2), l2 = `${r3.z}:${r3.row}:${r3.col}`, h2 = `${c2.z}:${c2.row}:${c2.col}`, d2 = l2 < h2 ? `${l2}|${h2}` : `${h2}|${l2}`, u2 = i2.rootConnectionName ?? o2, p2 = `${u2}|${d2}`;
n2.has(p2) ? this.overlapFriendlyRootNets.add(u2) : (n2.add(p2), t2.push({ connId: s2, startZ: r3.z, startRow: r3.row, startCol: r3.col, startPoint: e5, endZ: c2.z, endRow: c2.row, endCol: c2.col, endPoint: a2 }));
}
}
return t2;
}
pointToCell(e3) {
const t2 = Math.max(0, Math.min(this.cols - 1, Math.round((e3.x - this.gridOrigin.x) / this.cellSizeMm - 0.5))), n2 = Math.max(0, Math.min(this.rows - 1, Math.round((e3.y - this.gridOrigin.y) / this.cellSizeMm - 0.5)));
return { z: this.zToLayer.get(e3.z) ?? 0, row: n2, col: t2 };
}
shuffleConnections() {
const e3 = this.unsolvedSegs;
let t2 = this.hyperParameters.shuffleSeed;
const n2 = () => (t2 = 1664525 * t2 + 1013904223 & 4294967295, (t2 >>> 0) / 4294967295);
for (let t3 = e3.length - 1;t3 > 0; t3--) {
const o2 = Math.floor(n2() * (t3 + 1)), i2 = e3[t3];
e3[t3] = e3[o2], e3[o2] = i2;
}
}
finalizeRoute(e3) {
this.consecutiveSkips = Math.max(0, this.consecutiveSkips - 1);
const t2 = [];
let n2 = e3;
for (;n2 >= 0; ) {
const e4 = this.nodePool[n2];
t2.push({ z: e4.z, row: e4.row, col: e4.col }), n2 = e4.parentIdx;
}
for (t2.reverse();t2.length > 1; ) {
const e4 = t2[0], n3 = (e4.z * this.rows + e4.row) * this.cols + e4.col;
if (!this.sharedCrossRootPortCells.has(n3))
break;
t2.shift();
}
for (;t2.length > 1; ) {
const e4 = t2[t2.length - 1], n3 = (e4.z * this.rows + e4.row) * this.cols + e4.col;
if (!this.sharedCrossRootPortCells.has(n3))
break;
t2.pop();
}
const o2 = [];
for (let e4 = 1;e4 < t2.length; e4++)
t2[e4].z !== t2[e4 - 1].z && o2.push({ row: t2[e4].row, col: t2[e4].col });
const i2 = t2[0], r2 = t2[t2.length - 1], s2 = this.activeConnId, a2 = [];
for (let t3 = this.nodePool[e3].ripped;t3; t3 = t3.prev)
a2.push(t3.id);
for (let e4 = 0;e4 < a2.length; e4++)
if (this.ripTrace(a2[e4]), this.failed)
return;
const c2 = Math.ceil(this.traceMargin / this.cellSizeMm), l2 = [], h2 = this.rows, d2 = this.cols, u2 = this.usedCellsFlat;
for (let e4 = 0;e4 < t2.length; e4++) {
const n3 = t2[e4];
for (let e5 = -c2;e5 <= c2; e5++)
for (let t3 = -c2;t3 <= c2; t3++) {
const o3 = n3.row + e5, i3 = n3.col + t3;
if (o3 < 0 || o3 >= h2 || i3 < 0 || i3 >= d2)
continue;
const r3 = (n3.z * h2 + o3) * d2 + i3;
if ((o3 !== n3.row || i3 !== n3.col) && this.shouldSkipFixedPortHalo(r3, s2))
continue;
const a3 = u2[r3], c3 = this.connIdToRootNet[a3] === this.connIdToRootNet[s2] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[s2]);
(a3 === -1 || a3 === s2 || c3) && (u2[r3] = s2, l2.push(r3));
}
}
const p2 = [], m2 = this.viaOccupantScanOffsetsDr, g2 = this.viaOccupantScanOffsetsDc, f2 = this.viaOccupantScanOffsetsLen;
for (let e4 = 0;e4 < o2.length; e4++) {
const t3 = o2[e4];
for (let e5 = 0;e5 < this.layers; e5++) {
const n3 = e5 * this.planeSize;
for (let e6 = 0;e6 < f2; e6++) {
const o3 = t3.row + m2[e6], i3 = t3.col + g2[e6];
if (o3 < 0 || o3 >= h2 || i3 < 0 || i3 >= d2)
continue;
const r3 = n3 + o3 * d2 + i3;
if ((o3 !== t3.row || i3 !== t3.col) && this.shouldSkipFixedPortHalo(r3, s2))
continue;
const a3 = u2[r3], c3 = this.connIdToRootNet[a3] === this.connIdToRootNet[s2] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[s2]);
if (a3 !== -1 && a3 !== s2 && !c3) {
let e7 = false;
for (let t4 = 0;t4 < p2.length; t4++)
if (p2[t4] === a3) {
e7 = true;
break;
}
e7 || p2.push(a3);
}
u2[r3] = s2, l2.push(r3);
}
}
}
const _2 = [], y2 = this.cols - 1;
for (let e4 = 1;e4 < t2.length; e4++) {
const n3 = t2[e4 - 1], o3 = t2[e4];
if (n3.z !== o3.z)
continue;
const i3 = n3.row > o3.row ? n3.row - o3.row : o3.row - n3.row, r3 = n3.col > o3.col ? n3.col - o3.col : o3.col - n3.col;
if (i3 !== 1 || r3 !== 1)
continue;
const a3 = n3.row < o3.row ? n3.row : o3.row, c3 = n3.col < o3.col ? n3.col : o3.col, l3 = n3.row < o3.row && n3.col < o3.col || n3.row > o3.row && n3.col > o3.col ? 0 : 1, h3 = 1 ^ l3, d3 = 2 * ((n3.z * (this.rows - 1) + a3) * y2 + c3), u3 = d3 + h3, p3 = this.usedDiagFlat[u3], m3 = this.connIdToRootNet[p3] === this.connIdToRootNet[s2] && this.overlapFriendlyRootNets.has(this.connIdToRootNet[s2]);
if (p3 !== -1 && p3 !== s2 && !m3)
continue;
const g3 = d3 + l3;
this.usedDiagFlat[g3] = s2, _2.push(g3);
}
for (;this.usedIndicesByConn.length <= s2; )
this.usedIndicesByConn.push([]);
const b2 = this.usedIndicesByConn[s2] ?? [];
for (b2.push(...l2), this.usedIndicesByConn[s2] = b2;this.usedDiagIndicesByConn.length <= s2; )
this.usedDiagIndicesByConn.push([]);
const x2 = this.usedDiagIndicesByConn[s2] ?? [];
x2.push(..._2), this.usedDiagIndicesByConn[s2] = x2;
const v2 = this.solvedRoutes.get(s2) ?? [];
if (v2.push({ connId: s2, startZ: i2.z, startRow: i2.row, startCol: i2.col, startPoint: this.activeConnSeg.startPoint, endZ: r2.z, endRow: r2.row, endCol: r2.col, endPoint: this.activeConnSeg.endPoint, cells: t2, viaCells: o2 }), this.solvedRoutes.set(s2, v2), this.useExactViaTraceClearance) {
for (;this.viaCenterIndicesByConn.length <= s2; )
this.viaCenterIndicesByConn.push([]);
const e4 = this.viaCenterIndicesByConn[s2] ?? [];
for (const t3 of o2) {
const n3 = t3.row * this.cols + t3.col, o3 = this.viaOwnersByCell.get(n3) ?? new Set;
o3.has(s2) || (o3.add(s2), e4.push(n3)), this.viaOwnersByCell.set(n3, o3);
}
this.viaCenterIndicesByConn[s2] = e4;
}
for (let e4 = 0;e4 < p2.length; e4++)
if (this.ripTrace(p2[e4]), this.failed)
return;
if (a2.length > 0 || p2.length > 0) {
const e4 = this.penalty2d, t3 = this.penaltyCap;
if (this.totalRipEvents > 50)
for (let t4 = 0;t4 < e4.length; t4++)
e4[t4] = 0.99 * e4[t4];
else
for (let n3 = 0;n3 < e4.length; n3++)
e4[n3] > t3 && (e4[n3] = 0.5 * e4[n3]);
}
}
ripTrace(e3) {
for (;this.ripCount.length <= e3; )
this.ripCount.push(0);
if (this.ripCount[e3]++, this.totalRipEvents++, this.totalRipEvents >= this.MAX_RIPS)
return this.error = `Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`, void (this.failed = true);
const t2 = this.solvedRoutes.get(e3) ?? [];
if (t2.length > 0) {
const e4 = this.cols;
for (const n3 of t2) {
for (let t3 = 0;t3 < n3.cells.length; t3++) {
const o3 = n3.cells[t3], i3 = o3.row * e4 + o3.col;
this.penalty2d[i3] = this.penalty2d[i3] + this.hyperParameters.ripTracePenalty;
}
for (let t3 = 0;t3 < n3.viaCells.length; t3++) {
const o3 = n3.viaCells[t3], i3 = o3.row * e4 + o3.col;
this.penalty2d[i3] = this.penalty2d[i3] + this.hyperParameters.ripViaPenalty;
}
}
}
const n2 = this.usedIndicesByConn[e3];
if (n2) {
const t3 = this.usedCellsFlat;
for (let o3 = 0;o3 < n2.length; o3++) {
const i3 = n2[o3];
t3[i3] === e3 && (t3[i3] = -1);
}
this.usedIndicesByConn[e3] = [];
}
const o2 = this.usedDiagIndicesByConn[e3];
if (o2) {
const t3 = this.usedDiagFlat;
for (let n3 = 0;n3 < o2.length; n3++) {
const i3 = o2[n3];
t3[i3] === e3 && (t3[i3] = -1);
}
this.usedDiagIndicesByConn[e3] = [];
}
const i2 = this.viaCenterIndicesByConn[e3];
if (i2) {
for (const t3 of i2) {
const n3 = this.viaOwnersByCell.get(t3);
n3 && (n3.delete(e3), n3.size === 0 && this.viaOwnersByCell.delete(t3));
}
this.viaCenterIndicesByConn[e3] = [];
}
if (t2.length > 0) {
this.solvedRoutes.delete(e3);
for (const n3 of t2)
this.unsolvedSegs.push({ connId: e3, startZ: n3.startZ, startRow: n3.startRow, startCol: n3.startCol, startPoint: n3.startPoint, endZ: n3.endZ, endRow: n3.endRow, endCol: n3.endCol, endPoint: n3.endPoint });
}
}
visualize() {
const e3 = ["red", "blue", "orange", "green"], t2 = [], n2 = [], o2 = [], i2 = [], { width: r2, height: s2, center: a2 } = this.nodeWithPortPoints;
i2.push({ center: { x: a2.x, y: a2.y }, width: r2, height: s2, stroke: "gray" });
const c2 = this.gridToBoundsTransform;
if (this.showPenaltyMap && this.penalty2d) {
let e4 = 0;
for (let t3 = 0;t3 < this.penalty2d.length; t3++)
this.penalty2d[t3] > e4 && (e4 = this.penalty2d[t3]);
if (e4 > 0)
for (let t3 = 0;t3 < this.rows; t3++)
for (let n3 = 0;n3 < this.cols; n3++) {
const o3 = this.penalty2d[t3 * this.cols + n3];
if (o3 <= 0)
continue;
const r3 = Math.min(0.6, o3 / e4 * 0.6), s3 = fi(c2, { x: this.gridOrigin.x + (n3 + 0.5) * this.cellSizeMm, y: this.gridOrigin.y + (t3 + 0.5) * this.cellSizeMm });
i2.push({ center: s3, width: this.cellSizeMm * c2.a, height: this.cellSizeMm * c2.e, fill: `rgba(255,165,0,${r3.toFixed(3)})` });
}
}
if (this.showUsedCellMap && this.usedCellsFlat)
for (let e4 = 0;e4 < this.layers; e4++)
for (let t3 = 0;t3 < this.rows; t3++)
for (let n3 = 0;n3 < this.cols; n3++) {
if (this.usedCellsFlat[(e4 * this.rows + t3) * this.cols + n3] === -1)
continue;
const o3 = fi(c2, { x: this.gridOrigin.x + (n3 + 0.5) * this.cellSizeMm, y: this.gridOrigin.y + (t3 + 0.5) * this.cellSizeMm });
i2.push({ center: o3, width: this.cellSizeMm * c2.a, height: this.cellSizeMm * c2.e, fill: "rgba(0,0,255,0.5)" });
}
for (const n3 of this.nodeWithPortPoints.portPoints)
t2.push({ x: n3.x, y: n3.y, color: e3[n3.z] ?? "gray", label: n3.connectionName });
const l2 = ["rgba(255,0,0,0.75)", "rgba(0,0,255,0.75)", "rgba(255,165,0,0.75)", "rgba(0,128,0,0.75)"], h2 = this.getOutput();
for (const e4 of h2) {
if (e4.route.length < 2)
continue;
let t3 = 0;
for (let o3 = 1;o3 < e4.route.length; o3++) {
const i3 = e4.route[o3 - 1];
e4.route[o3].z !== i3.z && (o3 - t3 >= 2 && n2.push({ points: e4.route.slice(t3, o3).map((e5) => ({ x: e5.x, y: e5.y })), strokeColor: l2[i3.z] ?? "rgba(128,128,128,0.75)", strokeWidth: this.traceThickness }), t3 = o3);
}
if (e4.route.length - t3 >= 2) {
const o3 = e4.route[t3].z;
n2.push({ points: e4.route.slice(t3).map((e5) => ({ x: e5.x, y: e5.y })), strokeColor: l2[o3] ?? "rgba(128,128,128,0.75)", strokeWidth: this.traceThickness });
}
}
for (const e4 of h2)
for (const t3 of e4.vias)
o2.push({ center: { x: t3.x, y: t3.y }, radius: this.viaDiameter / 2, fill: "rgba(0,0,0,0.3)", stroke: "black" });
if (this.activeConnSeg && this.visitedStamp) {
const e4 = this.stamp;
for (let n3 = 0;n3 < this.layers; n3++)
for (let o3 = 0;o3 < this.rows; o3++)
for (let i3 = 0;i3 < this.cols; i3++) {
if (this.visitedStamp[(n3 * this.rows + o3) * this.cols + i3] !== e4)
continue;
const r3 = fi(c2, { x: this.gridOrigin.x + (i3 + 0.5) * this.cellSizeMm, y: this.gridOrigin.y + (o3 + 0.5) * this.cellSizeMm });
t2.push({ x: r3.x, y: r3.y, color: "rgba(0,0,255,0.2)" });
}
}
return { points: t2, lines: n2, circles: o2, rects: i2, coordinateSystem: "cartesian", title: `HighDensityA01 [${this.solvedRoutes?.size ?? 0} solved, ${this.unsolvedSegs?.length ?? 0} remaining]` };
}
getOutput() {
const e3 = this.gridToBoundsTransform, t2 = [];
for (const [n2, o2] of this.solvedRoutes ?? []) {
const i2 = this.connIdToName[n2];
for (const r2 of o2) {
const o3 = r2.cells.map((t3) => {
const n3 = this.gridOrigin.x + (t3.col + 0.5) * this.cellSizeMm, o4 = this.gridOrigin.y + (t3.row + 0.5) * this.cellSizeMm, i3 = fi(e3, { x: n3, y: o4 });
return { x: i3.x, y: i3.y, z: this.layerToZ.get(t3.z) ?? t3.z };
});
o3.length > 0 && (o3[0] = { ...r2.startPoint }, o3.length > 1 && (o3[o3.length - 1] = { ...r2.endPoint })), t2.push({ connectionName: i2, rootConnectionName: this.connIdToRootNet[n2], regionId: this.nodeWithPortPoints.capacityMeshNodeId, traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, route: o3, vias: r2.viaCells.map((t3) => {
const n3 = this.gridOrigin.x + (t3.col + 0.5) * this.cellSizeMm, o4 = this.gridOrigin.y + (t3.row + 0.5) * this.cellSizeMm;
return fi(e3, { x: n3, y: o4 });
}) });
}
}
return t2;
}
};
var wi = ["left", "top", "right", "bottom", "middle"];
var Ni = class {
f = new Float64Array(1024);
seq = new Uint32Array(1024);
id = new Int32Array(1024);
n = 0;
push(e3, t2, n2) {
this.ensureCapacity(this.n + 1);
let o2 = this.n++;
for (this.f[o2] = e3, this.seq[o2] = t2, this.id[o2] = n2;o2 > 0; ) {
const e4 = o2 - 1 >> 1;
if (this.less(e4, o2))
break;
this.swap(o2, e4), o2 = e4;
}
}
pop() {
const e3 = 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)), e3;
}
get size() {
return this.n;
}
clear() {
this.n = 0;
}
ensureCapacity(e3) {
if (e3 <= this.f.length)
return;
let t2 = this.f.length;
for (;t2 < e3; )
t2 *= 2;
const n2 = new Float64Array(t2);
n2.set(this.f), this.f = n2;
const o2 = new Uint32Array(t2);
o2.set(this.seq), this.seq = o2;
const i2 = new Int32Array(t2);
i2.set(this.id), this.id = i2;
}
siftDown(e3) {
for (;; ) {
const t2 = 2 * e3 + 1, n2 = t2 + 1;
if (t2 >= this.n)
return;
let o2 = t2;
if (n2 < this.n && !this.less(t2, n2) && (o2 = n2), this.less(e3, o2))
return;
this.swap(e3, o2), e3 = o2;
}
}
less(e3, t2) {
const n2 = this.f[e3], o2 = this.f[t2];
return n2 !== o2 ? n2 < o2 : this.seq[e3] < this.seq[t2];
}
swap(e3, t2) {
const n2 = this.f[e3];
this.f[e3] = this.f[t2], this.f[t2] = n2;
const o2 = this.seq[e3];
this.seq[e3] = this.seq[t2], this.seq[t2] = o2;
const i2 = this.id[e3];
this.id[e3] = this.id[t2], this.id[t2] = i2;
}
};
var Ti = 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(e3, t2, n2, o2, i2, r2) {
this.ensureCapacity(this.length + 1);
const s2 = this.length++;
return this.z[s2] = e3, this.cellId[s2] = t2, this.g[s2] = n2, this.parent[s2] = o2, this.ripHead[s2] = i2, this.ripCount[s2] = r2, s2;
}
ensureCapacity(e3) {
if (e3 <= this.z.length)
return;
let t2 = this.z.length;
for (;t2 < e3; )
t2 *= 2;
const n2 = new Int32Array(t2);
n2.set(this.z), this.z = n2;
const o2 = new Int32Array(t2);
o2.set(this.cellId), this.cellId = o2;
const i2 = new Float64Array(t2);
i2.set(this.g), this.g = i2;
const r2 = new Int32Array(t2);
r2.set(this.parent), this.parent = r2;
const s2 = new Int32Array(t2);
s2.fill(-1), s2.set(this.ripHead.subarray(0, this.length)), this.ripHead = s2;
const a2 = new Int32Array(t2);
a2.set(this.ripCount.subarray(0, this.length)), this.ripCount = a2;
}
};
var Ri = class {
connId = new Int32Array(1024);
prev = new Int32Array(1024).fill(-1);
length = 0;
clear() {
this.length = 0;
}
append(e3, t2) {
this.ensureCapacity(this.length + 1);
const n2 = this.length++;
return this.connId[n2] = t2, this.prev[n2] = e3, n2;
}
contains(e3, t2) {
for (let n2 = e3;n2 >= 0; n2 = this.prev[n2])
if (this.connId[n2] === t2)
return true;
return false;
}
collect(e3, t2) {
t2.length = 0;
for (let n2 = e3;n2 >= 0; n2 = this.prev[n2])
t2.push(this.connId[n2]);
}
ensureCapacity(e3) {
if (e3 <= this.connId.length)
return;
let t2 = this.connId.length;
for (;t2 < e3; )
t2 *= 2;
const n2 = new Int32Array(t2);
n2.set(this.connId), this.connId = n2;
const o2 = new Int32Array(t2);
o2.fill(-1), o2.set(this.prev.subarray(0, this.length)), this.prev = o2;
}
};
function Ei(e3, t2, n2) {
return Math.max(t2, Math.min(n2, e3));
}
function Ai(e3, t2) {
for (let n2 = 0;n2 < e3.length; n2++)
if (e3[n2] === t2)
return;
e3.push(t2);
}
function Oi(e3, t2) {
for (let n2 = 0;n2 < e3.length; n2++)
if (e3[n2].cellId === t2.cellId)
return;
e3.push(t2);
}
function ki(e3, t2, n2, o2, i2, r2, s2) {
const a2 = e3 - Ei(e3, o2, r2), c2 = t2 - Ei(t2, i2, s2);
return a2 * a2 + c2 * c2 <= n2 * n2;
}
var Di;
var Li = class extends De {
getSolverName() {
return "HighDensitySolverA03";
}
nodeWithPortPoints;
highResolutionCellSize;
highResolutionCellThickness;
lowResolutionCellSize;
viaDiameter;
MAX_RIPS;
maxCellCount;
traceThickness;
traceMargin;
viaMinDistFromBorder;
showPenaltyMap;
showUsedCellMap;
effort;
enableDiagonalMoves;
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 = [];
viaOccupantsByCell = new Map;
_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 e3 = new Map;
for (let t2 = 0;t2 < this.solvedRoutes.length; t2++) {
const n2 = this.getSolvedRoutesForConn(t2);
n2.length > 0 && e3.set(t2, n2);
}
return e3;
}
get activeConnection() {
if (!this.activeConnSeg)
return null;
const e3 = this.activeConnSeg.startCellId, t2 = this.activeConnSeg.endCellId;
return { connectionName: this.connIdToName[this.activeConnSeg.connId] ?? "", start: { cellId: e3, region: wi[this.cellRegion[e3]], row: this.cellRow[e3], col: this.cellCol[e3], x: this.cellCenterX[e3], y: this.cellCenterY[e3], z: this.activeConnSeg.startZ }, end: { cellId: t2, region: wi[this.cellRegion[t2]], row: this.cellRow[t2], col: this.cellCol[t2], x: this.cellCenterX[t2], y: this.cellCenterY[t2], 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((e3) => [e3.name, e3.rows * e3.cols])) : {} };
}
constructor(e3) {
super(), this.nodeWithPortPoints = e3.nodeWithPortPoints, this.highResolutionCellSize = e3.highResolutionCellSize ?? 0.1, this.highResolutionCellThickness = Math.max(1, Math.floor(e3.highResolutionCellThickness ?? 8)), this.lowResolutionCellSize = e3.lowResolutionCellSize ?? 0.4, this.viaDiameter = e3.viaDiameter, this.maxCellCount = e3.maxCellCount, this.traceThickness = e3.traceThickness ?? 0.1, this.traceMargin = e3.traceMargin ?? 0.15, this.viaMinDistFromBorder = e3.viaMinDistFromBorder ?? 0.15, this.showPenaltyMap = e3.showPenaltyMap ?? false, this.showUsedCellMap = e3.showUsedCellMap ?? false, this.effort = e3.effort ?? 1, this.enableDiagonalMoves = e3.enableDiagonalMoves ?? false, this.stepMultiplier = Math.max(1, Math.floor(e3.stepMultiplier ?? 1)), this.hyperParameters = { shuffleSeed: 0, ripCost: 8, ripTracePenalty: 0.5, ripViaPenalty: 0.75, viaBaseCost: 0.1, greedyMultiplier: 1.5, ...e3.hyperParameters }, this.MAX_ITERATIONS = 1e8, this.MAX_RIPS = 200, this.initialPenaltyFn = e3.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, enableDiagonalMoves: this.enableDiagonalMoves, hyperParameters: this.hyperParameters, initialPenaltyFn: this.initialPenaltyFn }];
}
_setup() {
const { nodeWithPortPoints: e3 } = this, { width: t2, height: n2, center: o2 } = e3, i2 = this.lowResolutionCellSize / this.highResolutionCellSize, r2 = Math.round(i2);
if (!Number.isFinite(i2) || i2 <= 0 || Math.abs(i2 - r2) > 0.000000001)
return this.error = "lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize", void (this.failed = true);
this.lowScale = Math.max(1, r2), this.availableZ = e3.availableZ ?? [...new Set(e3.portPoints.map((e4) => e4.z))].sort((e4, t3) => e4 - t3), this.layers = this.availableZ.length, this.zToLayer = new Map, this.layerToZ = new Map;
for (let e4 = 0;e4 < this.availableZ.length; e4++) {
const t3 = this.availableZ[e4];
this.zToLayer.set(t3, e4), this.layerToZ.set(e4, t3);
}
this.boundsMinX = o2.x - t2 / 2, this.boundsMaxX = o2.x + t2 / 2, this.boundsMinY = o2.y - n2 / 2, this.boundsMaxY = o2.y + n2 / 2, this.traceKeepoutRadius = this.traceMargin + this.traceThickness / 2, this.viaKeepoutRadius = this.viaDiameter / 2 + this.traceKeepoutRadius, this.buildFiveRegionGrid(t2, n2), this.gridToBoundsTransform = this.computeGridToBoundsTransform();
const s2 = this.layers * this.planeSize;
if (this.maxCellCount !== undefined && s2 > this.maxCellCount)
return this.error = `Cell count ${s2} exceeds maxCellCount ${this.maxCellCount}`, void (this.failed = true);
this.connNameToId = new Map, this.connIdToName = [], this.connIdToRootNet = [], this.overlapFriendlyRootNets = new Set, this.unsolvedSegs = this.buildConnectionSegs(), this.penalty2d = new Float64Array(this.planeSize);
const a2 = t2 > 0 ? 1 / t2 : 0, c2 = n2 > 0 ? 1 / n2 : 0;
for (let e4 = 0;e4 < this.planeSize; e4++) {
let t3 = 0;
this.initialPenaltyFn && (t3 += this.initialPenaltyFn({ x: this.cellCenterX[e4], y: this.cellCenterY[e4], px: (this.cellCenterX[e4] - this.boundsMinX) * a2, py: (this.cellCenterY[e4] - this.boundsMinY) * c2, cellId: e4, region: wi[this.cellRegion[e4]], row: this.cellRow[e4], col: this.cellCol[e4] })), this.penalty2d[e4] = t3;
}
this.usedCellsFlat = new Int32Array(s2).fill(-1), this.sharedCellsFlat = Array.from({ length: s2 }, () => {}), this.portOwnerFlat = new Int32Array(s2).fill(-1), this.sharedCrossRootPortFlat = new Uint8Array(s2), this.ripStateBuckets = 1;
const l2 = s2;
this.visitedStamp = new Uint32Array(l2), this.bestGStamp = new Uint32Array(l2), this.bestGValue = new Float64Array(l2), this.visitedFlatStamp = new Uint32Array(s2), this.stamp = 0;
const h2 = new Map;
for (const e4 of this.nodeWithPortPoints.portPoints) {
const t3 = this.connNameToId.get(e4.connectionName);
if (t3 === undefined)
continue;
const n3 = this.pointToCell(e4), o3 = n3.z * this.planeSize + n3.cellId, i3 = this.connIdToRootNet[t3], r3 = h2.get(o3);
r3 === undefined ? h2.set(o3, i3) : r3 !== i3 && (this.sharedCrossRootPortFlat[o3] = 1);
const s3 = this.portOwnerFlat[o3];
this.portOwnerFlat[o3] = s3 === -1 || s3 === t3 ? t3 : -2;
}
this.solvedRoutes = [], this.usedIndicesByConn = [], this.ripCount = [], this.consecutiveSkips = 0, this.penaltyCap = 0.5 * this.hyperParameters.ripCost, this.shuffleConnections();
const d2 = vi({ planeSize: this.planeSize, layers: this.layers, connectionCount: this.unsolvedSegs.length, effort: this.effort, maxIterations: this.MAX_ITERATIONS });
this.baseSearchBudgetIters = d2.baseSearchBudgetIters, this.MAX_ITERATIONS = d2.maxIterationsIters, this.activeConnSeg = null, this.activeConnId = -1, this.nodePool = new Ti, this.heap = new Ni, this.ripChain = new Ri, this.seqCounter = 0;
}
_step() {
for (let e3 = 0;e3 < this.stepMultiplier; e3++) {
if (this.solved || this.failed)
return;
this.stepOnce();
}
}
buildFiveRegionGrid(e3, t2) {
this.fineCols = Math.max(1, Math.ceil(e3 / this.highResolutionCellSize)), this.fineRows = Math.max(1, Math.ceil(t2 / 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 n2 = Math.max(0, this.fineCols - 2 * this.bandCols), o2 = Math.max(0, this.fineRows - 2 * this.bandRows), i2 = n2, r2 = n2;
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: i2, cellScale: 1, rows: this.bandRows, cols: i2, 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: r2, cellScale: 1, rows: this.bandRows, cols: r2, offset: 0 }, { id: 4, name: "middle", fineOriginRow: this.bandRows, fineOriginCol: this.bandCols, fineRows: o2, fineCols: n2, cellScale: this.lowScale, rows: o2 > 0 ? Math.ceil(o2 / this.lowScale) : 0, cols: n2 > 0 ? Math.ceil(n2 / this.lowScale) : 0, offset: 0 }];
let s2 = 0;
for (let e4 = 0;e4 < this.regions.length; e4++)
this.regions[e4].offset = s2, s2 += this.regions[e4].rows * this.regions[e4].cols;
this.planeSize = s2, 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 e4 = 0;e4 < this.regions.length; e4++) {
const t3 = this.regions[e4];
for (let e5 = 0;e5 < t3.rows; e5++) {
const n3 = t3.fineOriginRow + e5 * t3.cellScale, o3 = Math.min(t3.fineOriginRow + t3.fineRows, n3 + t3.cellScale), i3 = this.boundsMinY + n3 * this.highResolutionCellSize, r3 = Math.min(this.boundsMaxY, this.boundsMinY + o3 * this.highResolutionCellSize);
for (let n4 = 0;n4 < t3.cols; n4++) {
const o4 = t3.fineOriginCol + n4 * t3.cellScale, s3 = Math.min(t3.fineOriginCol + t3.fineCols, o4 + t3.cellScale), a3 = this.boundsMinX + o4 * this.highResolutionCellSize, c3 = Math.min(this.boundsMaxX, this.boundsMinX + s3 * this.highResolutionCellSize), l3 = this.cellIdFor(t3.id, e5, n4);
this.cellCenterX[l3] = (a3 + c3) / 2, this.cellCenterY[l3] = (i3 + r3) / 2, this.cellMinX[l3] = a3, this.cellMinY[l3] = i3, this.cellMaxX[l3] = c3, this.cellMaxY[l3] = r3, this.cellWidth[l3] = c3 - a3, this.cellHeight[l3] = r3 - i3, this.cellRegion[l3] = t3.id, this.cellRow[l3] = e5, this.cellCol[l3] = n4;
const h3 = Math.min(this.cellCenterX[l3] - this.boundsMinX, this.boundsMaxX - this.cellCenterX[l3], this.cellCenterY[l3] - this.boundsMinY, this.boundsMaxY - this.cellCenterY[l3]);
this.viaAllowed[l3] = h3 >= this.viaMinDistFromBorder ? 1 : 0;
}
}
}
const a2 = Array.from({ length: this.planeSize }, () => []), c2 = (e4, t3) => {
if (e4 === t3 || e4 < 0 || t3 < 0)
return;
const n3 = this.cellCenterX[e4] - this.cellCenterX[t3], o3 = this.cellCenterY[e4] - this.cellCenterY[t3], i3 = Math.hypot(n3, o3);
Oi(a2[e4], { cellId: t3, cost: i3 }), Oi(a2[t3], { cellId: e4, cost: i3 });
};
for (let e4 = 0;e4 < this.regions.length; e4++) {
const t3 = this.regions[e4];
for (let e5 = 0;e5 < t3.rows; e5++)
for (let n3 = 0;n3 < t3.cols; n3++) {
const o3 = this.cellIdFor(t3.id, e5, n3);
e5 + 1 < t3.rows && c2(o3, this.cellIdFor(t3.id, e5 + 1, n3)), n3 + 1 < t3.cols && c2(o3, this.cellIdFor(t3.id, e5, n3 + 1)), this.enableDiagonalMoves && e5 + 1 < t3.rows && (n3 + 1 < t3.cols && c2(o3, this.cellIdFor(t3.id, e5 + 1, n3 + 1)), n3 > 0 && c2(o3, this.cellIdFor(t3.id, e5 + 1, n3 - 1)));
}
}
const l2 = this.regions[0], h2 = this.regions[1], d2 = this.regions[2], u2 = this.regions[3], p2 = this.regions[4], m2 = l2.rows > 0 && l2.cols > 0, g2 = h2.rows > 0 && h2.cols > 0, f2 = d2.rows > 0 && d2.cols > 0, _2 = u2.rows > 0 && u2.cols > 0, y2 = p2.rows > 0 && p2.cols > 0;
if (m2 && g2)
for (let e4 = 0;e4 < this.bandRows; e4++)
c2(this.cellIdFor(0, e4, l2.cols - 1), this.cellIdFor(1, e4, 0));
if (g2 && f2)
for (let e4 = 0;e4 < this.bandRows; e4++)
c2(this.cellIdFor(1, e4, h2.cols - 1), this.cellIdFor(2, e4, 0));
if (m2 && _2)
for (let e4 = this.fineRows - this.bandRows;e4 < this.fineRows; e4++)
c2(this.cellIdFor(0, e4, l2.cols - 1), this.cellIdFor(3, e4 - (this.fineRows - this.bandRows), 0));
if (_2 && f2)
for (let e4 = this.fineRows - this.bandRows;e4 < this.fineRows; e4++)
c2(this.cellIdFor(3, e4 - (this.fineRows - this.bandRows), u2.cols - 1), this.cellIdFor(2, e4, 0));
if (m2 && y2)
for (let e4 = this.bandRows;e4 < this.fineRows - this.bandRows; e4++)
c2(this.cellIdFor(0, e4, l2.cols - 1), this.cellIdFor(4, Math.floor((e4 - this.bandRows) / this.lowScale), 0));
if (f2 && y2)
for (let e4 = this.bandRows;e4 < this.fineRows - this.bandRows; e4++)
c2(this.cellIdFor(4, Math.floor((e4 - this.bandRows) / this.lowScale), p2.cols - 1), this.cellIdFor(2, e4, 0));
if (g2 && y2)
for (let e4 = this.bandCols;e4 < this.fineCols - this.bandCols; e4++)
c2(this.cellIdFor(1, h2.rows - 1, e4 - this.bandCols), this.cellIdFor(4, 0, Math.floor((e4 - this.bandCols) / this.lowScale)));
if (_2 && y2)
for (let e4 = this.bandCols;e4 < this.fineCols - this.bandCols; e4++)
c2(this.cellIdFor(4, p2.rows - 1, Math.floor((e4 - this.bandCols) / this.lowScale)), this.cellIdFor(3, 0, e4 - this.bandCols));
if (!y2 && !g2 && !_2 && m2 && f2)
for (let e4 = 0;e4 < Math.min(l2.rows, d2.rows); e4++)
c2(this.cellIdFor(0, e4, l2.cols - 1), this.cellIdFor(2, e4, 0));
if (!y2 && !m2 && !f2 && g2 && _2)
for (let e4 = 0;e4 < Math.min(h2.cols, u2.cols); e4++)
c2(this.cellIdFor(1, h2.rows - 1, e4), this.cellIdFor(3, 0, e4));
const b2 = this.flattenNeighborLists(a2);
this.neighborOffset = b2.offset, this.neighborIds = b2.ids, this.neighborCosts = b2.costs;
}
cellIdFor(e3, t2, n2) {
const o2 = this.regions[e3];
return o2.offset + t2 * o2.cols + n2;
}
stepOnce() {
if (!this.activeConnSeg) {
if (this.unsolvedSegs.length === 0)
return void (this.solved = true);
const e4 = this.unsolvedSegs.shift();
this.activeConnSeg = e4, this.activeConnId = e4.connId, this.viaOccupantsByCell.clear(), this.nodePool.clear(), this.ripChain.clear(), this.heap.clear(), this.seqCounter = 0, this.searchIterations = 0, this.nextStamp();
const t3 = this.computeH(e4.startZ, e4.startCellId, e4.endZ, e4.endCellId) * this.hyperParameters.greedyMultiplier, n3 = this.nodePool.push(e4.startZ, e4.startCellId, 0, -1, -1, 0), o3 = e4.startZ * this.planeSize + e4.startCellId, i3 = this.getSearchStateIdx(o3, 0);
return this.bestGStamp[i3] = this.stamp, this.bestGValue[i3] = 0, void this.heap.push(t3, this.seqCounter++, n3);
}
this.searchIterations++;
const e3 = this.ripCount[this.activeConnId] ?? 0, t2 = Math.round(this.baseSearchBudgetIters * (1 + 0.25 * Math.min(e3, 10)));
if (this.searchIterations > t2) {
const e4 = this.penalty2d;
for (let t3 = 0;t3 < e4.length; t3++)
e4[t3] = 0.9 * e4[t3];
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 = true));
}
if (this.heap.size === 0)
return this.error = `No path found for ${this.connIdToName[this.activeConnId]}`, void (this.failed = true);
const n2 = this.heap.pop(), o2 = this.nodePool.z[n2], i2 = this.nodePool.cellId[n2], r2 = this.nodePool.g[n2], s2 = this.nodePool.ripHead[n2], a2 = this.nodePool.ripCount[n2], c2 = o2 * this.planeSize + i2, l2 = this.getSearchStateIdx(c2, a2);
if (this.visitedStamp[l2] === this.stamp)
return;
this.visitedStamp[l2] = this.stamp, this.visitedFlatStamp[c2] = this.stamp;
const h2 = this.activeConnSeg;
if (o2 === h2.endZ && i2 === h2.endCellId)
return this.finalizeRoute(n2), this.activeConnSeg = null, void (this.activeConnId = -1);
const d2 = this.visitedStamp, u2 = this.stamp, p2 = this.activeConnId, m2 = h2.endZ, g2 = h2.endCellId, f2 = this.neighborOffset[i2], _2 = this.neighborOffset[i2 + 1];
for (let e4 = f2;e4 < _2; e4++) {
const t3 = this.neighborIds[e4], i3 = o2 * this.planeSize + t3;
if (this.computeMoveCostAndRips(p2, o2, t3, false, s2, a2, this.neighborCosts[e4]), this._moveCost < 0)
continue;
const c3 = this.getSearchStateIdx(i3, this._moveRipCount);
if (d2[c3] === u2)
continue;
const l3 = r2 + this._moveCost;
if (this.bestGStamp[c3] === u2 && l3 >= this.bestGValue[c3])
continue;
this.bestGStamp[c3] = u2, this.bestGValue[c3] = l3;
const h3 = l3 + this.computeH(o2, t3, m2, g2) * this.hyperParameters.greedyMultiplier, f3 = this.nodePool.push(o2, t3, l3, n2, this._moveRippedHead, this._moveRipCount);
this.heap.push(h3, this.seqCounter++, f3);
}
if (this.viaAllowed[i2])
for (let e4 = 0;e4 < this.layers; e4++) {
if (e4 === o2)
continue;
const t3 = e4 * this.planeSize + i2;
if (this.computeMoveCostAndRips(p2, e4, i2, true, s2, a2, 0), this._moveCost < 0)
continue;
const c3 = this.getSearchStateIdx(t3, this._moveRipCount);
if (d2[c3] === u2)
continue;
const l3 = r2 + this._moveCost;
if (this.bestGStamp[c3] === u2 && l3 >= this.bestGValue[c3])
continue;
this.bestGStamp[c3] = u2, this.bestGValue[c3] = l3;
const h3 = l3 + this.computeH(e4, i2, m2, g2) * this.hyperParameters.greedyMultiplier, f3 = this.nodePool.push(e4, i2, l3, n2, this._moveRippedHead, this._moveRipCount);
this.heap.push(h3, this.seqCounter++, f3);
}
}
computeMoveCostAndRips(e3, t2, n2, o2, i2, r2, s2) {
let a2 = 0, c2 = i2, l2 = r2;
const h2 = t2 * this.planeSize + n2;
if (o2) {
a2 += this.hyperParameters.viaBaseCost, a2 += Math.min(this.penalty2d[n2], this.penaltyCap);
const o3 = this.portOwnerFlat[h2], i3 = this.allowSharedUse(e3, o3), r3 = this.activeConnSeg, s3 = !!r3 && t2 === r3.endZ && n2 === r3.endCellId;
if (o3 >= 0 && o3 !== e3 && !i3 && !s3)
return this._moveCost = -1, void (this._moveRippedHead = c2);
this.fillViaOccupants(n2, e3);
const d2 = this._viaOccs;
for (let e4 = 0;e4 < d2.length; e4++) {
const t3 = d2[e4];
this.ripChain.contains(c2, t3) || (a2 += this.hyperParameters.ripCost, c2 = this.ripChain.append(c2, t3), l2++), a2 += this.hyperParameters.ripViaPenalty;
}
} else {
a2 += s2, a2 += Math.min(this.penalty2d[n2], this.penaltyCap);
const o3 = this.portOwnerFlat[h2], i3 = this.allowSharedUse(e3, o3), r3 = this.activeConnSeg, d2 = !!r3 && t2 === r3.endZ && n2 === r3.endCellId;
if (o3 >= 0 && o3 !== e3 && !i3 && !d2)
return this._moveCost = -1, void (this._moveRippedHead = c2);
this.fillTraceOccupants(h2, e3, this._cellOccs);
for (let e4 = 0;e4 < this._cellOccs.length; e4++) {
const t3 = this._cellOccs[e4];
this.ripChain.contains(c2, t3) || (a2 += this.hyperParameters.ripCost, c2 = this.ripChain.append(c2, t3), l2++), a2 += this.hyperParameters.ripTracePenalty;
}
}
this._moveCost = a2, this._moveRippedHead = c2, this._moveRipCount = l2;
}
fillViaOccupants(e3, t2) {
const n2 = this._viaOccs;
n2.length = 0;
const o2 = this.viaOccupantsByCell.get(e3);
if (o2) {
for (const e4 of o2)
n2.push(e4);
return;
}
const i2 = this.cellCenterX[e3], r2 = this.cellCenterY[e3];
this.forEachCellNearCircle(i2, r2, this.viaKeepoutRadius, (e4) => {
if (ki(i2, r2, this.viaKeepoutRadius, this.cellMinX[e4], this.cellMinY[e4], this.cellMaxX[e4], this.cellMaxY[e4]))
for (let o3 = 0;o3 < this.layers; o3++)
this.pushFlatOccupants(o3 * this.planeSize + e4, t2, n2);
}), this.viaOccupantsByCell.set(e3, n2.slice());
}
fillTraceOccupants(e3, t2, n2) {
n2.length = 0, this.pushFlatOccupants(e3, t2, n2);
}
pushFlatOccupants(e3, t2, n2) {
const o2 = this.usedCellsFlat[e3];
o2 === -1 || o2 === t2 || this.allowSharedUse(t2, o2) || Ai(n2, o2);
const i2 = this.sharedCellsFlat[e3];
if (i2)
for (let e4 = 0;e4 < i2.length; e4++) {
const o3 = i2[e4];
o3 !== t2 && (this.allowSharedUse(t2, o3) || Ai(n2, o3));
}
}
addSharedOccupant(e3, t2) {
if (this.usedCellsFlat[e3] === t2)
return;
let n2 = this.sharedCellsFlat[e3];
n2 || (n2 = [], this.sharedCellsFlat[e3] = n2), Ai(n2, t2);
}
replaceOccupants(e3, t2) {
this.usedCellsFlat[e3] = t2, this.sharedCellsFlat[e3] = undefined;
}
removeOccupant(e3, t2) {
const n2 = this.sharedCellsFlat[e3];
if (this.usedCellsFlat[e3] === t2)
return void (n2 && n2.length > 0 ? (this.usedCellsFlat[e3] = n2.pop(), n2.length === 0 && (this.sharedCellsFlat[e3] = undefined)) : this.usedCellsFlat[e3] = -1);
if (!n2)
return;
const o2 = n2.indexOf(t2);
o2 !== -1 && (n2.splice(o2, 1), n2.length === 0 && (this.sharedCellsFlat[e3] = undefined));
}
allowSharedUse(e3, t2) {
if (t2 < 0)
return false;
return this.connIdToRootNet[t2] === this.connIdToRootNet[e3];
}
shouldSkipFixedPortHalo(e3, t2) {
const n2 = this.portOwnerFlat[e3];
return n2 !== t2 && (n2 === -2 || !(n2 < 0) && !this.allowSharedUse(t2, n2));
}
nextStamp() {
this.stamp = this.stamp + 1 >>> 0, this.stamp === 0 && (this.visitedStamp.fill(0), this.bestGStamp.fill(0), this.visitedFlatStamp.fill(0), this.stamp = 1);
}
getSearchStateIdx(e3, t2) {
return e3;
}
computeH(e3, t2, n2, o2) {
const i2 = Math.hypot(this.cellCenterX[t2] - this.cellCenterX[o2], this.cellCenterY[t2] - this.cellCenterY[o2]);
return e3 === n2 ? i2 : i2 + this.hyperParameters.viaBaseCost;
}
internConn(e3, t2) {
const n2 = this.connNameToId.get(e3);
if (n2 !== undefined)
return n2;
const o2 = this.connIdToName.length;
var i2;
return this.connIdToName.push(e3), this.connIdToRootNet.push((i2 = e3, t2 ?? i2.replace(/_mst\d+$/, ""))), this.connNameToId.set(e3, o2), o2;
}
buildConnectionSegs() {
const e3 = new Map;
for (const t3 of this.nodeWithPortPoints.portPoints) {
const n3 = t3.connectionName;
e3.has(n3) || e3.set(n3, { points: [], rootConnectionName: t3.rootConnectionName }), e3.get(n3).points.push(t3);
}
const t2 = [], n2 = new Set;
for (const [o2, i2] of e3) {
const e4 = i2.points, r2 = bi(e4);
if (r2.length === 0)
continue;
const s2 = this.internConn(o2, i2.rootConnectionName);
for (const [e5, a2] of r2) {
const r3 = this.pointToCell(e5), c2 = this.pointToCell(a2), l2 = `${r3.z}:${r3.cellId}`, h2 = `${c2.z}:${c2.cellId}`, d2 = l2 < h2 ? `${l2}|${h2}` : `${h2}|${l2}`, u2 = i2.rootConnectionName ?? o2, p2 = `${u2}|${d2}`;
n2.has(p2) ? this.overlapFriendlyRootNets.add(u2) : (n2.add(p2), t2.push({ connId: s2, startZ: r3.z, startCellId: r3.cellId, startPoint: e5, endZ: c2.z, endCellId: c2.cellId, endPoint: a2 }));
}
}
return t2;
}
pointToCell(e3) {
const t2 = Ei(Math.floor((e3.x - this.boundsMinX) / this.highResolutionCellSize), 0, this.fineCols - 1), n2 = Ei(Math.floor((e3.y - this.boundsMinY) / this.highResolutionCellSize), 0, this.fineRows - 1);
let o2 = 4;
t2 < this.bandCols ? o2 = 0 : t2 >= this.fineCols - this.bandCols ? o2 = 2 : n2 < this.bandRows ? o2 = 1 : n2 >= this.fineRows - this.bandRows && (o2 = 3);
const i2 = this.regions[o2], r2 = n2 - i2.fineOriginRow, s2 = t2 - i2.fineOriginCol, a2 = Ei(Math.floor(r2 / i2.cellScale), 0, Math.max(0, i2.rows - 1)), c2 = Ei(Math.floor(s2 / i2.cellScale), 0, Math.max(0, i2.cols - 1));
return { z: this.zToLayer.get(e3.z) ?? 0, cellId: this.cellIdFor(o2, a2, c2) };
}
shuffleConnections() {
const e3 = this.unsolvedSegs;
let t2 = this.hyperParameters.shuffleSeed >>> 0;
const n2 = () => (t2 = Math.imul(t2, 1664525) + 1013904223 >>> 0, t2 / 4294967295);
for (let t3 = e3.length - 1;t3 > 0; t3--) {
const o2 = Math.floor(n2() * (t3 + 1)), i2 = e3[t3];
e3[t3] = e3[o2], e3[o2] = i2;
}
}
finalizeRoute(e3) {
this.consecutiveSkips = Math.max(0, this.consecutiveSkips - 1);
const t2 = [];
let n2 = e3;
for (;n2 >= 0; ) {
const e4 = this.nodePool.z[n2], o3 = this.nodePool.cellId[n2];
t2.push(e4 * this.planeSize + o3), n2 = this.nodePool.parent[n2];
}
for (t2.reverse();t2.length > 1 && this.sharedCrossRootPortFlat[t2[0]]; )
t2.shift();
for (;t2.length > 1 && this.sharedCrossRootPortFlat[t2[t2.length - 1]]; )
t2.pop();
const o2 = this.extractViaCellIds(t2), i2 = this.activeConnId;
this.ripChain.collect(this.nodePool.ripHead[e3], this._rippedIds);
for (let e4 = 0;e4 < this._rippedIds.length; e4++)
if (this.ripTrace(this._rippedIds[e4]), this.failed)
return;
const r2 = [];
for (let e4 = 0;e4 < t2.length; e4++) {
const n3 = t2[e4], o3 = Math.floor(n3 / this.planeSize), s3 = n3 - o3 * this.planeSize;
this.markTraceFootprint(i2, o3, s3, r2);
}
const s2 = [];
for (let e4 = 0;e4 < o2.length; e4++)
this.markViaFootprint(i2, o2[e4], r2, s2);
for (;this.usedIndicesByConn.length <= i2; )
this.usedIndicesByConn.push(undefined);
const a2 = this.usedIndicesByConn[i2] ?? [];
for (a2.push(...r2), this.usedIndicesByConn[i2] = a2;this.solvedRoutes.length <= i2; )
this.solvedRoutes.push(undefined);
const c2 = this.solvedRoutes[i2] ?? [];
c2.push({ connId: i2, states: Int32Array.from(t2), viaCellIds: Int32Array.from(o2), startPoint: this.activeConnSeg.startPoint, endPoint: this.activeConnSeg.endPoint }), this.solvedRoutes[i2] = c2;
for (let e4 = 0;e4 < s2.length; e4++)
if (this.ripTrace(s2[e4]), this.failed)
return;
if (this._rippedIds.length > 0 || s2.length > 0) {
const e4 = this.penalty2d, t3 = this.penaltyCap;
if (this.totalRipEvents > 50)
for (let t4 = 0;t4 < e4.length; t4++)
e4[t4] = 0.99 * e4[t4];
else
for (let n3 = 0;n3 < e4.length; n3++)
e4[n3] > t3 && (e4[n3] = 0.5 * e4[n3]);
}
}
extractViaCellIds(e3) {
const t2 = [];
for (let n2 = 1;n2 < e3.length; n2++) {
const o2 = e3[n2 - 1], i2 = e3[n2], r2 = Math.floor(o2 / this.planeSize), s2 = Math.floor(i2 / this.planeSize);
r2 !== s2 && t2.push(i2 - s2 * this.planeSize);
}
return t2;
}
markTraceFootprint(e3, t2, n2, o2) {
const i2 = this.cellCenterX[n2], r2 = this.cellCenterY[n2];
this.forEachCellNearCircle(i2, r2, this.traceKeepoutRadius, (s2) => {
if (!ki(i2, r2, this.traceKeepoutRadius, this.cellMinX[s2], this.cellMinY[s2], this.cellMaxX[s2], this.cellMaxY[s2]))
return;
const a2 = t2 * this.planeSize + s2;
if (s2 !== n2 && this.shouldSkipFixedPortHalo(a2, e3))
return;
const c2 = this.usedCellsFlat[a2], l2 = this.allowSharedUse(e3, c2);
(c2 === -1 || c2 === e3 || l2) && (c2 !== -1 && c2 !== e3 ? this.addSharedOccupant(a2, e3) : this.usedCellsFlat[a2] = e3, o2.push(a2));
});
}
markViaFootprint(e3, t2, n2, o2) {
const i2 = this.cellCenterX[t2], r2 = this.cellCenterY[t2];
this.forEachCellNearCircle(i2, r2, this.viaKeepoutRadius, (s2) => {
if (ki(i2, r2, this.viaKeepoutRadius, this.cellMinX[s2], this.cellMinY[s2], this.cellMaxX[s2], this.cellMaxY[s2]))
for (let i3 = 0;i3 < this.layers; i3++) {
const r3 = i3 * this.planeSize + s2;
if (s2 !== t2 && this.shouldSkipFixedPortHalo(r3, e3))
continue;
if (this.fillTraceOccupants(r3, e3, this._cellOccs), this._cellOccs.length > 0) {
for (let e4 = 0;e4 < this._cellOccs.length; e4++)
Ai(o2, this._cellOccs[e4]);
this.replaceOccupants(r3, e3), n2.push(r3);
continue;
}
const a2 = this.usedCellsFlat[r3];
a2 !== -1 && a2 !== e3 ? this.addSharedOccupant(r3, e3) : this.usedCellsFlat[r3] = e3, n2.push(r3);
}
});
}
forEachCellNearCircle(e3, t2, n2, o2) {
const i2 = Ei(Math.floor((e3 - n2 - this.boundsMinX) / this.highResolutionCellSize), 0, this.fineCols - 1), r2 = Ei(Math.floor((e3 + n2 - this.boundsMinX) / this.highResolutionCellSize), 0, this.fineCols - 1), s2 = Ei(Math.floor((t2 - n2 - this.boundsMinY) / this.highResolutionCellSize), 0, this.fineRows - 1), a2 = Ei(Math.floor((t2 + n2 - this.boundsMinY) / this.highResolutionCellSize), 0, this.fineRows - 1);
for (let e4 = 0;e4 < this.regions.length; e4++) {
const t3 = this.regions[e4];
if (t3.rows === 0 || t3.cols === 0)
continue;
const n3 = Math.max(s2, t3.fineOriginRow), c2 = Math.min(a2, t3.fineOriginRow + t3.fineRows - 1), l2 = Math.max(i2, t3.fineOriginCol), h2 = Math.min(r2, t3.fineOriginCol + t3.fineCols - 1);
if (n3 > c2)
continue;
if (l2 > h2)
continue;
const d2 = Math.floor((n3 - t3.fineOriginRow) / t3.cellScale), u2 = Math.floor((c2 - t3.fineOriginRow) / t3.cellScale), p2 = Math.floor((l2 - t3.fineOriginCol) / t3.cellScale), m2 = Math.floor((h2 - t3.fineOriginCol) / t3.cellScale);
for (let e5 = d2;e5 <= u2; e5++)
for (let n4 = p2;n4 <= m2; n4++)
o2(this.cellIdFor(t3.id, e5, n4));
}
}
ripTrace(e3) {
for (;this.ripCount.length <= e3; )
this.ripCount.push(0);
if (this.ripCount[e3]++, this.totalRipEvents++, this.totalRipEvents >= this.MAX_RIPS)
return this.error = `Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`, void (this.failed = true);
const t2 = this.getSolvedRoutesForConn(e3);
if (t2.length > 0)
for (const e4 of t2) {
for (let t3 = 0;t3 < e4.states.length; t3++) {
const n3 = e4.states[t3] % this.planeSize;
this.penalty2d[n3] = this.penalty2d[n3] + this.hyperParameters.ripTracePenalty;
}
for (let t3 = 0;t3 < e4.viaCellIds.length; t3++) {
const n3 = e4.viaCellIds[t3];
this.penalty2d[n3] = this.penalty2d[n3] + this.hyperParameters.ripViaPenalty;
}
}
const n2 = this.usedIndicesByConn[e3];
if (n2) {
for (let t3 = 0;t3 < n2.length; t3++)
this.removeOccupant(n2[t3], e3);
this.usedIndicesByConn[e3] = undefined;
}
if (t2.length > 0) {
this.solvedRoutes[e3] = undefined;
for (const n3 of t2) {
const t3 = n3.states[0], o2 = n3.states[n3.states.length - 1], i2 = Math.floor(t3 / this.planeSize), r2 = Math.floor(o2 / this.planeSize);
this.unsolvedSegs.push({ connId: e3, startZ: i2, startCellId: t3 - i2 * this.planeSize, startPoint: n3.startPoint, endZ: r2, endCellId: o2 - r2 * this.planeSize, endPoint: n3.endPoint });
}
}
}
flattenNeighborLists(e3) {
const t2 = new Int32Array(e3.length + 1);
let n2 = 0;
for (let o3 = 0;o3 < e3.length; o3++)
t2[o3] = n2, n2 += e3[o3].length;
t2[e3.length] = n2;
const o2 = new Int32Array(n2), i2 = new Float32Array(n2);
let r2 = 0;
for (let t3 = 0;t3 < e3.length; t3++) {
const n3 = e3[t3];
for (let e4 = 0;e4 < n3.length; e4++) {
const t4 = n3[e4];
o2[r2] = t4.cellId, i2[r2] = t4.cost, r2++;
}
}
return { offset: t2, ids: o2, costs: i2 };
}
visualize() {
const e3 = ["red", "blue", "orange", "green"], t2 = this.gridToBoundsTransform, n2 = [], o2 = [], i2 = [], r2 = [];
if (r2.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 e4 = 0;
for (let t3 = 0;t3 < this.penalty2d.length; t3++)
this.penalty2d[t3] > e4 && (e4 = this.penalty2d[t3]);
if (e4 > 0)
for (let n3 = 0;n3 < this.planeSize; n3++) {
const o3 = this.penalty2d[n3];
if (o3 <= 0)
continue;
const i3 = fi(t2, { x: this.cellCenterX[n3], y: this.cellCenterY[n3] }), s3 = Math.min(0.6, o3 / e4 * 0.6);
r2.push({ center: i3, width: this.cellWidth[n3] * t2.a, height: this.cellHeight[n3] * t2.e, fill: `rgba(255,165,0,${s3.toFixed(3)})` });
}
}
if (this.showUsedCellMap && this.usedCellsFlat)
for (let e4 = 0;e4 < this.layers; e4++) {
const n3 = e4 * this.planeSize;
for (let e5 = 0;e5 < this.planeSize; e5++) {
if (this.usedCellsFlat[n3 + e5] === -1)
continue;
const o3 = fi(t2, { x: this.cellCenterX[e5], y: this.cellCenterY[e5] });
r2.push({ center: o3, width: this.cellWidth[e5] * t2.a, height: this.cellHeight[e5] * t2.e, fill: "rgba(0,0,255,0.5)" });
}
}
for (const t3 of this.nodeWithPortPoints.portPoints)
n2.push({ x: t3.x, y: t3.y, color: e3[t3.z] ?? "gray", label: t3.connectionName });
const s2 = ["rgba(255,0,0,0.75)", "rgba(0,0,255,0.75)", "rgba(255,165,0,0.75)", "rgba(0,128,0,0.75)"], a2 = this.getOutput();
for (const e4 of a2) {
if (e4.route.length < 2)
continue;
let t3 = 0;
for (let n3 = 1;n3 < e4.route.length; n3++) {
const i3 = e4.route[n3 - 1];
e4.route[n3].z !== i3.z && (n3 - t3 >= 2 && o2.push({ points: e4.route.slice(t3, n3).map((e5) => ({ x: e5.x, y: e5.y })), strokeColor: s2[i3.z] ?? "rgba(128,128,128,0.75)", strokeWidth: this.traceThickness }), t3 = n3);
}
if (e4.route.length - t3 >= 2) {
const n3 = e4.route[t3].z;
o2.push({ points: e4.route.slice(t3).map((e5) => ({ x: e5.x, y: e5.y })), strokeColor: s2[n3] ?? "rgba(128,128,128,0.75)", strokeWidth: this.traceThickness });
}
}
for (const e4 of a2)
for (const t3 of e4.vias)
i2.push({ center: { x: t3.x, y: t3.y }, radius: this.viaDiameter / 2, fill: "rgba(0,0,0,0.3)", stroke: "black" });
if (this.activeConnSeg && this.visitedFlatStamp) {
const e4 = this.stamp;
for (let o3 = 0;o3 < this.layers; o3++) {
const i3 = o3 * this.planeSize;
for (let o4 = 0;o4 < this.planeSize; o4++) {
if (this.visitedFlatStamp[i3 + o4] !== e4)
continue;
const r3 = fi(t2, { x: this.cellCenterX[o4], y: this.cellCenterY[o4] });
n2.push({ x: r3.x, y: r3.y, color: "rgba(0,0,255,0.2)" });
}
}
}
return { points: n2, lines: o2, circles: i2, rects: r2, coordinateSystem: "cartesian", title: `${this.getSolverName()} [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length ?? 0} remaining]` };
}
getOutput() {
const e3 = this.gridToBoundsTransform, t2 = [];
for (let n2 = 0;n2 < this.solvedRoutes.length; n2++) {
const o2 = this.getSolvedRoutesForConn(n2);
if (o2.length === 0)
continue;
const i2 = this.connIdToName[n2];
for (const r2 of o2) {
const o3 = Array.from(r2.states, (t3) => {
const n3 = Math.floor(t3 / this.planeSize), o4 = t3 - n3 * this.planeSize, i3 = fi(e3, { x: this.cellCenterX[o4], y: this.cellCenterY[o4] });
return { x: i3.x, y: i3.y, z: this.layerToZ.get(n3) ?? n3 };
});
o3.length === 1 ? (o3[0] = { ...r2.startPoint }, o3.push({ ...r2.endPoint })) : o3.length > 1 && (o3[0] = { ...r2.startPoint }, o3[o3.length - 1] = { ...r2.endPoint }), t2.push({ connectionName: i2, rootConnectionName: this.connIdToRootNet[n2], regionId: this.nodeWithPortPoints.capacityMeshNodeId, traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, route: o3, vias: Array.from(r2.viaCellIds, (t3) => fi(e3, { x: this.cellCenterX[t3], y: this.cellCenterY[t3] })) });
}
}
return t2;
}
getSolvedRoutesForConn(e3) {
const t2 = this.solvedRoutes[e3];
return t2 ? Array.isArray(t2) ? t2 : [t2] : [];
}
getSolvedRouteCount() {
let e3 = 0;
for (let t2 = 0;t2 < this.solvedRoutes.length; t2++)
e3 += this.getSolvedRoutesForConn(t2).length;
return e3;
}
computeGridToBoundsTransform() {
let e3 = 1 / 0, t2 = -1 / 0, n2 = 1 / 0, o2 = -1 / 0;
for (let i3 = 0;i3 < this.planeSize; i3++) {
const r3 = this.cellCenterX[i3], s3 = this.cellCenterY[i3];
r3 < e3 && (e3 = r3), r3 > t2 && (t2 = r3), s3 < n2 && (n2 = s3), s3 > o2 && (o2 = s3);
}
const i2 = t2 - e3, r2 = o2 - n2, s2 = this.boundsMaxX - this.boundsMinX, a2 = this.boundsMaxY - this.boundsMinY, c2 = i2 > 0 ? s2 / i2 : 1, l2 = r2 > 0 ? a2 / r2 : 1;
return { a: c2, b: 0, c: i2 > 0 ? this.boundsMinX - c2 * e3 : (this.boundsMinX + this.boundsMaxX) / 2 - e3, d: 0, e: l2, f: r2 > 0 ? this.boundsMinY - l2 * n2 : (this.boundsMinY + this.boundsMaxY) / 2 - n2 };
}
};
var zi = class {
begin;
run;
copyParents;
constructor(e3, t2, n2, o2, i2) {
const r2 = e3 * t2, s2 = r2 * n2, a2 = new Float64Array(s2), c2 = new Int32Array(s2), l2 = new Uint32Array(s2), h2 = new Int32Array(s2), d2 = new Uint8Array(s2);
let u2, p2, m2, g2, f2, _2, y2, b2, x2 = 0, v2 = 0, I2 = 0, S2 = 1024, C2 = new Float64Array(S2), P2 = new Int32Array(S2), M2 = new Uint32Array(S2);
for (let n3 = 0;n3 < s2; n3++) {
const o3 = n3 % r2, i3 = o3 % e3, s3 = Math.floor(o3 / e3), a3 = Math.floor(n3 / r2);
h2[n3] = o3, d2[n3] = Number(i3 > 0) | Number(i3 + 1 < e3) << 1 | Number(s3 > 0) << 2 | Number(s3 + 1 < t2) << 3 | a3 % 2 << 4;
}
function w2(e4, t3) {
let n3 = I2++;
for (;n3 > 0; ) {
const e5 = n3 - 1 >> 1;
if (C2[e5] <= t3)
break;
C2[n3] = C2[e5], P2[n3] = P2[e5], M2[n3] = M2[e5], n3 = e5;
}
C2[n3] = t3, P2[n3] = e4, l2[e4] = l2[e4] + 1 >>> 0, M2[n3] = l2[e4];
}
let N2 = 0, T2 = 0;
function R2() {
N2 = P2[0], T2 = M2[0];
const e4 = --I2;
if (!e4)
return;
const t3 = P2[e4], n3 = M2[e4], o3 = C2[e4];
let i3 = 0;
for (;2 * i3 + 1 < I2; ) {
let e5 = 2 * i3 + 1;
if (e5 + 1 < I2 && C2[e5 + 1] < C2[e5] && e5++, o3 <= C2[e5])
break;
C2[i3] = C2[e5], P2[i3] = P2[e5], M2[i3] = M2[e5], i3 = e5;
}
C2[i3] = o3, P2[i3] = t3, M2[i3] = n3;
}
function E2(e4, t3, n3, o3, i3, r3) {
const s3 = r3 + t3;
if (s3 >= a2[e4])
return;
if (m2[e4] && e4 !== x2)
return;
if (n3 && g2[o3])
return;
const l3 = n3 ? p2[o3] : u2[e4], h3 = n3 ? _2[o3] : f2[e4], d3 = s3 + v2 * l3 + h3;
d3 >= a2[e4] || (a2[e4] = d3, c2[e4] = i3, w2(e4, d3 + y2[e4]));
}
this.begin = (e4, t3, n3, o3) => {
(({ traceCost: u2, viaCost: p2, fixed: m2, fixedVia: g2, history: f2, viaHistory: _2, viaAllowed: b2 } = e4)), y2 = e4.heuristicCost, x2 = n3, v2 = o3, I2 = 0, a2.fill(1 / 0), c2.fill(-1), l2.fill(0), a2[t3] = 0, w2(t3, y2[t3]);
}, this.run = (t3, s3) => {
let c3 = 0, u3 = 0;
for (;u3 < t3; ) {
if (c3 >= s3)
return { status: 3, expansions: c3 };
if (!I2)
return { status: 2, expansions: c3 };
if (I2 + 4 + n2 > S2) {
S2 *= 2;
const e4 = new Float64Array(S2), t5 = new Int32Array(S2), n3 = new Uint32Array(S2);
e4.set(C2), t5.set(P2), n3.set(M2), C2 = e4, P2 = t5, M2 = n3;
continue;
}
R2(), u3++;
const t4 = N2;
if (T2 !== l2[t4])
continue;
const p3 = a2[t4];
if (c3++, t4 === x2)
return { status: 1, expansions: c3 };
const m3 = h2[t4], g3 = d2[t4], f3 = o2 * (16 & g3 ? 1.05 : 1), _3 = i2 * (16 & g3 ? 1 : 1.05);
if (1 & g3 && E2(t4 - 1, f3, false, 0, t4, p3), 2 & g3 && E2(t4 + 1, f3, false, 0, t4, p3), 4 & g3 && E2(t4 - e3, _3, false, 0, t4, p3), 8 & g3 && E2(t4 + e3, _3, false, 0, t4, p3), b2[m3])
for (let e4 = 0;e4 < n2; e4++) {
const n3 = e4 * r2 + m3;
n3 !== t4 && E2(n3, 0.8, true, m3, t4, p3);
}
}
return { status: 0, expansions: c3 };
}, this.copyParents = (e4) => e4.set(c2);
}
};
var Bi = class {
exports;
offsets = [];
states;
heapCapacity = 1024;
constructor(e3, t2, n2, o2, i2) {
Di ??= new WebAssembly.Module(Uint8Array.from(atob("AGFzbQEAAAABHwVgB39/f3x8f38AYAF/AGAAAX9gA39/fABgAn9/AX8DBwYAAQICAwQFAwEAAgYPAn8BQYCABAt/AEGAgQQLB2kIBm1lbW9yeQIACWNvbmZpZ3VyZQAAEXNldF9oZWFwX2NhcGFjaXR5AAEOZ2V0X2V4cGFuc2lvbnMAAghnZXRfcG9wcwADDGJlZ2luX3NlYXJjaAAEA3J1bgAFC19faGVhcF9iYXNlAwEK0h8G8wcEBX8FewR/BHtBACEHQQAgAjYChICEgABBACAANgKAgISAAEEAIAY2AqCAhIAAQQAgASAAbCIINgKIgISAAEEAIAggAmwiCTYCjICEgABBACADOQOQgISAAEEAIAQ5A5iAhIAAQQAgBSgCBDYCqICEgABBACAFKAIINgKsgISAAEEAIAUoAgw2ArCAhIAAQQAgBSgCEDYCtICEgABBACAFKAIUNgK4gISAAEEAIAUoAgA2AqSAhIAAQQAgBSgCGDYCvICEgABBACAFKAIcNgLAgISAAEEAIAUoAiA2AsSAhIAAQQAgBSgCJDYCyICEgABBACAFKAIoIgo2AsyAhIAAQQAgBSgCLCILNgLQgISAAEEAIAUoAjA2AtSAhIAAQQAgBSgCNDYC2ICEgAACQCAJQQFIDQACQCAJQQhJDQAgCyACIAFsIABsQQJ0IgVqIgIgCksgCiAFaiIFIAtLcQ0AIApBhICEgABJIAVBgICEgABLcQ0AIAtBhICEgABJIAJBgICEgABLcQ0AIAH9ESEMIAD9ESENIAj9ESEOQQD9CQKAgISAACEP/QwAAAAAAQAAAAIAAAADAAAAIRAgCiEFIAshAiAJQfz///8HcSIHIQYDQCAFIBAgEP0bACAO/RsAbSIR/REgEP0bASAO/RsBbSIS/RwBIBD9GwIgDv0bAm0iE/0cAiAQ/RsDIA79GwNtIhT9HAMgDv21Af2xASIV/QsCACACIBX9GwAgDf0bAG39ESAV/RsBIA39GwFt/RwBIBX9GwIgDf0bAm39HAIgFf0bAyAN/RsDbf0cAyIW/QwAAAAAAAAAAAAAAAAAAAAAIhf9O/0MBAAAAAQAAAAEAAAABAAAACIY/U4gFSAWIA39tQH9sQEiFSAX/Tj9sQEgEUECb/0RIBJBAm/9HAEgE0ECb/0cAiAUQQJv/RwDQQT9qwH9UCAV/QwBAAAAAQAAAAEAAAABAAAAIhf9rgEgD/05/QwCAAAAAgAAAAIAAAACAAAA/U79UCAWIBf9rgEgDP05/QwIAAAACAAAAAgAAAAIAAAA/U79UP0LAgAgBUEQaiEFIAJBEGohAiAQIBj9rgEhECAGQXxqIgYNAAsgCSAHRg0BC0EAIAFrIRMgCiAHQQJ0IgJqIQUgCyACaiECQQAgCGshFANAIAUgByAUIAcgCG0iBmxqIhE2AgAgAkEEQQAgESAAbSIRQQBKGyAHIAAgEyAGbCARa2wiEmpBAEdyIAZBAm9BBHRyQQJBACAHQQFqIgYgEmpBACgCgICEgABIG3JBCEEAIBFBAWogAUgbcjYCACAFQQRqIQUgAkEEaiECIAYhByAJIAZHDQALCwsNAEEAIAA2AqCAhIAACwsAQQAoAtyAhIAACwsAQQAoAuCAhIAAC4gFAQl/QQAgAjkD6ICEgABBACABNgLkgISAAEEAKALUgISAACEDQQAoAsSAhIAAIQQCQEEAKAKMgISAACIFQQFIDQBBACgCyICEgAAhBkEAIQcCQCAFQQRJDQBBACEHIAMgBmtBCEkNACAEIQEgBiEIIAMhCSAFQf7///8HcSIHIQoDQCAIQn83AgAgAf0MAAAAAAAA8H8AAAAAAADwf/0LAwAgCUIANwIAIAFBEGohASAIQQhqIQggCUEIaiEJIApBfmoiCg0ACyAFIAdGDQELIAchCwJAIAUgB2tBA3EiCkUNACAHIApqIQsgBCAHQQN0aiEBIAYgB0ECdCIJaiEIIAMgCWohCQNAIAhBfzYCACABQoCAgICAgID4/wA3AwAgCUEANgIAIAFBCGohASAIQQRqIQggCUEEaiEJIApBf2oiCg0ACwsgByAFa0F8Sw0AIAtBAnQhByAFIAtrIQUgBCALQQN0aiEBIAMhCgNAIAYgB2oiCEF/NgIAIAogB2oiCUEANgIAIAhBBGpBfzYCACAJQQRqQQA2AgAgCEEIakF/NgIAIAlBCGpBADYCACAIQQxqQX82AgAgAUKAgICAgICA+P8ANwMAIAFBCGpCgICAgICAgPj/ADcDACABQRBqQoCAgICAgID4/wA3AwAgAUEYakKAgICAgICA+P8ANwMAIAlBDGpBADYCACABQSBqIQEgBkEQaiEGIApBEGohCiAFQXxqIgUNAAsLQQBBATYC8ICEgAAgBCAAQQN0IghqQgA3AwAgAyAAQQJ0aiIBIAEoAgBBAWoiCTYCAEEAKALYgISAACIBQQAoAryAhIAAIAhqKwMAOQMAIAEgCTYCDCABIAA2AggLqhIMC38BfAN/AnwNfwF+AXwDfwJ8AX8BfAN/QQAhAkEAQQA2AuCAhIAAQQBBADYC3ICEgAACQCAAQQFIDQBBACgChICEgAAiA0EEaiEEQQAoAriAhIAAIQVBACgCqICEgAAhBkEAKAKwgISAACEHQQAoAoiAhIAAIQhBACgCwICEgAAhCUEAKAKAgISAACEKQQAoAryAhIAAIQtBACgCyICEgAAhDEEAKwPogISAACENQQAoArSAhIAAIQ5BACgCpICEgAAhD0EAKAKsgISAACEQQQArA5iAhIAAIRFBACsDkICEgAAhEkEAKALQgISAACETQQAoAsyAhIAAIRRBACgC5ICEgAAhFUEAKALEgISAACEWQQAoAtSAhIAAIRdBACgC2ICEgAAhGEEAKAKggISAACEZQQAoAvCAhIAAIRpBACEbQQAhHANAAkAgHCABSA0AQQMPCwJAIBoNAEECDwsCQCAaIARqIBlMDQBBBA8LQQAgGkF/aiIdNgLwgISAACAYKAIMIR4gGCgCCCEfAkAgHUUNACAYIB1BBHRqIgIpAwghICACKwMAISFBACECAkAgGkEDSA0AQQAhIkEBISNBACEkA0ACQAJAICRBAmoiJCAdSA0AICMhAgwBCyAjIQIgGCAkQQR0aisDACAYICNBBHRqKwMAY0UNACAkIQILAkAgISAYIAJBBHRqIiMrAwBlRQ0AICIhAgwCCyAYICJBBHRqICP9AAMA/QsDACACISIgAkEBdCIkQQFyIiMgHUgNAAsLIBggAkEEdGoiAiAgNwMIIAIgITkDAAtBACAbQQFqIhs2AuCAhIAAAkACQCAeIBcgH0ECdCIjaigCAEYNACAdIRoMAQtBASECQQAgHEEBaiIcNgLcgISAACAfIBVGDQIgFiAfQQN0aisDACEhIBJEzczMzMzM8D9EAAAAAAAA8D8gEyAjaigCACICQRBxIiIboiElIBQgI2ooAgAhIwJAAkAgAkEBcQ0AIB0hGgwBCwJAICEgJaAiJiAWIB9Bf2oiHkEDdCIkaiInKwMAIihmRQ0AIB0hGgwBCwJAIB4gFUYNACAQIB5qLQAAQf8BcUUNACAdIRoMAQsCQCAOICRqKwMAICYgDSAPIB5BAXRqLwEAuKKgoCImIChmRQ0AIB0hGgwBCyAMIB5BAnQiKWogHzYCACAnICY5AwBBACAaNgLwgISAACAmIAsgJGorAwCgISYCQCAaQQJIDQADQCAYIB1Bf2pBAXYiJEEEdGoiJysDACAmZQ0BIBggHUEEdGogJ/0AAwD9CwMAICQhHSAkDQALQQAhHQsgFyApaiIkICQoAgBBAWoiJDYCACAYIB1BBHRqIh0gJjkDACAdICQ2AgwgHSAeNgIIC0QAAAAAAADwP0TNzMzMzMzwPyAiGyEmAkACQCACQQJxDQAgGiEdDAELAkAgISAloCIlIBYgH0EBaiIeQQN0IiJqIh0rAwAiKGZFDQAgGiEdDAELAkAgHiAVRg0AIBAgHmotAABB/wFxRQ0AIBohHQwBCwJAIA4gImorAwAgJSANIA8gHkEBdGovAQC4oqCgIiUgKGZFDQAgGiEdDAELIAwgHkECdCInaiAfNgIAIB0gJTkDAEEAIBpBAWoiHTYC8ICEgAAgJSALICJqKwMAoCElAkAgGkEBSA0AA0AgGCAaQX9qQQF2IiJBBHRqIiQrAwAgJWUNASAYIBpBBHRqICT9AAMA/QsDACAiIRogIg0AC0EAIRoLIBcgJ2oiIiAiKAIAQQFqIiI2AgAgGCAaQQR0aiIaICU5AwAgGiAiNgIMIBogHjYCCAsgESAmoiElAkACQCACQQRxDQAgHSEiDAELAkAgISAloCImIBYgHyAKayIeQQN0IhpqIiIrAwAiKGZFDQAgHSEiDAELAkAgHiAVRg0AIBAgHmotAABB/wFxRQ0AIB0hIgwBCwJAIA4gGmorAwAgJiANIA8gHkEBdGovAQC4oqCgIiYgKGZFDQAgHSEiDAELIAwgHkECdCInaiAfNgIAICIgJjkDAEEAIB1BAWoiIjYC8ICEgAAgJiALIBpqKwMAoCEmAkAgHUEBSA0AA0AgGCAdQX9qQQF2IhpBBHRqIiQrAwAgJmUNASAYIB1BBHRqICT9AAMA/QsDACAaIR0gGg0AC0EAIR0LIBcgJ2oiGiAaKAIAQQFqIho2AgAgGCAdQQR0aiIdICY5AwAgHSAaNgIMIB0gHjYCCAsCQAJAIAJBCHENACAiIRoMAQsCQCAhICWgIiUgFiAKIB9qIiRBA3QiAmoiHSsDACImZkUNACAiIRoMAQsCQCAkIBVGDQAgECAkai0AAEH/AXFFDQAgIiEaDAELAkAgDiACaisDACAlIA0gDyAkQQF0ai8BALiioKAiJSAmZkUNACAiIRoMAQsgDCAkQQJ0Ih5qIB82AgAgHSAlOQMAQQAgIkEBaiIaNgLwgISAACAlIAsgAmorAwCgISUCQCAiQQFIDQADQCAYICJBf2pBAXYiAkEEdGoiHSsDACAlZQ0BIBggIkEEdGogHf0AAwD9CwMAIAIhIiACDQALQQAhIgsgFyAeaiICIAIoAgBBAWoiHTYCACAYICJBBHRqIgIgJTkDACACIB02AgwgAiAkNgIICyAJICNqLQAARQ0AIANBAUgNACAHICNqIR4gIUSamZmZmZnpP6AhISAFICNBA3RqIScgBiAjQQF0aiEpQQAhAgNAAkAgCCACbCAjaiIdIB9GDQAgISAWIB1BA3QiImoiJCsDACIlZg0AAkAgHSAVRg0AIBAgHWotAABB/wFxDQELIB4tAAANACAnKwMAICEgDSApLwEAuKKgoCImICVmDQAgDCAdQQJ0IipqIB82AgAgJCAmOQMAQQAgGkEBaiIrNgLwgISAACAmIAsgImorAwCgISUCQCAaQQFIDQADQCAYIBpBf2pBAXYiIkEEdGoiJCsDACAlZQ0BIBggGkEEdGogJP0AAwD9CwMAICIhGiAiDQALQQAhGgsgFyAqaiIiICIoAgBBAWoiIjYCACAYIBpBBHRqIhogJTkDACAaICI2AgwgGiAdNgIIICshGgsgAkEBaiICIANHDQALCyAbIABHDQALQQAhAgsgAgsAdQRuYW1lAAwLa2VybmVsLndhc20BTAYACWNvbmZpZ3VyZQERc2V0X2hlYXBfY2FwYWNpdHkCDmdldF9leHBhbnNpb25zAwhnZXRfcG9wcwQMYmVnaW5fc2VhcmNoBQNydW4HEgEAD19fc3RhY2tfcG9pbnRlcgAvCXByb2R1Y2VycwEMcHJvY2Vzc2VkLWJ5AQ5Ib21lYnJldyBjbGFuZwYyMi4xLjgAnQEPdGFyZ2V0X2ZlYXR1cmVzCSsLYnVsay1tZW1vcnkrD2J1bGstbWVtb3J5LW9wdCsWY2FsbC1pbmRpcmVjdC1vdmVybG9uZysKbXVsdGl2YWx1ZSsPbXV0YWJsZS1nbG9iYWxzKxNub250cmFwcGluZy1mcHRvaW50Kw9yZWZlcmVuY2UtdHlwZXMrCHNpZ24tZXh0KwdzaW1kMTI4"), (e4) => e4.charCodeAt(0))), this.exports = new WebAssembly.Instance(Di).exports;
const r2 = e3 * t2;
this.states = r2 * n2;
let s2 = Number(this.exports.__heap_base.value);
const a2 = s2;
s2 += 56;
for (const e4 of [2 * this.states, 2 * r2, this.states, r2, 8 * this.states, 8 * r2, 8 * this.states, r2, 8 * this.states, 4 * this.states, 4 * this.states, 4 * this.states, 4 * this.states, 16 * this.heapCapacity])
s2 = 8 * Math.ceil(s2 / 8), this.offsets.push(s2), s2 += e4;
this.ensureMemory(s2), new Int32Array(this.exports.memory.buffer, a2, 14).set(this.offsets), this.exports.configure(e3, t2, n2, o2, i2, a2, this.heapCapacity);
}
ensureMemory(e3) {
const t2 = this.exports.memory;
e3 > t2.buffer.byteLength && t2.grow(Math.ceil((e3 - t2.buffer.byteLength) / 65536));
}
begin(e3, t2, n2, o2) {
const i2 = new Uint8Array(this.exports.memory.buffer), r2 = [e3.traceCost, e3.viaCost, e3.fixed, e3.fixedVia, e3.history, e3.viaHistory, e3.heuristicCost, e3.viaAllowed];
for (let e4 = 0;e4 < r2.length; e4++) {
const t3 = r2[e4];
i2.set(new Uint8Array(t3.buffer, t3.byteOffset, t3.byteLength), this.offsets[e4]);
}
this.exports.begin_search(t2, n2, o2);
}
run(e3, t2) {
let n2 = 0, o2 = 0, i2 = Math.ceil(e3);
for (;i2 > 0; )
if (o2 = this.exports.run(Math.min(i2, 1e6), Math.min(Math.ceil(t2 - n2), 2147483647)), i2 -= this.exports.get_pops(), n2 += this.exports.get_expansions(), o2 === 4)
this.heapCapacity *= 2, this.ensureMemory(this.offsets[13] + 16 * this.heapCapacity), this.exports.set_heap_capacity(this.heapCapacity);
else if (o2 !== 0)
break;
return { status: o2, expansions: n2 };
}
copyParents(e3) {
e3.set(new Int32Array(this.exports.memory.buffer, this.offsets[9], this.states));
}
};
var Fi = (e3, t2, n2) => {
const [o2, i2] = e3;
if (o2 === i2)
return;
const r2 = ((e4, t3) => {
const n3 = e4.portPointId ?? `${e4.connectionName}:${e4.x}:${e4.y}:${e4.z}`, o3 = t3.portPointId ?? `${t3.connectionName}:${t3.x}:${t3.y}:${t3.z}`;
return n3 < o3 ? `${n3}|${o3}` : `${o3}|${n3}`;
})(o2, i2);
t2.has(r2) || (t2.add(r2), n2.push(e3));
};
var ji = (e3, t2, n2) => {
for (let o2 = 0;o2 < e3.length - 1; o2++)
Fi([e3[o2], e3[o2 + 1]], t2, n2);
};
var $i = (e3) => {
const t2 = [], n2 = new Set, o2 = ((e4) => {
const t3 = new Map;
for (const n3 of e4)
n3.portPointId && t3.set(n3.portPointId, n3);
return t3;
})(e3);
for (const i3 of e3) {
if (i3.prevPortPointId) {
const e4 = o2.get(i3.prevPortPointId);
e4 && e4.connectionName === i3.connectionName && Fi([e4, i3], n2, t2);
}
if (i3.nextPortPointId) {
const e4 = o2.get(i3.nextPortPointId);
e4 && e4.connectionName === i3.connectionName && Fi([i3, e4], n2, t2);
}
}
if (t2.length === 0)
return ji(e3, n2, t2), t2;
const i2 = ((e4) => {
const t3 = new Set;
for (const [n3, o3] of e4)
n3.portPointId && t3.add(n3.portPointId), o3.portPointId && t3.add(o3.portPointId);
return t3;
})(t2), r2 = e3.filter((e4) => !e4.portPointId || !i2.has(e4.portPointId));
return ji(r2, n2, t2), t2;
};
var Yi = 0.000000001;
var Xi = 0.01;
var Wi = 0.000001;
function Vi(e3, t2, n2) {
return (t2.x - e3.x) * (n2.y - e3.y) - (t2.y - e3.y) * (n2.x - e3.x);
}
function Hi(e3, t2, n2, o2) {
const i2 = Vi(n2, o2, e3), r2 = Vi(n2, o2, t2), s2 = Vi(e3, t2, n2), a2 = Vi(e3, t2, o2);
if ((i2 > Yi && r2 < -1e-9 || i2 < -1e-9 && r2 > Yi) && (s2 > Yi && a2 < -1e-9 || s2 < -1e-9 && a2 > Yi)) {
const n3 = i2 / (i2 - r2);
return { x: e3.x + n3 * (t2.x - e3.x), y: e3.y + n3 * (t2.y - e3.y) };
}
return null;
}
function Gi(e3, t2) {
const n2 = [];
for (let o2 = 0;o2 < e3.route.length - 1; o2++) {
const i2 = e3.route[o2], r2 = e3.route[o2 + 1];
i2.z === t2 && r2.z === t2 && n2.push([{ x: i2.x, y: i2.y }, { x: r2.x, y: r2.y }]);
}
return n2;
}
function Ui(e3, t2) {
return e3.route.filter((e4) => e4.z === t2).map((e4) => ({ x: e4.x, y: e4.y }));
}
function Zi(e3, t2) {
return Math.hypot(e3.x - t2.x, e3.y - t2.y);
}
function qi(e3, t2, n2 = 0.01) {
return Math.abs(e3.x - t2.x) < n2 && Math.abs(e3.y - t2.y) < n2;
}
function Ji(e3, t2, n2) {
const o2 = new Set, i2 = [e3.route[0], e3.route[e3.route.length - 1]];
for (const e4 of i2)
e4 && e4.z === t2 && e4.portPointId && qi(e4, n2) && o2.add(e4.portPointId);
return o2;
}
function Qi(e3, t2, n2, o2) {
const i2 = Ji(e3, n2, o2);
if (i2.size === 0)
return false;
const r2 = Ji(t2, n2, o2);
if (r2.size === 0)
return false;
for (const e4 of i2)
if (r2.has(e4))
return true;
return false;
}
function Ki(e3, t2, n2, o2) {
const i2 = [t2.a, t2.b], r2 = [o2.a, o2.b];
for (const o3 of i2)
for (const i3 of r2)
if (qi(o3, i3) && Qi(e3, n2, t2.z, o3))
return true;
return false;
}
function er(e3, t2, n2) {
const o2 = n2.x - t2.x, i2 = n2.y - t2.y, r2 = o2 * o2 + i2 * i2;
if (r2 <= Yi)
return Zi(e3, t2);
const s2 = e3.x - t2.x, a2 = e3.y - t2.y, c2 = Math.max(0, Math.min(1, (s2 * o2 + a2 * i2) / r2));
const l2 = t2.x + o2 * c2, h2 = t2.y + i2 * c2;
return Math.hypot(e3.x - l2, e3.y - h2);
}
function tr(e3, t2, n2, o2) {
return Hi(e3, t2, n2, o2) ? 0 : Math.min(er(e3, n2, o2), er(t2, n2, o2), er(n2, e3, t2), er(o2, e3, t2));
}
function nr(e3) {
return e3.rootConnectionName ?? e3.connectionName.replace(/_mst\d+$/, "");
}
function or(e3, t2) {
e3.push(t2);
}
function ir(e3) {
const t2 = function(e4) {
const t3 = [], n3 = new Set;
for (const t4 of e4)
for (const e5 of t4.route)
n3.add(e5.z);
for (const o2 of n3) {
const n4 = e4.map((e5) => ({ points: Ui(e5, o2), segments: Gi(e5, o2), root: nr(e5) }));
for (let i2 = 0;i2 < e4.length; i2++) {
const r2 = e4[i2], { points: s2, segments: a2, root: c2 } = n4[i2];
for (let l2 = i2 + 1;l2 < e4.length; l2++) {
const i3 = e4[l2], { points: h2, segments: d2, root: u2 } = n4[l2];
if (c2 === u2)
continue;
const p2 = new Set;
for (const e5 of s2)
for (const n5 of h2)
if (qi(e5, n5)) {
if (Qi(r2, i3, o2, e5))
continue;
const n6 = `${e5.x.toFixed(2)},${e5.y.toFixed(2)}`;
if (p2.has(n6))
continue;
p2.add(n6), t3.push({ trace1: r2.connectionName, trace2: i3.connectionName, z: o2, point: e5, type: "shared_point" });
}
for (const [e5, n5] of a2)
for (const [s3, a3] of d2) {
const c3 = Hi(e5, n5, s3, a3);
c3 && t3.push({ trace1: r2.connectionName, trace2: i3.connectionName, z: o2, point: c3, type: "crossing", seg1: [e5, n5], seg2: [s3, a3] });
}
}
}
}
return t3;
}(e3).map((e4) => ({ trace1: e4.trace1, trace2: e4.trace2, type: e4.type, z: e4.z, point: e4.point, seg1: e4.seg1, seg2: e4.seg2, distance: 0, requiredDistance: 0 })), n2 = e3.map((e4) => {
const t3 = function(e5) {
const t4 = [];
for (let n4 = 0;n4 < e5.route.length - 1; n4++) {
const o3 = e5.route[n4], i3 = e5.route[n4 + 1];
o3.z === i3.z && t4.push({ minX: Math.min(o3.x, i3.x), maxX: Math.max(o3.x, i3.x), minY: Math.min(o3.y, i3.y), maxY: Math.max(o3.y, i3.y), z: o3.z, a: { x: o3.x, y: o3.y }, b: { x: i3.x, y: i3.y } });
}
return t4;
}(e4), n3 = new Set, o2 = new Map, i2 = new Map;
for (const t4 of e4.route) {
n3.add(t4.z);
const e5 = o2.get(t4.z) ?? [];
e5.push({ x: t4.x, y: t4.y }), o2.set(t4.z, e5);
}
for (const e5 of t3) {
const t4 = i2.get(e5.z) ?? [];
t4.push(e5), i2.set(e5.z, t4);
}
return { route: e4, rootNet: nr(e4), pointsByLayer: o2, segmentsByLayer: i2, segments: t3, vias: e4.vias.map((e5) => ({ x: e5.x, y: e5.y })), traceRadius: e4.traceThickness / 2, viaRadius: e4.viaDiameter / 2, zLayers: n3 };
});
for (let e4 = 0;e4 < n2.length; e4++) {
const o2 = n2[e4];
for (let i2 = e4 + 1;i2 < n2.length; i2++) {
const e5 = n2[i2];
if (o2.rootNet === e5.rootNet)
continue;
const r2 = new Set([...o2.zLayers.values(), ...e5.zLayers.values()]);
for (const n3 of r2) {
const i3 = o2.segmentsByLayer.get(n3) ?? [], r3 = e5.segmentsByLayer.get(n3) ?? [], s3 = o2.pointsByLayer.get(n3) ?? [], a2 = e5.pointsByLayer.get(n3) ?? [], c2 = o2.traceRadius + e5.traceRadius;
for (const s4 of i3)
for (const i4 of r3) {
if (s4.minX - i4.maxX >= c2 || i4.minX - s4.maxX >= c2 || s4.minY - i4.maxY >= c2 || i4.minY - s4.maxY >= c2)
continue;
const r4 = tr(s4.a, s4.b, i4.a, i4.b);
r4 + Wi >= c2 || (r4 <= Xi && Ki(o2.route, s4, e5.route, i4) || or(t2, { trace1: o2.route.connectionName, trace2: e5.route.connectionName, type: r4 <= Xi ? "shared_point" : "trace_clearance", z: n3, distance: r4, requiredDistance: c2, seg1: [s4.a, s4.b], seg2: [i4.a, i4.b] }));
}
for (const i4 of s3)
for (const r4 of a2) {
if (Math.abs(i4.x - r4.x) >= c2 || Math.abs(i4.y - r4.y) >= c2)
continue;
const s4 = Zi(i4, r4);
s4 + Wi >= c2 || (s4 <= Xi && Qi(o2.route, e5.route, n3, i4) || or(t2, { trace1: o2.route.connectionName, trace2: e5.route.connectionName, type: s4 <= Xi ? "shared_point" : "trace_clearance", z: n3, distance: s4, requiredDistance: c2, point: i4, point2: r4 }));
}
}
const s2 = o2.viaRadius + e5.viaRadius;
for (const n3 of o2.vias)
for (const i3 of e5.vias) {
if (Math.abs(n3.x - i3.x) >= s2 || Math.abs(n3.y - i3.y) >= s2)
continue;
const r3 = Zi(n3, i3);
r3 + Wi >= s2 || or(t2, { trace1: o2.route.connectionName, trace2: e5.route.connectionName, type: "via_via_clearance", z: null, distance: r3, requiredDistance: s2, point: n3, point2: i3 });
}
for (const n3 of o2.vias) {
const i3 = o2.viaRadius + e5.traceRadius;
for (const r3 of e5.segments) {
if (n3.x - r3.maxX >= i3 || r3.minX - n3.x >= i3 || n3.y - r3.maxY >= i3 || r3.minY - n3.y >= i3)
continue;
const s3 = er(n3, r3.a, r3.b);
s3 + Wi >= i3 || or(t2, { trace1: o2.route.connectionName, trace2: e5.route.connectionName, type: "via_trace_clearance", z: r3.z, distance: s3, requiredDistance: i3, point: n3, seg2: [r3.a, r3.b] });
}
}
for (const n3 of e5.vias) {
const i3 = e5.viaRadius + o2.traceRadius;
for (const r3 of o2.segments) {
if (n3.x - r3.maxX >= i3 || r3.minX - n3.x >= i3 || n3.y - r3.maxY >= i3 || r3.minY - n3.y >= i3)
continue;
const s3 = er(n3, r3.a, r3.b);
s3 + Wi >= i3 || or(t2, { trace1: o2.route.connectionName, trace2: e5.route.connectionName, type: "via_trace_clearance", z: r3.z, distance: s3, requiredDistance: i3, point: n3, seg1: [r3.a, r3.b] });
}
}
}
}
return t2;
}
var rr = class extends De {
nodeWithPortPoints;
props;
traceThickness;
traceMargin;
viaDiameter;
hyperParameters;
phase = "routing";
round = 0;
routingIterations = 0;
routedCount = 0;
conflictCount = 0;
rerouteCount = 0;
bestConflictCount = 1 / 0;
broadNegotiations = 0;
stagnantRounds = 0;
violations = [];
connections = [];
activeConnectionIndex = -1;
rows = 0;
cols = 0;
plane = 0;
layers = [];
pitchX = 0;
pitchY = 0;
left = 0;
bottom = 0;
routes = new Map;
pairCache = new WeakMap;
queue = [];
traceCost;
viaCost;
fixed;
fixedVia;
history;
viaHistory;
parent;
searchKernel;
heuristicCost;
heuristicCache = new Map;
viaAllowed;
goal = 0;
presentCost = 0.5;
randomState = 1;
constructor(e3) {
super(), this.props = e3, this.nodeWithPortPoints = e3.nodeWithPortPoints, this.traceThickness = e3.traceThickness ?? 0.1, this.traceMargin = e3.traceMargin ?? 0.1, this.viaDiameter = e3.viaDiameter ?? 0.3, this.hyperParameters = { shuffleSeed: 0, greedyMultiplier: 1.1, ...e3.hyperParameters };
for (const t2 of [e3.cellSizeMm ?? 0.1, this.traceThickness, this.viaDiameter, e3.stepMultiplier ?? 1000, e3.maxRounds ?? 200, e3.maxSearchIterations ?? 50000000, this.hyperParameters.greedyMultiplier])
if (!Number.isFinite(t2) || t2 <= 0)
throw new Error("A13 dimensions and search limits must be positive and finite");
if (!Number.isFinite(this.traceMargin) || this.traceMargin < 0)
throw new Error("traceMargin must be nonnegative");
this.MAX_ITERATIONS = 1e8;
}
getSolverName() {
return "HighDensitySolverA13";
}
getConstructorParams() {
return [{ ...this.props }];
}
_setup() {
const e3 = this.nodeWithPortPoints;
if (e3.width <= 0 || e3.height <= 0)
throw new Error("Node dimensions must be positive");
this.cols = Math.ceil(e3.width / (this.props.cellSizeMm ?? 0.1)) + 1, this.rows = Math.ceil(e3.height / (this.props.cellSizeMm ?? 0.1)) + 1, this.pitchX = e3.width / (this.cols - 1), this.pitchY = e3.height / (this.rows - 1), this.left = e3.center.x - e3.width / 2, this.bottom = e3.center.y - e3.height / 2, this.layers = e3.availableZ ?? [...new Set(e3.portPoints.map((e4) => e4.z))].sort((e4, t3) => e4 - t3), this.plane = this.rows * this.cols;
const t2 = this.plane * this.layers.length;
if (t2 > 2000000)
throw new Error("A13 grid exceeds two million states");
this.traceCost = new Uint16Array(t2), this.viaCost = new Uint16Array(this.plane), this.fixed = new Uint8Array(t2), this.fixedVia = new Uint8Array(this.plane), this.history = new Float64Array(t2), this.viaHistory = new Float64Array(this.plane), this.heuristicCost = new Float64Array(t2), this.viaAllowed = new Uint8Array(this.plane);
const n2 = Math.max(this.viaDiameter / 2, this.props.viaMinDistFromBorder ?? this.viaDiameter / 2);
for (let t3 = 0;t3 < this.plane; t3++) {
const o3 = this.point(t3);
o3.x - this.left >= n2 && this.left + e3.width - o3.x >= n2 && o3.y - this.bottom >= n2 && this.bottom + e3.height - o3.y >= n2 && (this.viaAllowed[t3] = 1);
}
this.parent = new Int32Array(t2);
const o2 = this.props.searchBackend === "wasm" ? Bi : zi;
this.searchKernel = new o2(this.cols, this.rows, this.layers.length, this.pitchX, this.pitchY);
const i2 = new Map;
for (const t3 of e3.portPoints) {
if (!this.layers.includes(t3.z))
throw new Error("Port is on an unavailable layer");
const e4 = i2.get(t3.connectionName) ?? [];
e4.push(t3), i2.set(t3.connectionName, e4);
}
for (const e4 of i2.values())
for (const [t3, n3] of $i(e4))
this.connections.push({ start: t3, end: n3, root: t3.rootConnectionName ?? t3.connectionName.replace(/_mst\d+$/, "") });
this.randomState = this.hyperParameters.shuffleSeed + 1 >>> 0, this.queue = this.shuffle(this.connections.map((e4, t3) => t3));
}
shuffle(e3) {
for (let t2 = e3.length - 1;t2 > 0; t2--) {
this.randomState = Math.imul(this.randomState, 1664525) + 1013904223 >>> 0;
const n2 = this.randomState % (t2 + 1);
[e3[t2], e3[n2]] = [e3[n2], e3[t2]];
}
return e3;
}
index(e3) {
const t2 = Math.max(0, Math.min(this.cols - 1, Math.round((e3.x - this.left) / this.pitchX))), n2 = Math.max(0, Math.min(this.rows - 1, Math.round((e3.y - this.bottom) / this.pitchY)));
return this.layers.indexOf(e3.z) * this.plane + n2 * this.cols + t2;
}
point(e3) {
const t2 = e3 % this.plane;
return { x: this.left + t2 % this.cols * this.pitchX, y: this.bottom + Math.floor(t2 / this.cols) * this.pitchY, z: this.layers[Math.floor(e3 / this.plane)] };
}
capsule(e3, t2, n2, o2) {
const i2 = Math.max(0, Math.floor((Math.min(e3.x, t2.x) - n2 - this.left) / this.pitchX)), r2 = Math.min(this.cols - 1, Math.ceil((Math.max(e3.x, t2.x) + n2 - this.left) / this.pitchX)), s2 = Math.max(0, Math.floor((Math.min(e3.y, t2.y) - n2 - this.bottom) / this.pitchY)), a2 = Math.min(this.rows - 1, Math.ceil((Math.max(e3.y, t2.y) + n2 - this.bottom) / this.pitchY)), c2 = t2.x - e3.x, l2 = t2.y - e3.y, h2 = c2 * c2 + l2 * l2;
for (let t3 = s2;t3 <= a2; t3++)
for (let s3 = i2;s3 <= r2; s3++) {
const i3 = this.left + s3 * this.pitchX, r3 = this.bottom + t3 * this.pitchY, a3 = h2 ? Math.max(0, Math.min(1, ((i3 - e3.x) * c2 + (r3 - e3.y) * l2) / h2)) : 0;
(i3 - e3.x - a3 * c2) ** 2 + (r3 - e3.y - a3 * l2) ** 2 < n2 * n2 - 0.000000000001 && o2(t3 * this.cols + s3);
}
}
prepareSearch(e3) {
this.activeConnectionIndex = e3;
const t2 = this.connections[e3];
this.traceCost.fill(0), this.viaCost.fill(0), this.fixed.fill(0), this.fixedVia.fill(0);
for (const [e4, n3] of this.routes)
if (this.connections[e4].root !== t2.root) {
for (const e5 of n3.traceFootprint)
this.traceCost[e5]++;
for (const e5 of n3.viaFootprint)
this.viaCost[e5]++;
}
for (const e4 of this.connections)
if (e4.root !== t2.root)
for (const t3 of [e4.start, e4.end])
this.capsule(t3, t3, this.traceThickness + this.traceMargin, (e5) => {
this.fixed[this.layers.indexOf(t3.z) * this.plane + e5] = 1;
}), this.capsule(t3, t3, (this.traceThickness + this.viaDiameter) / 2 + this.traceMargin, (e5) => {
this.fixedVia[e5] = 1;
});
const n2 = this.index(t2.start);
this.goal = this.index(t2.end);
const o2 = this.point(this.goal), i2 = this.heuristicCache.get(this.goal);
if (i2)
this.heuristicCost = i2;
else {
this.heuristicCost = new Float64Array(this.parent.length);
for (let e5 = 0;e5 < this.layers.length; e5++)
for (let t3 = 0;t3 < this.rows; t3++) {
const n3 = Math.abs(this.bottom + t3 * this.pitchY - o2.y);
for (let i3 = 0;i3 < this.cols; i3++)
this.heuristicCost[e5 * this.plane + t3 * this.cols + i3] = (Math.abs(this.left + i3 * this.pitchX - o2.x) + n3 + (this.layers[e5] === o2.z ? 0 : 0.8)) * this.hyperParameters.greedyMultiplier;
}
const e4 = Math.floor(8388608 / this.heuristicCost.byteLength);
e4 > 0 && (this.heuristicCache.size >= e4 && this.heuristicCache.delete(this.heuristicCache.keys().next().value), this.heuristicCache.set(this.goal, this.heuristicCost));
}
this.searchKernel.begin({ traceCost: this.traceCost, viaCost: this.viaCost, fixed: this.fixed, fixedVia: this.fixedVia, history: this.history, viaHistory: this.viaHistory, heuristicCost: this.heuristicCost, viaAllowed: this.viaAllowed }, n2, this.goal, this.presentCost);
}
_step() {
if (this.phase === "negotiating")
return void this.negotiate();
if (this.activeConnectionIndex < 0) {
const e4 = this.queue.shift();
if (e4 === undefined)
return void (this.phase = "negotiating");
this.prepareSearch(e4);
}
const { status: e3, expansions: t2 } = this.searchKernel.run(this.props.stepMultiplier ?? 1000, (this.props.maxSearchIterations ?? 50000000) - this.routingIterations);
this.routingIterations += t2, e3 === 1 ? (this.searchKernel.copyParents(this.parent), this.commit(this.goal)) : e3 === 2 ? (this.failed = true, this.error = `No path between fixed terminals of ${this.connections[this.activeConnectionIndex].start.connectionName}`) : e3 === 3 && (this.failed = true, this.error = "A13 exhausted its search budget");
}
commit(e3) {
const t2 = this.activeConnectionIndex, n2 = this.connections[t2], o2 = [];
for (let t3 = e3;t3 !== -1; t3 = this.parent[t3])
o2.push(t3);
o2.reverse();
const i2 = [{ ...n2.start }, ...o2.map((e4) => this.point(e4)), { ...n2.end }], r2 = [];
for (const e4 of i2) {
const t3 = r2.at(-1), n3 = r2.at(-2);
t3 && t3.x === e4.x && t3.y === e4.y && t3.z === e4.z || (n3 && t3 && n3.z === e4.z && t3.z === e4.z && (t3.x - n3.x) * (e4.y - t3.y) === (t3.y - n3.y) * (e4.x - t3.x) && r2.pop(), r2.push(e4));
}
r2[0] = { ...n2.start }, r2[r2.length - 1] = { ...n2.end };
const s2 = [], a2 = [];
for (let e4 = 1;e4 < o2.length; e4++)
if (Math.floor(o2[e4] / this.plane) !== Math.floor(o2[e4 - 1] / this.plane)) {
const t3 = this.point(o2[e4]);
s2.push({ x: t3.x, y: t3.y }), a2.push(o2[e4] % this.plane);
}
const c2 = { connectionName: n2.start.connectionName, rootConnectionName: n2.root, regionId: this.nodeWithPortPoints.capacityMeshNodeId, traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, route: r2, vias: s2 }, l2 = new Set, h2 = new Set, d2 = new Set;
for (let e4 = 1;e4 < r2.length; e4++) {
const t3 = r2[e4 - 1], n3 = r2[e4];
t3.z === n3.z && (this.capsule(t3, n3, 0.00001, (e5) => d2.add(this.layers.indexOf(t3.z) * this.plane + e5)), this.capsule(t3, n3, this.traceThickness + this.traceMargin, (e5) => l2.add(this.layers.indexOf(t3.z) * this.plane + e5)), this.capsule(t3, n3, (this.traceThickness + this.viaDiameter) / 2 + this.traceMargin, (e5) => h2.add(e5)));
}
for (const e4 of s2)
this.capsule(e4, e4, (this.viaDiameter + this.traceThickness) / 2 + this.traceMargin, (e5) => {
for (let t3 = 0;t3 < this.layers.length; t3++)
l2.add(t3 * this.plane + e5);
}), this.capsule(e4, e4, this.viaDiameter + this.traceMargin, (e5) => h2.add(e5));
this.routes.has(t2) && this.rerouteCount++, this.routes.set(t2, { output: c2, clearanceOutput: { ...c2, traceThickness: c2.traceThickness + this.traceMargin, viaDiameter: c2.viaDiameter + this.traceMargin }, traceFootprint: [...l2], traceFootprintSet: l2, viaFootprint: [...h2], viaFootprintSet: h2, cells: [...d2], viaCells: a2 }), this.routedCount = this.routes.size, this.activeConnectionIndex = -1;
}
getPair(e3, t2) {
let n2 = this.pairCache.get(e3);
n2 || (n2 = new WeakMap, this.pairCache.set(e3, n2));
let o2 = n2.get(t2);
return o2 || (o2 = { cells: [...e3.cells.filter((e4) => t2.traceFootprintSet.has(e4)), ...t2.cells.filter((t3) => e3.traceFootprintSet.has(t3))], vias: [...e3.viaCells.filter((e4) => t2.viaFootprintSet.has(e4)), ...t2.viaCells.filter((t3) => e3.viaFootprintSet.has(t3))], violations: ir([e3.clearanceOutput, t2.clearanceOutput]) }, n2.set(t2, o2)), o2;
}
negotiate() {
this.round++;
const e3 = new Set, t2 = new Set, n2 = new Set;
for (const [o3, i3] of this.routes)
for (const [r3, s2] of this.routes) {
if (r3 <= o3 || this.connections[o3].root === this.connections[r3].root)
continue;
const a2 = this.getPair(i3, s2);
if (a2.cells.length || a2.vias.length) {
e3.add(o3), e3.add(r3);
for (const e4 of a2.cells)
t2.add(e4);
for (const e4 of a2.vias)
n2.add(e4);
}
}
const o2 = [...this.routes.entries()].sort(([e4], [t3]) => e4 - t3), i2 = new Map;
for (const [, e4] of o2)
for (const t3 of e4.output.route)
i2.has(t3.z) || i2.set(t3.z, []);
const r2 = [];
for (let e4 = 0;e4 < o2.length; e4++)
for (let t3 = e4 + 1;t3 < o2.length; t3++) {
const [n3, s2] = o2[e4], [a2, c2] = o2[t3];
if (this.connections[n3].root !== this.connections[a2].root)
for (const e5 of this.getPair(s2, c2).violations)
e5.requiredDistance === 0 ? i2.get(e5.z).push(e5) : r2.push(e5);
}
this.violations = [...i2.values()].flat().concat(r2);
for (const o3 of this.violations) {
for (let t3 = 0;t3 < this.connections.length; t3++)
[o3.trace1, o3.trace2].includes(this.connections[t3].start.connectionName) && e3.add(t3);
for (const e4 of [o3.point, o3.point2])
if (e4) {
const i3 = this.index({ ...e4, z: this.layers[0] }) % this.plane;
n2.add(i3), o3.z !== null && t2.add(this.layers.indexOf(o3.z) * this.plane + i3);
}
}
if (this.conflictCount = e3.size, this.stagnantRounds = this.conflictCount < this.bestConflictCount ? 0 : this.stagnantRounds + 1, this.bestConflictCount = Math.min(this.bestConflictCount, this.conflictCount), this.stats = { round: this.round, conflictedRoutes: this.conflictCount, geometryViolations: this.violations.length, reroutes: this.rerouteCount, searchExpansions: this.routingIterations }, !this.violations.length && this.routes.size === this.connections.length)
return this.solved = true, this.stats.conflictedRoutes = 0, this.conflictCount = 0, this.bestConflictCount = 0, void (this.phase = "complete");
if (this.round >= (this.props.maxRounds ?? 200))
return this.failed = true, void (this.error = `Negotiation exhausted ${this.round} rounds (${this.conflictCount} conflicted routes)`);
for (const e4 of t2)
this.history[e4] += 0.15;
for (const e4 of n2)
this.viaHistory[e4] += 0.15;
this.presentCost = Math.min(20, 1.08 * this.presentCost), this.stagnantRounds >= 8 ? (this.queue = this.shuffle(this.connections.map((e4, t3) => t3)), this.presentCost = Math.max(0.5, this.presentCost / 2), this.stagnantRounds = 0, this.broadNegotiations++) : this.queue = this.shuffle([...e3]), this.phase = "routing";
}
getOutput() {
return [...this.routes.entries()].sort(([e3], [t2]) => e3 - t2).map(([, e3]) => e3.output);
}
visualize() {
const e3 = this.nodeWithPortPoints, t2 = { title: `A13 negotiated congestion · round ${this.round} · ${this.conflictCount} conflicted routes`, rects: [{ center: e3.center, width: e3.width, height: e3.height, stroke: "#475569", fill: "transparent" }], points: e3.portPoints.map((e4) => ({ ...e4, color: e4.z === 0 ? "red" : "blue", layer: `z${e4.z}`, label: e4.connectionName })), lines: [], circles: [] };
for (const e4 of this.getOutput()) {
for (let n2 = 1;n2 < e4.route.length; n2++) {
const o2 = e4.route[n2 - 1], i2 = e4.route[n2];
o2.z === i2.z && t2.lines.push({ points: [o2, i2], strokeColor: o2.z === 0 ? "#ef4444" : "#3b82f6", strokeWidth: this.traceThickness, layer: `z${o2.z}` });
}
for (const n2 of e4.vias)
t2.circles.push({ center: n2, radius: this.viaDiameter / 2, fill: "#cbd5e1", stroke: "#334155", layer: `z${this.layers.join(",")}` });
}
for (const e4 of this.violations.slice(0, 50))
e4.point && t2.circles.push({ center: e4.point, radius: 0.2, stroke: "#f59e0b", fill: "transparent" });
return t2;
}
};
var ar = (e3) => ({ minX: Math.min(e3[0].x, e3[1].x), maxX: Math.max(e3[0].x, e3[1].x), minY: Math.min(e3[0].y, e3[1].y), maxY: Math.max(e3[0].y, e3[1].y) });
function cr(e3, t2) {
const n2 = e3.x - t2.x, o2 = e3.y - t2.y;
return n2 * n2 + o2 * o2;
}
function lr(e3, t2, n2) {
const o2 = cr(t2, n2);
if (o2 === 0)
return cr(e3, t2);
let i2 = ((e3.x - t2.x) * (n2.x - t2.x) + (e3.y - t2.y) * (n2.y - t2.y)) / o2;
i2 = Math.max(0, Math.min(1, i2));
return cr(e3, { x: t2.x + i2 * (n2.x - t2.x), y: t2.y + i2 * (n2.y - t2.y) });
}
function hr(e3, t2, n2, o2) {
if (_t(e3, t2, n2, o2))
return 0;
const i2 = { x: e3.x, y: e3.y }, r2 = { x: t2.x, y: t2.y }, s2 = { x: n2.x, y: n2.y }, a2 = { x: o2.x, y: o2.y };
return Math.min(lr(i2, s2, a2), lr(r2, s2, a2), lr(s2, i2, r2), lr(a2, i2, r2));
}
var dr = class {
segmentBuckets;
viaBuckets;
CELL_SIZE;
maximumCopperRadius = 0;
constructor(e3, t2 = 1) {
this.segmentBuckets = new Map, this.viaBuckets = new Map, this.CELL_SIZE = t2;
for (const t3 of e3)
if (t3 && t3.connectionName) {
if (this.maximumCopperRadius = Math.max(this.maximumCopperRadius, t3.traceThickness / 2, t3.viaDiameter / 2), t3.route && t3.route.length >= 2)
for (let e4 = 0;e4 < t3.route.length - 1; e4++) {
const n2 = t3.route[e4], o2 = t3.route[e4 + 1];
if (n2.x === o2.x && n2.y === o2.y)
continue;
if (n2.insideJumperPad && o2.insideJumperPad)
continue;
const i2 = [n2, o2], r2 = ar(i2), s2 = { segmentId: `${t3.connectionName}-seg-${e4}`, segment: i2, parentRoute: t3 }, a2 = Math.floor(r2.minX / this.CELL_SIZE), c2 = Math.floor((r2.maxX + 0.000000001) / this.CELL_SIZE), l2 = Math.floor(r2.minY / this.CELL_SIZE), h2 = Math.floor((r2.maxY + 0.000000001) / this.CELL_SIZE);
for (let e5 = a2;e5 <= c2; e5++)
for (let t4 = l2;t4 <= h2; t4++) {
const n3 = `${e5}x${t4}`;
let o3 = this.segmentBuckets.get(n3);
o3 || (o3 = [], this.segmentBuckets.set(n3, o3)), o3.push(s2);
}
}
if (t3.vias && t3.vias.length > 0)
for (let e4 = 0;e4 < t3.vias.length; e4++) {
const n2 = t3.vias[e4];
if (n2 == null)
continue;
const o2 = { viaId: `${t3.connectionName}-via-${e4}`, x: n2.x, y: n2.y, parentRoute: t3 }, i2 = `${Math.floor(n2.x / this.CELL_SIZE)}x${Math.floor(n2.y / this.CELL_SIZE)}`;
let r2 = this.viaBuckets.get(i2);
r2 || (r2 = [], this.viaBuckets.set(i2, r2)), r2.push(o2);
}
} else
console.warn("Skipping route with missing data:", t3);
}
getConflictingRoutesForSegment(e3, t2, n2) {
const o2 = ar([e3, t2]), i2 = n2 + this.maximumCopperRadius, r2 = o2.minX - i2, s2 = o2.minY - i2, a2 = o2.maxX + i2, c2 = o2.maxY + i2, l2 = Math.floor(r2 / this.CELL_SIZE), h2 = Math.floor((a2 + 0.000000001) / this.CELL_SIZE), d2 = Math.floor(s2 / this.CELL_SIZE), u2 = Math.floor((c2 + 0.000000001) / this.CELL_SIZE), p2 = new Map, m2 = new Set, g2 = new Set, f2 = { x: e3.x, y: e3.y }, _2 = { x: t2.x, y: t2.y };
for (let o3 = l2;o3 <= h2; o3++)
for (let i3 = d2;i3 <= u2; i3++) {
const r3 = `${o3}x${i3}`, s3 = this.segmentBuckets.get(r3);
if (s3)
for (const o4 of s3) {
if (m2.has(o4.segmentId))
continue;
m2.add(o4.segmentId);
const i4 = o4.parentRoute, [r4, s4] = o4.segment;
if (e3.z !== t2.z || r4.z !== s4.z || r4.z !== e3.z)
continue;
const a4 = n2 + i4.traceThickness / 2, c3 = a4 * a4, l3 = hr(e3, t2, r4, s4);
if (l3 < c3) {
const e4 = i4.connectionName, t3 = p2.get(e4);
(!t3 || l3 < t3.minDistSq) && p2.set(e4, { route: i4, minDistSq: l3 });
}
}
const a3 = this.viaBuckets.get(r3);
if (a3)
for (const e4 of a3) {
if (g2.has(e4.viaId))
continue;
g2.add(e4.viaId);
const t3 = e4.parentRoute, o4 = { x: e4.x, y: e4.y }, i4 = n2 + t3.viaDiameter / 2, r4 = i4 * i4, s4 = lr(o4, f2, _2);
if (s4 < r4) {
const e5 = t3.connectionName, n3 = p2.get(e5);
(!n3 || s4 < n3.minDistSq) && p2.set(e5, { route: t3, minDistSq: s4 });
}
}
}
const y2 = [];
for (const e4 of p2.values())
y2.push({ conflictingRoute: e4.route, distance: Math.sqrt(e4.minDistSq) });
return y2;
}
removeRoute(e3) {
for (const [t2, n2] of this.segmentBuckets) {
const o2 = n2.filter((t3) => t3.parentRoute.connectionName !== e3);
o2.length === 0 ? this.segmentBuckets.delete(t2) : o2.length !== n2.length && this.segmentBuckets.set(t2, o2);
}
for (const [t2, n2] of this.viaBuckets) {
const o2 = n2.filter((t3) => t3.parentRoute.connectionName !== e3);
o2.length === 0 ? this.viaBuckets.delete(t2) : o2.length !== n2.length && this.viaBuckets.set(t2, o2);
}
}
addRoute(e3) {
if (!e3 || !e3.connectionName)
return void console.warn("Skipping route with missing data:", e3);
this.maximumCopperRadius = Math.max(this.maximumCopperRadius, e3.traceThickness / 2, e3.viaDiameter / 2);
if (e3.route && e3.route.length >= 2)
for (let t2 = 0;t2 < e3.route.length - 1; t2++) {
const n2 = e3.route[t2], o2 = e3.route[t2 + 1];
if (n2.x === o2.x && n2.y === o2.y)
continue;
if (n2.insideJumperPad && o2.insideJumperPad)
continue;
const i2 = [n2, o2], r2 = ar(i2), s2 = { segmentId: `${e3.connectionName}-seg-${t2}`, segment: i2, parentRoute: e3 }, a2 = Math.floor(r2.minX / this.CELL_SIZE), c2 = Math.floor((r2.maxX + 0.000000001) / this.CELL_SIZE), l2 = Math.floor(r2.minY / this.CELL_SIZE), h2 = Math.floor((r2.maxY + 0.000000001) / this.CELL_SIZE);
for (let e4 = a2;e4 <= c2; e4++)
for (let t3 = l2;t3 <= h2; t3++) {
const n3 = `${e4}x${t3}`;
let o3 = this.segmentBuckets.get(n3);
o3 || (o3 = [], this.segmentBuckets.set(n3, o3)), o3.push(s2);
}
}
if (e3.vias && e3.vias.length > 0)
for (let t2 = 0;t2 < e3.vias.length; t2++) {
const n2 = e3.vias[t2];
if (n2 == null)
continue;
const o2 = { viaId: `${e3.connectionName}-via-${t2}`, x: n2.x, y: n2.y, parentRoute: e3 }, i2 = `${Math.floor(n2.x / this.CELL_SIZE)}x${Math.floor(n2.y / this.CELL_SIZE)}`;
let r2 = this.viaBuckets.get(i2);
r2 || (r2 = [], this.viaBuckets.set(i2, r2)), r2.push(o2);
}
}
getConflictingRoutesNearPoint(e3, t2) {
const n2 = t2 + this.maximumCopperRadius, o2 = e3.x - n2, i2 = e3.y - n2, r2 = e3.x + n2, s2 = e3.y + n2, a2 = Math.floor(o2 / this.CELL_SIZE), c2 = Math.floor((r2 + 0.000000001) / this.CELL_SIZE), l2 = Math.floor(i2 / this.CELL_SIZE), h2 = Math.floor((s2 + 0.000000001) / this.CELL_SIZE), d2 = new Map, u2 = new Set, p2 = new Set;
for (let n3 = a2;n3 <= c2; n3++)
for (let o3 = l2;o3 <= h2; o3++) {
const i3 = `${n3}x${o3}`, r3 = this.segmentBuckets.get(i3);
if (r3)
for (const n4 of r3) {
if (u2.has(n4.segmentId))
continue;
u2.add(n4.segmentId);
const o4 = n4.segment[0], i4 = n4.segment[1];
if (o4.z !== i4.z || o4.z !== e3.z)
continue;
const r4 = n4.parentRoute, s4 = { x: n4.segment[0].x, y: n4.segment[0].y }, a3 = { x: n4.segment[1].x, y: n4.segment[1].y }, c3 = t2 + r4.traceThickness / 2, l3 = c3 * c3, h3 = lr(e3, s4, a3);
if (h3 < l3) {
const e4 = r4.connectionName, t3 = d2.get(e4);
(!t3 || h3 < t3.minDistSq) && d2.set(e4, { route: r4, minDistSq: h3 });
}
}
const s3 = this.viaBuckets.get(i3);
if (s3)
for (const n4 of s3) {
if (p2.has(n4.viaId))
continue;
p2.add(n4.viaId);
const o4 = n4.parentRoute, i4 = { x: n4.x, y: n4.y }, r4 = t2 + o4.viaDiameter / 2, s4 = r4 * r4, a3 = cr(e3, i4);
if (a3 < s4) {
const e4 = o4.connectionName, t3 = d2.get(e4);
(!t3 || a3 < t3.minDistSq) && d2.set(e4, { route: o4, minDistSq: a3 });
}
}
}
const m2 = [];
for (const e4 of d2.values())
m2.push({ conflictingRoute: e4.route, distance: Math.sqrt(e4.minDistSq) });
return m2;
}
};
function ur(e3) {
let t2 = e3;
for (let e4 = 0;e4 < 10; e4++)
t2 = 16807 * t2 % 2147483647;
let n2 = t2;
t2 = (69069 * e3 + 1) % 2147483647;
for (let e4 = 0;e4 < 10; e4++)
t2 = 48271 * t2 % 2147483647;
let o2 = t2;
return () => {
let e4 = n2;
n2 = o2, e4 ^= e4 << 23, e4 ^= e4 >>> 17, e4 ^= o2, e4 ^= o2 >>> 26, o2 = e4;
const t3 = (n2 + o2) / 4294967296;
return t3 - Math.floor(t3);
};
}
var pr = { 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 mr(e3, t2) {
if (t2 === 0)
return e3;
if (e3.length === 0)
return e3;
if (e3.length <= 4) {
const n3 = pr[e3.length];
return n3[t2 % n3.length].map((t3) => e3[t3]);
}
const n2 = ur(t2), o2 = e3.slice();
for (let e4 = 0;e4 < o2.length; e4++) {
const t3 = Math.floor(n2() * o2.length), i2 = Math.floor(n2() * (e4 + 1));
[o2[t3], o2[i2]] = [o2[i2], o2[t3]];
}
return o2;
}
var gr = class {
heap = [];
constructor(e3) {
this.heap = [];
for (const t2 of e3)
this.enqueue(t2);
}
dequeue() {
if (this.heap.length === 0)
return null;
const e3 = this.heap[0];
return this.heap[0] = this.heap[this.heap.length - 1], this.heap.pop(), this.heapifyDown(), e3;
}
peek() {
return this.heap.length === 0 ? null : this.heap[0];
}
enqueue(e3) {
this.heap.push(e3), this.heapifyUp();
}
heapifyUp() {
let e3 = this.heap.length - 1;
const t2 = this.heap[e3];
for (;e3 > 0; ) {
const n2 = Math.floor((e3 - 1) / 2), o2 = this.heap[n2];
if (o2.f <= t2.f)
break;
this.heap[e3] = o2, e3 = n2;
}
this.heap[e3] = t2;
}
heapifyDown() {
let e3 = 0;
const t2 = this.heap.length, n2 = this.heap[e3];
if (n2) {
for (;; ) {
const o2 = 2 * e3 + 1;
if (o2 >= t2)
break;
const i2 = o2 + 1;
let r2 = o2;
if (i2 < t2 && this.heap[i2].f < this.heap[o2].f && (r2 = i2), n2.f < this.heap[r2].f)
break;
this.heap[e3] = this.heap[r2], e3 = r2;
}
this.heap[e3] = n2;
}
}
getTopN(e3) {
return [...this.heap].sort((e4, t2) => e4.f - t2.f).slice(0, e3);
}
};
var fr = (e3, t2, n2 = []) => [e3, t2 ? `rootConnectionName: ${t2}` : undefined, ...n2].filter(Boolean).join(`
`);
var _r = class extends ai {
getSolverName() {
return "SingleHighDensityRouteSolver";
}
obstacleRoutes;
bounds;
boundsSize;
boundsCenter;
A;
B;
straightLineDistance;
viaDiameter;
traceThickness;
obstacleMargin;
layerCount;
availableZ;
minCellSize = 0.05;
cellStep = 0.05;
GREEDY_MULTIPLER = 1.1;
numRoutes;
VIA_PENALTY_FACTOR = 0.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;
freePlanarObstaclePoints = new Map;
cachedPlanarTraceProximity;
cachedPlanarViaProximity;
debug_exploredNodesOrdered;
debug_nodesTooCloseToObstacle;
debug_nodePathToParentIntersectsObstacle;
debugEnabled;
initialNodeGridOffset;
constructor(e3) {
super(), this.bounds = e3.bounds, this.connMap = e3.connMap, this.hyperParameters = e3.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 = e3.connectionName, this.rootConnectionName = e3.rootConnectionName, this.regionId = e3.regionId, this.obstacleRoutes = e3.obstacleRoutes, this.A = e3.A, this.B = e3.B, this.viaDiameter = e3.viaDiameter ?? 0.3, this.traceThickness = e3.traceThickness ?? 0.15, this.obstacleMargin = e3.obstacleMargin ?? 0.15, this.layerCount = e3.layerCount ?? 2, this.availableZ = e3.availableZ && e3.availableZ.length > 0 ? [...new Set(e3.availableZ)].sort((e4, t3) => e4 - t3) : Array.from({ length: this.layerCount }, (e4, t3) => t3), this.exploredNodes = new Set, this.straightLineDistance = vt(this.A, this.B), this.futureConnections = e3.futureConnections ?? [], this.NEARBY_SEGMENT_CLEARANCE = e3.nearbySegmentClearance ?? 0.15, this.debugEnabled = e3.captureSearchDebug ?? true, 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 t2 = Math.ceil(5 * (this.numRoutes + 1));
let n2 = this.boundsSize.width / this.cellStep, o2 = this.boundsSize.height / this.cellStep;
for (;n2 * o2 > t2 ** 2 && !(2 * this.cellStep > e3.minDistBetweenEnteringPoints); )
this.cellStep *= 2, n2 = this.boundsSize.width / this.cellStep, o2 = 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 i2 = Math.round(this.bounds.maxX / this.cellStep) + 1, r2 = Math.round(this.bounds.maxY / this.cellStep) + 1;
this.gridWidth = i2 - this.gridMinXIndex + 1, this.gridHeight = r2 - this.gridMinYIndex + 1;
const s2 = Math.abs(this.A.x - this.bounds.minX) < 0.001 && Math.abs(this.B.x - this.bounds.minX) < 0.001 || Math.abs(this.A.x - this.bounds.maxX) < 0.001 && Math.abs(this.B.x - this.bounds.maxX) < 0.001 || Math.abs(this.A.y - this.bounds.minY) < 0.001 && Math.abs(this.B.y - this.bounds.minY) < 0.001 || Math.abs(this.A.y - this.bounds.maxY) < 0.001 && Math.abs(this.B.y - this.bounds.maxY) < 0.001;
this.futureConnections && this.futureConnections.length === 0 && this.obstacleRoutes.length === 0 && !s2 && this.handleSimpleCases();
const a2 = { x: Math.round(e3.A.x / (this.cellStep / 2)) * (this.cellStep / 2), y: Math.round(e3.A.y / (this.cellStep / 2)) * (this.cellStep / 2) };
this.initialNodeGridOffset = { x: a2.x - Math.round(e3.A.x / this.cellStep) * this.cellStep, y: a2.y - Math.round(e3.A.y / this.cellStep) * this.cellStep };
const c2 = { ...e3.A, z: e3.A.z ?? 0, g: 0, h: 0, f: 0, parent: null }, l2 = { ...e3.A, ...a2, z: e3.A.z ?? 0, g: 0, h: 0, f: 0, parent: c2 }, h2 = (Math.abs(l2.x - e3.A.x) > 0.000000001 || Math.abs(l2.y - e3.A.y) > 0.000000001) && (this.isNodeTooCloseToObstacle(l2) || this.isNodeTooCloseToEdge(l2, false) || this.doesPathToParentIntersectObstacle(l2));
this.candidates = new gr([h2 ? c2 : l2]);
}
handleSimpleCases() {
this.solved = true;
const { A: e3, B: t2 } = this, n2 = e3.z === t2.z ? [e3, t2] : [e3, { ...this.boundsCenter, z: this.A.z }, { ...this.boundsCenter, z: t2.z }, t2];
this.solvedPath = { connectionName: this.connectionName, rootConnectionName: this.rootConnectionName, regionId: this.regionId, route: n2, 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(e3, t2, n2, o2) {
if (t2 ??= this.obstacleMargin, n2 && e3.parent) {
const n3 = this.getViasInNodePath(e3.parent);
for (const o3 of n3)
if (vt(e3, o3) < this.viaDiameter / 2 + t2)
return true;
}
const i2 = this.traceThickness + t2, r2 = this.viaDiameter / 2 + this.traceThickness / 2 + t2, s2 = !n2 && this.gridWidth !== undefined && (!o2 || o2.pointQueryProximity === i2) && (this.obstacleViaIndex !== null || this.obstacleSegmentIndexByLayer.has(e3.z)) ? o2?.pointKey ?? this.getNodeKey(e3) : undefined;
if (s2 !== undefined) {
this.cachedPlanarTraceProximity === i2 && this.cachedPlanarViaProximity === r2 || (this.freePlanarObstaclePoints.clear(), this.cachedPlanarTraceProximity = i2, this.cachedPlanarViaProximity = r2);
const t3 = this.freePlanarObstaclePoints.get(s2);
if (t3 && t3.x === e3.x && t3.y === e3.y && t3.z === e3.z)
return false;
}
const a2 = o2?.segments ?? (n2 ? this.obstacleSegments : this.obstacleSegmentsByLayer.get(e3.z)), c2 = o2?.segmentIds ?? (n2 ? this.obstacleSegmentIndex : this.obstacleSegmentIndexByLayer.get(e3.z))?.search(e3.x - i2, e3.y - i2, e3.x + i2, e3.y + i2) ?? [], l2 = o2?.segmentBounds;
if (a2)
for (const t3 of c2) {
const r3 = a2[t3];
if (r3 && !r3.connectedToCurrentConnection && ((n2 || r3.z === e3.z) && !(l2 && (l2.maxX < r3.minX || l2.maxY < r3.minY || l2.minX > r3.maxX || l2.minY > r3.maxY) || o2 && (e3.x + i2 < r3.minX || e3.y + i2 < r3.minY || e3.x - i2 > r3.maxX || e3.y - i2 > r3.maxY) || !(Math.sqrt(vr(e3, r3.A, r3.deltaX, r3.deltaY, r3.lengthSquared)) < i2))))
return true;
}
if (this.obstacleViaIndex) {
const t3 = this.obstacleViaIndex.search(e3.x - r2, e3.y - r2, e3.x + r2, e3.y + r2);
for (const n3 of t3) {
const t4 = this.obstacleVias[n3];
if (t4 && vt(e3, t4) < r2)
return true;
}
}
return s2 !== undefined && this.freePlanarObstaclePoints.set(s2, { x: e3.x, y: e3.y, z: e3.z }), false;
}
isNodeTooCloseToEdge(e3, t2) {
const n2 = t2 ? this.viaDiameter / 2 + this.obstacleMargin / 2 : this.obstacleMargin / 2, o2 = e3.x < this.bounds.minX + n2 || e3.x > this.bounds.maxX - n2 || e3.y < this.bounds.minY + n2 || e3.y > this.bounds.maxY - n2;
return !(o2 && !t2 && (vt(e3, this.B) < 2 * n2 || vt(e3, this.A) < 2 * n2)) && o2;
}
doesPathToParentIntersectObstacle(e3, t2) {
const n2 = e3.parent;
if (!n2)
return false;
const o2 = t2?.segments ?? this.obstacleSegmentsByLayer.get(e3.z);
if (!o2)
return false;
const i2 = e3.z === n2.z && this.obstacleSegments.length > 0 ? this.NEARBY_SEGMENT_CLEARANCE : 0, r2 = Math.min(e3.x, n2.x), s2 = Math.max(e3.x, n2.x), a2 = Math.min(e3.y, n2.y), c2 = Math.max(e3.y, n2.y), l2 = t2?.segmentIds ?? this.obstacleSegmentIndexByLayer.get(e3.z)?.search(r2 - i2, a2 - i2, s2 + i2, c2 + i2) ?? [], h2 = t2?.segmentBounds, d2 = n2.x - e3.x, u2 = n2.y - e3.y, p2 = d2 ** 2 + u2 ** 2;
for (const m2 of l2) {
const l3 = o2[m2];
if (l3 && !l3.connectedToCurrentConnection && (l3.z === e3.z && !(h2 && (h2.maxX < l3.minX || h2.maxY < l3.minY || h2.minX > l3.maxX || h2.minY > l3.maxY) || t2 && (s2 + i2 < l3.minX || c2 + i2 < l3.minY || r2 - i2 > l3.maxX || a2 - i2 > l3.maxY)))) {
if (_t(e3, n2, l3.A, l3.B))
return true;
if (i2 > 0 && xr(e3, n2, d2, u2, p2, l3) < i2)
return true;
}
}
return false;
}
getPlanarObstacleQuery(e3, t2, n2) {
const o2 = e3.parent;
if (!o2)
return;
const i2 = t2 ? undefined : this.obstacleSegmentIndexByLayer.get(e3.z), r2 = t2?.segments ?? this.obstacleSegmentsByLayer.get(e3.z);
if (!r2 || !t2 && !i2)
return;
const s2 = this.traceThickness + this.obstacleMargin, a2 = e3.z === o2.z && this.obstacleSegments.length > 0 ? this.NEARBY_SEGMENT_CLEARANCE : 0, c2 = Math.min(e3.x - s2, o2.x - a2), l2 = Math.min(e3.y - s2, o2.y - a2), h2 = Math.max(e3.x + s2, o2.x + a2), d2 = Math.max(e3.y + s2, o2.y + a2);
if (t2) {
const e4 = t2.segmentBounds ??= { minX: c2, minY: l2, maxX: h2, maxY: d2 };
return e4.minX = c2, e4.minY = l2, e4.maxX = h2, e4.maxY = d2, t2.pointQueryProximity = s2, t2.pointKey = n2, t2;
}
return { segments: r2, segmentIds: i2.search(c2, l2, h2, d2), pointQueryProximity: s2, pointKey: n2 };
}
getPlanarNeighborObstacleQuery(e3) {
const t2 = this.obstacleSegmentIndexByLayer.get(e3.z), n2 = this.obstacleSegmentsByLayer.get(e3.z);
if (!t2 || !n2)
return;
const o2 = this.traceThickness + this.obstacleMargin, i2 = this.obstacleSegments.length > 0 ? this.NEARBY_SEGMENT_CLEARANCE : 0, { minX: r2, minY: s2, maxX: a2, maxY: c2 } = this.bounds, l2 = br(e3.x - this.cellStep, r2, a2), h2 = br(e3.y - this.cellStep, s2, c2), d2 = br(e3.x + this.cellStep, r2, a2), u2 = br(e3.y + this.cellStep, s2, c2);
return { segments: n2, segmentIds: t2.search(Math.min(l2 - o2, e3.x - i2), Math.min(h2 - o2, e3.y - i2), Math.max(d2 + o2, e3.x + i2), Math.max(u2 + o2, e3.y + i2)) };
}
buildObstacleIndexes() {
if (this.freePlanarObstaclePoints.clear(), this.obstacleRoutes.length === 0)
return this.obstacleSegmentIndex = null, this.obstacleSegmentsByLayer.clear(), this.obstacleSegmentIndexByLayer.clear(), void (this.obstacleViaIndex = null);
const e3 = [], t2 = [];
for (const n2 of this.obstacleRoutes) {
const o2 = this.connMap?.areIdsConnected?.(this.connectionName, n2.connectionName) ?? false;
for (const t3 of yr(n2)) {
const n3 = t3.B.x - t3.A.x, i2 = t3.B.y - t3.A.y;
e3.push({ ...t3, deltaX: n3, deltaY: i2, lengthSquared: n3 ** 2 + i2 ** 2, minX: Math.min(t3.A.x, t3.B.x), minY: Math.min(t3.A.y, t3.B.y), maxX: Math.max(t3.A.x, t3.B.x), maxY: Math.max(t3.A.y, t3.B.y), connectedToCurrentConnection: o2 });
}
for (const e4 of n2.vias)
t2.push(e4);
}
if (this.obstacleSegments = e3, this.obstacleVias = t2, this.obstacleSegmentsByLayer.clear(), this.obstacleSegmentIndexByLayer.clear(), e3.length > 0) {
const t3 = new je(e3.length);
for (const n2 of e3)
t3.add(n2.minX, n2.minY, n2.maxX, n2.maxY);
t3.finish(), this.obstacleSegmentIndex = t3;
for (const t4 of e3) {
if (t4.connectedToCurrentConnection)
continue;
const e4 = this.obstacleSegmentsByLayer.get(t4.z);
e4 ? e4.push(t4) : this.obstacleSegmentsByLayer.set(t4.z, [t4]);
}
for (const [e4, t4] of this.obstacleSegmentsByLayer) {
const n2 = new je(t4.length);
for (const e5 of t4)
n2.add(e5.minX, e5.minY, e5.maxX, e5.maxY);
n2.finish(), this.obstacleSegmentIndexByLayer.set(e4, n2);
}
} else
this.obstacleSegmentIndex = null;
if (t2.length > 0) {
const e4 = new je(t2.length);
for (const n2 of t2)
e4.add(n2.x, n2.y, n2.x, n2.y);
e4.finish(), this.obstacleViaIndex = e4;
} else
this.obstacleViaIndex = null;
}
computeH(e3) {
return vt(e3, this.B) + (e3.z !== this.B.z ? this.viaPenaltyDistance : 0);
}
computeG(e3) {
return (e3.parent?.g ?? 0) + (e3.z === e3.parent?.z ? 0 : this.viaPenaltyDistance) + vt(e3, e3.parent);
}
computeF(e3, t2) {
return e3 + t2 * this.GREEDY_MULTIPLER;
}
setNodeCosts(e3) {
e3.g = this.computeG(e3), e3.h = this.computeH(e3), e3.f = this.computeF(e3.g, e3.h);
}
getNodeKey(e3) {
const t2 = Math.round(e3.x / this.cellStep) - this.gridMinXIndex, n2 = Math.round(e3.y / this.cellStep) - this.gridMinYIndex;
return (e3.z * this.gridHeight + n2) * this.gridWidth + t2;
}
getNeighbors(e3) {
const t2 = [];
let n2, o2 = false;
const { maxX: i2, minX: r2, maxY: s2, minY: a2 } = this.bounds;
for (let c2 = -1;c2 <= 1; c2++)
for (let l2 = -1;l2 <= 1; l2++) {
if (c2 === 0 && l2 === 0)
continue;
const h2 = { x: br(e3.x + c2 * this.cellStep, r2, i2), y: br(e3.y + l2 * this.cellStep, a2, s2), z: e3.z, g: e3.g, h: e3.h, f: e3.f, parent: e3 }, d2 = this.getNodeKey(h2);
if (this.exploredNodes.has(d2))
continue;
o2 || (n2 = this.getPlanarNeighborObstacleQuery(e3), o2 = true);
const u2 = this.getPlanarObstacleQuery(h2, n2, d2);
this.isNodeTooCloseToObstacle(h2, undefined, false, u2) ? (this.debugEnabled && this.debug_nodesTooCloseToObstacle.add(d2), this.exploredNodes.add(d2)) : this.isNodeTooCloseToEdge(h2, false) ? this.exploredNodes.add(d2) : this.doesPathToParentIntersectObstacle(h2, u2) ? (this.debugEnabled && this.debug_nodePathToParentIntersectsObstacle.add(d2), this.exploredNodes.add(d2)) : (this.setNodeCosts(h2), t2.push(h2));
}
for (const n3 of this.availableZ) {
if (n3 === e3.z)
continue;
const o3 = { x: e3.x, y: e3.y, z: n3, g: e3.g, h: e3.h, f: e3.f, parent: e3 };
this.exploredNodes.has(this.getNodeKey(o3)) || this.isNodeTooCloseToObstacle(o3, this.viaDiameter / 2 + this.obstacleMargin / 2, true) || this.isNodeTooCloseToEdge(o3, true) || (this.setNodeCosts(o3), t2.push(o3));
}
return t2;
}
getNodePath(e3) {
const t2 = [];
for (;e3; )
t2.push(e3), e3 = e3.parent;
return t2;
}
getViasInNodePath(e3) {
const t2 = this.viasInPathByNode.get(e3);
if (t2)
return t2;
const n2 = e3.parent, o2 = n2 ? this.getViasInNodePath(n2) : [], i2 = n2 && e3.z !== n2.z ? [{ x: e3.x, y: e3.y }, ...o2] : o2;
return this.viasInPathByNode.set(e3, i2), i2;
}
setSolvedPath(e3) {
const t2 = this.getNodePath(e3);
t2.reverse();
const n2 = [];
for (let e4 = 0;e4 < t2.length - 1; e4++)
t2[e4].z !== t2[e4 + 1].z && n2.push({ x: t2[e4].x, y: t2[e4].y });
this.solvedPath = { connectionName: this.connectionName, rootConnectionName: this.rootConnectionName, regionId: this.regionId, traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, route: t2.map((e4) => ({ x: e4.x, y: e4.y, z: e4.z })).concat([this.B]), vias: n2 };
}
computeProgress(e3, t2, n2) {
if (t2 === undefined || n2 === undefined)
return Number.NaN;
n2 || (t2 += this.viaPenaltyDistance);
const o2 = 1 - t2 / this.straightLineDistance;
return Math.max(this.progress || 0, 2 / Math.PI * Math.atan(0.112 * o2 / (1 - o2)));
}
_step() {
let e3 = this.candidates.dequeue(), t2 = e3 ? this.getNodeKey(e3) : undefined;
for (;e3 && t2 && this.exploredNodes.has(t2); )
e3 = this.candidates.dequeue(), t2 = e3 ? this.getNodeKey(e3) : undefined;
if (!e3 || !t2)
return this.failed = true, void (this.error = "Ran out of candidate nodes to explore");
this.exploredNodes.add(t2), this.debugEnabled && this.debug_exploredNodesOrdered.push({ key: t2, x: Math.round(e3.x / this.cellStep) * this.cellStep + this.initialNodeGridOffset.x, y: Math.round(e3.y / this.cellStep) * this.cellStep + this.initialNodeGridOffset.y, z: e3.z });
const n2 = vt(e3, this.B);
this.progress = this.computeProgress(e3, n2, e3.z === this.B.z), n2 <= this.cellStep * Math.SQRT2 && e3.z === this.B.z && !this.doesPathToParentIntersectObstacle({ ...e3, parent: e3, x: this.B.x, y: this.B.y }) && (this.solved = true, this.setSolvedPath(e3));
const o2 = this.getNeighbors(e3);
for (const e4 of o2)
this.candidates.enqueue(e4);
}
visualize() {
const e3 = { lines: [], points: [], rects: [], circles: [] };
e3.points.push({ x: this.A.x, y: this.A.y, label: fr(this.connectionName, this.rootConnectionName, ["Input A", `z: ${this.A.z}`]), color: "orange" }), e3.points.push({ x: this.B.x, y: this.B.y, label: fr(this.connectionName, this.rootConnectionName, ["Input B", `z: ${this.B.z}`]), color: "orange" }), e3.lines.push({ points: [this.A, this.B], strokeColor: "rgba(255, 0, 0, 0.5)", label: fr(this.connectionName, this.rootConnectionName, ["Direct Input Connection"]) });
for (let t2 = 0;t2 < this.obstacleRoutes.length; t2++) {
const n2 = this.obstacleRoutes[t2];
for (let o2 = 0;o2 < n2.route.length - 1; o2++) {
const i2 = n2.route[o2].z;
e3.lines.push({ points: [n2.route[o2], n2.route[o2 + 1]], strokeColor: i2 === 0 ? "rgba(255, 0, 0, 0.75)" : "rgba(255, 128, 0, 0.25)", strokeWidth: n2.traceThickness, label: fr(n2.connectionName, n2.rootConnectionName, ["Obstacle Route"]), layer: `obstacle${t2.toString()}` });
}
}
for (let t2 = 0;t2 < this.debug_exploredNodesOrdered.length; t2++) {
const { key: n2, x: o2, y: i2, z: r2 } = this.debug_exploredNodesOrdered[t2];
this.debug_nodesTooCloseToObstacle.has(n2) || (this.debug_nodePathToParentIntersectsObstacle.has(n2) || e3.rects.push({ center: { x: o2 + r2 * this.cellStep / 20, y: i2 + r2 * this.cellStep / 20 }, fill: r2 === 0 ? `rgba(255,0,255,${0.3 - t2 / this.debug_exploredNodesOrdered.length * 0.2})` : `rgba(0,0,255,${0.3 - t2 / this.debug_exploredNodesOrdered.length * 0.2})`, width: 0.9 * this.cellStep, height: 0.9 * this.cellStep, label: `Explored (z=${r2})` }));
}
if (this.candidates.peek()) {
const t2 = this.candidates.peek();
e3.rects.push({ center: { x: t2.x + t2.z * this.cellStep / 20, y: t2.y + t2.z * this.cellStep / 20 }, fill: "rgba(0, 255, 0, 0.8)", width: 0.9 * this.cellStep, height: 0.9 * this.cellStep, label: `Next (z=${t2.z})` });
}
for (const t2 of this.obstacleRoutes)
for (const n2 of t2.vias)
e3.circles.push({ center: { x: n2.x, y: n2.y }, radius: this.viaDiameter / 2, fill: "rgba(255, 0, 0, 0.5)", label: "Via" });
if (this.solvedPath) {
e3.lines.push({ points: this.solvedPath.route, strokeColor: "green", label: fr(this.solvedPath.connectionName, this.solvedPath.rootConnectionName, ["Solved Route"]) });
for (const t2 of this.solvedPath.vias)
e3.circles.push({ center: t2, radius: this.viaDiameter / 2, fill: "green", label: fr(this.solvedPath.connectionName, this.solvedPath.rootConnectionName, ["Via"]) });
}
return e3;
}
};
function yr(e3) {
const t2 = [];
for (let n2 = 0;n2 < e3.route.length - 1; n2++)
e3.route[n2].z === e3.route[n2 + 1].z && t2.push({ z: e3.route[n2].z, A: e3.route[n2], B: e3.route[n2 + 1] });
return t2;
}
function br(e3, t2, n2) {
return Math.max(t2, Math.min(e3, n2));
}
function xr(e3, t2, n2, o2, i2, r2) {
return Math.sqrt(Math.min(vr(e3, r2.A, r2.deltaX, r2.deltaY, r2.lengthSquared), vr(t2, r2.A, r2.deltaX, r2.deltaY, r2.lengthSquared), vr(r2.A, e3, n2, o2, i2), vr(r2.B, e3, n2, o2, i2)));
}
function vr(e3, t2, n2, o2, i2) {
if (i2 === 0) {
const n3 = e3.x - t2.x, o3 = e3.y - t2.y;
return n3 * n3 + o3 * o3;
}
const r2 = Math.max(0, Math.min(1, ((e3.x - t2.x) * n2 + (e3.y - t2.y) * o2) / i2)), s2 = t2.x + r2 * n2, a2 = t2.y + r2 * o2, c2 = e3.x - s2, l2 = e3.y - a2;
return c2 * c2 + l2 * l2;
}
var Ir = class extends _r {
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 = false;
FUTURE_CONNECTION_VIA_TRACE_CLEARANCE = 0.1;
futureConnectionPoints;
futureConnectionSegmentsCache = null;
constructor(e3) {
super({ ...e3, nearbySegmentClearance: e3.nearbySegmentClearance ?? (e3.traceThickness ?? 0.15) / 2 + (e3.obstacleMargin ?? 0.15) });
for (const t3 in e3.hyperParameters)
this[t3] = e3.hyperParameters[t3];
const t2 = this.boundsSize.width / this.viaDiameter, n2 = Math.max(1, this.numRoutes);
this.VIA_PENALTY_FACTOR = t2 / n2 * 0.3 * this.VIA_PENALTY_FACTOR_2, this.futureConnectionPoints = this.futureConnections.flatMap((e4) => e4.points);
}
getClosestFutureConnectionPoint(e3) {
let t2 = 1 / 0, n2 = null;
for (const o2 of this.futureConnectionPoints) {
const i2 = vt(e3, o2) + (e3.z !== o2.z ? this.viaPenaltyDistance : 0);
i2 < t2 && (t2 = i2, n2 = o2);
}
return n2;
}
getFutureConnectionSegments() {
if (this.futureConnectionSegmentsCache)
return this.futureConnectionSegmentsCache;
const e3 = [];
for (const t2 of this.futureConnections) {
if (t2.connectionName === this.connectionName || (this.connMap?.areIdsConnected?.(this.connectionName, t2.connectionName) ?? false))
continue;
const [n2, ...o2] = t2.points;
if (n2)
for (const i2 of o2)
Math.abs(n2.x - i2.x) < 0.000000001 && Math.abs(n2.y - i2.y) < 0.000000001 || e3.push({ connectionName: t2.connectionName, start: n2, end: i2 });
}
return this.futureConnectionSegmentsCache = e3, e3;
}
isViaTooCloseToFutureConnectionTrace(e3) {
const t2 = this.viaDiameter / 2 + this.traceThickness / 2 + this.FUTURE_CONNECTION_VIA_TRACE_CLEARANCE;
for (const n2 of this.getFutureConnectionSegments())
if (xt(e3, n2.start, n2.end) < t2)
return true;
return false;
}
isNodeTooCloseToObstacle(e3, t2, n2, o2) {
return !!super.isNodeTooCloseToObstacle(e3, t2, n2, o2) || !(!n2 || !this.isViaTooCloseToFutureConnectionTrace(e3));
}
diminishCloseToGoal(e3) {
const t2 = vt(e3, this.B);
return 1 - Math.exp(-t2 / this.straightLineDistance * 5);
}
getFutureConnectionPenalty(e3, t2) {
let n2 = 0;
const o2 = this.getClosestFutureConnectionPoint(e3), i2 = vt(e3, this.B);
if (o2) {
const r2 = vt(e3, o2);
if (i2 <= r2)
return 0;
const s2 = r2 / (this.viaDiameter * this.FUTURE_CONNECTION_PROXIMITY_VD);
n2 = (t2 ? this.straightLineDistance * this.FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR : this.straightLineDistance * this.FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR) * Math.exp(5 * -s2);
}
return n2;
}
computeH(e3) {
const t2 = vt(e3, this.B) ** 1.6;
this.straightLineDistance;
return t2 + (e3.z !== this.B.z ? this.viaPenaltyDistance : 0) + this.getFutureConnectionPenalty(e3, e3.z !== e3.parent?.z);
}
computeG(e3) {
const t2 = Math.abs(e3.x - e3.parent.x), n2 = Math.abs(e3.y - e3.parent.y), o2 = Math.sqrt(t2 ** 2 + n2 ** 2), i2 = e3.z % 2 == 0, r2 = this.FLIP_TRACE_ALIGNMENT_DIRECTION ? i2 ? t2 : n2 : i2 ? n2 : t2;
return (e3.parent?.g ?? 0) + (e3.z === e3.parent?.z ? 0 : this.viaPenaltyDistance) + o2 + r2 * this.MISALIGNED_DIST_PENALTY_FACTOR + this.getFutureConnectionPenalty(e3, e3.z !== e3.parent?.z);
}
setNodeCosts(e3) {
const t2 = Math.abs(e3.x - e3.parent.x), n2 = Math.abs(e3.y - e3.parent.y), o2 = Math.sqrt(t2 ** 2 + n2 ** 2), i2 = e3.z % 2 == 0, r2 = this.FLIP_TRACE_ALIGNMENT_DIRECTION ? i2 ? t2 : n2 : i2 ? n2 : t2, s2 = (e3.parent?.g ?? 0) + (e3.z === e3.parent?.z ? 0 : this.viaPenaltyDistance) + o2 + r2 * this.MISALIGNED_DIST_PENALTY_FACTOR, a2 = vt(e3, this.B) ** 1.6 + (e3.z !== this.B.z ? this.viaPenaltyDistance : 0), c2 = this.getFutureConnectionPenalty(e3, e3.z !== e3.parent?.z);
e3.g = s2 + c2, e3.h = a2 + c2, e3.f = this.computeF(e3.g, e3.h);
}
};
var Sr = (e3) => {
let t2 = 1 / 0;
const n2 = e3.portPoints;
for (let e4 = 0;e4 < n2.length; e4++)
for (let o2 = e4 + 1;o2 < n2.length; o2++) {
const i2 = n2[e4], r2 = n2[o2];
if (i2.z !== r2.z)
continue;
if (i2.rootConnectionName && i2.rootConnectionName === r2.rootConnectionName)
continue;
const s2 = Math.sqrt((i2.x - r2.x) ** 2 + (i2.y - r2.y) ** 2);
t2 = Math.min(t2, s2);
}
return t2 === 1 / 0 ? 0 : t2;
};
var Cr = (e3) => {
const t2 = new Map, n2 = new Map, o2 = new Map;
for (const { connectionName: i2, rootConnectionName: r2, x: s2, y: a2, z: c2 } of e3.portPoints) {
r2 && n2.set(i2, r2);
let e4 = t2.get(i2), l2 = o2.get(i2);
e4 && l2 || (e4 = [], l2 = new Set, t2.set(i2, e4), o2.set(i2, l2));
const h2 = c2 ?? 0, d2 = `${s2.toFixed(6)},${a2.toFixed(6)},${h2}`;
l2.has(d2) || (l2.add(d2), e4.push({ x: s2, y: a2, z: h2 }));
}
return { connectionPointsByName: t2, rootConnectionNameByConnectionName: n2, minDistBetweenEnteringPoints: Sr(e3) };
};
var Pr = (e3, t2, n2 = []) => [e3, t2 ? `rootConnectionName: ${t2}` : undefined, ...n2].filter(Boolean).join(`
`);
var Mr = (e3) => `${e3.x.toFixed(6)},${e3.y.toFixed(6)},${e3.z}`;
var wr = class extends ai {
getSolverName() {
return "IntraNodeRouteSolver";
}
nodeWithPortPoints;
colorMap;
unsolvedConnections;
originalConnectionPointsByName;
rootConnectionNameByConnectionName;
totalConnections;
solvedRoutes;
failedSubSolvers;
hyperParameters;
minDistBetweenEnteringPoints;
viaDiameter;
traceWidth;
obstacleMargin;
captureSearchDebug;
rerouteAttemptsByConnection;
POSTROUTE_VIA_TRACE_CLEARANCE = 0.1;
MAX_POSTROUTE_REPAIR_ATTEMPTS = 2;
activeSubSolver = null;
connMap;
get failedSolvers() {
return this.failedSubSolvers;
}
get activeSolver() {
return this.activeSubSolver;
}
constructor(e3) {
const { nodeWithPortPoints: t2, colorMap: n2 } = e3;
super(), this.nodeWithPortPoints = t2, this.colorMap = n2 ?? {}, this.solvedRoutes = [], this.hyperParameters = e3.hyperParameters ?? {}, this.failedSubSolvers = [], this.connMap = e3.connMap, this.viaDiameter = e3.viaDiameter ?? 0.3, this.traceWidth = e3.traceWidth ?? 0.15, this.obstacleMargin = e3.obstacleMargin ?? 0.15, this.captureSearchDebug = e3.captureSearchDebug ?? true;
const o2 = e3.precomputedIntraNodeRouteParams ?? Cr(t2);
this.rootConnectionNameByConnectionName = new Map(o2.rootConnectionNameByConnectionName), this.originalConnectionPointsByName = new Map(Array.from(o2.connectionPointsByName.entries()).map(([e4, t3]) => [e4, t3.map((e5) => ({ ...e5 }))])), this.unsolvedConnections = Array.from(this.originalConnectionPointsByName.entries().map(([e4, t3]) => ({ connectionName: e4, rootConnectionName: this.rootConnectionNameByConnectionName.get(e4), points: [...t3] }))), this.rerouteAttemptsByConnection = new Map, this.hyperParameters.SHUFFLE_SEED && (this.unsolvedConnections = mr(this.unsolvedConnections, this.hyperParameters.SHUFFLE_SEED ?? 0), this.unsolvedConnections = this.unsolvedConnections.map(({ points: e4, ...t3 }, n3) => ({ ...t3, points: mr(e4, 7117 * n3 + (this.hyperParameters.SHUFFLE_SEED ?? 0)) }))), this.totalConnections = this.unsolvedConnections.length, this.MAX_ITERATIONS = 1000 * this.totalConnections ** 1.5, this.minDistBetweenEnteringPoints = o2.minDistBetweenEnteringPoints;
}
computeProgress() {
return (this.solvedRoutes.length + (this.activeSubSolver?.progress || 0)) / this.totalConnections;
}
getSingleRouteSolverOpts(e3) {
const { connectionName: t2, rootConnectionName: n2, points: o2 } = e3;
return { connectionName: t2, rootConnectionName: n2, regionId: this.nodeWithPortPoints.capacityMeshNodeId, minDistBetweenEnteringPoints: this.minDistBetweenEnteringPoints, bounds: so(this.nodeWithPortPoints), A: { x: o2[0].x, y: o2[0].y, z: o2[0].z }, B: { x: o2[o2.length - 1].x, y: o2[o2.length - 1].y, z: o2[o2.length - 1].z }, obstacleRoutes: this.connMap ? this.solvedRoutes.filter((e4) => !this.connMap.areIdsConnected(e4.connectionName, t2)) : this.solvedRoutes, futureConnections: this.unsolvedConnections, layerCount: this.nodeWithPortPoints.portPoints.reduce((e4, t3) => Math.max(e4, (t3.z ?? 0) + 1), 2), availableZ: this.nodeWithPortPoints.availableZ && this.nodeWithPortPoints.availableZ.length > 0 ? this.nodeWithPortPoints.availableZ : [...new Set(this.nodeWithPortPoints.portPoints.map((e4) => e4.z ?? 0))].sort((e4, t3) => e4 - t3), hyperParameters: this.hyperParameters, connMap: this.connMap, viaDiameter: this.viaDiameter, traceThickness: this.traceWidth, obstacleMargin: this.obstacleMargin, captureSearchDebug: this.captureSearchDebug };
}
trySolveSamePointLayerChange(e3) {
const t2 = this.getSingleRouteSolverOpts(e3), n2 = new Ir(t2), { A: o2, B: i2 } = t2, r2 = { x: o2.x, y: o2.y };
if (!Nr(n2, r2, o2))
return false;
const s2 = [{ x: o2.x, y: o2.y, z: o2.z }, { ...r2, z: o2.z }, { ...r2, z: i2.z }, { x: i2.x, y: i2.y, z: i2.z }].filter((e4, t3, n3) => t3 === 0 || Math.abs(e4.x - n3[t3 - 1].x) > 0.000001 || Math.abs(e4.y - n3[t3 - 1].y) > 0.000001 || e4.z !== n3[t3 - 1].z);
return this.solvedRoutes.push({ connectionName: e3.connectionName, rootConnectionName: e3.rootConnectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, traceThickness: this.traceWidth, viaDiameter: this.viaDiameter, route: s2, vias: [{ x: r2.x, y: r2.y }] }), true;
}
queueExtraBranchesForMultiPointConnection(e3) {
const [t2, ...n2] = ((e4) => {
const t3 = new Set, n3 = [];
for (const o2 of e4) {
const e5 = Mr(o2);
t3.has(e5) || (t3.add(e5), n3.push(o2));
}
return n3;
})(e3.points);
if (!t2 || n2.length <= 1)
return false;
for (const o2 of n2)
this.unsolvedConnections.push({ connectionName: e3.connectionName, rootConnectionName: e3.rootConnectionName, points: [t2, o2] });
return true;
}
getAvailableZLayers() {
return this.nodeWithPortPoints.availableZ && this.nodeWithPortPoints.availableZ.length > 0 ? [...new Set(this.nodeWithPortPoints.availableZ)].sort((e3, t2) => e3 - t2) : [...new Set(this.nodeWithPortPoints.portPoints.map((e3) => e3.z ?? 0))].sort((e3, t2) => e3 - t2);
}
getFirstSolvedViaTraceConflict() {
if (this.solvedRoutes.length < 2)
return null;
const e3 = new dr(this.solvedRoutes), t2 = this.getAvailableZLayers();
for (const n2 of this.solvedRoutes) {
const o2 = n2.viaDiameter / 2 + this.POSTROUTE_VIA_TRACE_CLEARANCE;
for (const i2 of n2.vias)
for (const r2 of t2) {
const t3 = e3.getConflictingRoutesNearPoint({ x: i2.x, y: i2.y, z: r2 }, o2).filter(({ conflictingRoute: e4 }) => e4.connectionName !== n2.connectionName && !this.connMap?.areIdsConnected(n2.connectionName, e4.connectionName));
if (t3.length > 0)
return { route: n2, via: i2, conflictingRoute: t3[0].conflictingRoute };
}
}
return null;
}
queueConnectionForPostrouteRepair(e3) {
const t2 = this.originalConnectionPointsByName.get(e3);
return !(!t2 || t2.length < 2) && (this.solvedRoutes = this.solvedRoutes.filter((t3) => t3.connectionName !== e3), this.unsolvedConnections.push({ connectionName: e3, rootConnectionName: this.rootConnectionNameByConnectionName.get(e3), points: t2.map((e4) => ({ ...e4 })) }), this.rerouteAttemptsByConnection.set(e3, (this.rerouteAttemptsByConnection.get(e3) ?? 0) + 1), true);
}
_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((e4) => e4.error).join(`
`), this.failed = true));
const e3 = this.unsolvedConnections.pop();
if (this.progress = this.computeProgress(), !e3) {
const e4 = this.getFirstSolvedViaTraceConflict();
if (e4) {
if ((this.rerouteAttemptsByConnection.get(e4.route.connectionName) ?? 0) >= this.MAX_POSTROUTE_REPAIR_ATTEMPTS)
return this.error = ["Post-route via/trace clearance repair exceeded retry budget", `route: ${e4.route.connectionName}`, `conflicts with: ${e4.conflictingRoute.connectionName}`, `via: (${e4.via.x.toFixed(3)}, ${e4.via.y.toFixed(3)})`].join(`
`), void (this.failed = true);
if (this.queueConnectionForPostrouteRepair(e4.route.connectionName))
return void (this.progress = this.computeProgress());
}
return void (this.solved = this.failedSubSolvers.length === 0);
}
if (e3.points.length !== 1 && !(e3.points.length > 2 && this.queueExtraBranchesForMultiPointConnection(e3))) {
if (e3.points.length === 2) {
const [t2, n2] = e3.points, o2 = Math.abs(t2.x - n2.x) < 0.000001, i2 = Math.abs(t2.y - n2.y) < 0.000001;
if (o2 && i2 && t2.z === n2.z)
return;
if (o2 && i2 && t2.z !== n2.z && this.trySolveSamePointLayerChange(e3))
return;
}
this.activeSubSolver = new Ir(this.getSingleRouteSolverOpts(e3));
}
}
visualize() {
const e3 = { lines: [], points: [], rects: [], circles: [] };
for (const t3 of this.nodeWithPortPoints.portPoints)
e3.points.push({ x: t3.x, y: t3.y, label: Pr(t3.connectionName, t3.rootConnectionName, [`layer: ${t3.z}`]), color: this.colorMap[t3.connectionName] ?? "blue" });
for (let t3 = 0;t3 < this.solvedRoutes.length; t3++) {
const n3 = this.solvedRoutes[t3];
if (n3.route.length > 0) {
const o3 = this.colorMap[n3.connectionName] ?? "blue", i3 = n3.rootConnectionName ?? this.rootConnectionNameByConnectionName.get(n3.connectionName);
for (let r3 = 0;r3 < n3.route.length - 1; r3++) {
const s2 = n3.route[r3], a2 = n3.route[r3 + 1];
e3.lines.push({ points: [s2, a2], label: Pr(n3.connectionName, i3, [`layer: ${s2.z}`]), strokeColor: s2.z === 0 ? Oo(o3, 0.2) : Oo(o3, 0.8), layer: `route-layer-${s2.z}`, step: t3, strokeWidth: n3.traceThickness });
}
for (const r3 of n3.vias)
e3.circles.push({ center: { x: r3.x, y: r3.y }, radius: n3.viaDiameter / 2, fill: Oo(o3, 0.5), layer: "via", step: t3, label: Pr(n3.connectionName, i3, ["via"]) });
}
}
const t2 = so(this.nodeWithPortPoints), { minX: n2, minY: o2, maxX: i2, maxY: r2 } = t2;
return e3.lines.push({ points: [{ x: n2, y: o2 }, { x: i2, y: o2 }, { x: i2, y: r2 }, { x: n2, y: r2 }, { x: n2, y: o2 }], strokeColor: "rgba(255, 0, 0, 0.25)", strokeDash: "4 4", layer: "border" }), e3;
}
};
var Nr = (e3, t2, n2, o2) => {
const i2 = { x: t2.x, y: t2.y, z: n2.z, parent: { x: n2.x, y: n2.y, z: n2.z, g: 0, h: 0, f: 0, parent: null }, g: 0, h: 0, f: 0 };
return !e3.isNodeTooCloseToObstacle(i2, e3.viaDiameter / 2 + e3.obstacleMargin / 2, true) && !e3.isNodeTooCloseToEdge(i2, true);
};
var Tr = (e3) => Math.round(200 * e3) / 200;
var Rr = (e3) => typeof structuredClone == "function" ? structuredClone(e3) : JSON.parse(JSON.stringify(e3));
ro();
var Er = class extends wr {
getSolverName() {
return "CachedIntraNodeRouteSolver";
}
cacheProvider;
cacheHit = false;
hasAttemptedToUseCache = false;
initialUnsolvedConnections;
constructor(e3) {
super(e3), this.cacheProvider = e3.cacheProvider === undefined ? io() : e3.cacheProvider, this.initialUnsolvedConnections = this.unsolvedConnections.map((e4) => ({ ...e4, points: e4.points.map((e5) => ({ ...e5 })) })), (this.solved || this.failed) && this.cacheProvider && !this.cacheHit && this.saveToCacheSync();
}
_step() {
if (!this.hasAttemptedToUseCache && this.cacheProvider && this.attemptToUseCacheSync())
return;
const e3 = this.solved, t2 = this.failed;
super._step(), !this.cacheProvider || this.cacheHit || !this.solved && !this.failed || e3 || t2 || this.saveToCacheSync();
}
computeCacheKeyAndTransform() {
const e3 = this.nodeWithPortPoints.center, t2 = this.initialUnsolvedConnections.map(({ connectionName: t3, rootConnectionName: n3, points: o3 }) => ({ connectionName: t3, rootConnectionName: n3, points: o3.map((n4) => ({ connectionName: t3, x: Tr(n4.x - e3.x), y: Tr(n4.y - e3.y), z: n4.z ?? 0 })) })), n2 = [...this.nodeWithPortPoints.portPoints].sort((e4, t3) => e4.connectionName !== t3.connectionName ? e4.connectionName.localeCompare(t3.connectionName) : (e4.portPointId ?? "") !== (t3.portPointId ?? "") ? (e4.portPointId ?? "").localeCompare(t3.portPointId ?? "") : e4.x !== t3.x ? e4.x - t3.x : e4.y !== t3.y ? e4.y - t3.y : (e4.z ?? 0) - (t3.z ?? 0)).map((t3) => ({ connectionName: t3.connectionName, rootConnectionName: t3.rootConnectionName, portPointId: t3.portPointId, prevPortPointId: t3.prevPortPointId, nextPortPointId: t3.nextPortPointId, x: Tr(t3.x - e3.x), y: Tr(t3.y - e3.y), z: t3.z ?? 0 })), o2 = Object.fromEntries(Object.entries(this.hyperParameters ?? {}).filter(([, e4]) => e4 !== undefined).sort(([e4], [t3]) => e4.localeCompare(t3))), i2 = this.connMap ? this.initialUnsolvedConnections.map(({ connectionName: e4 }) => ({ connectionName: e4, connectedIds: [...new Set(this.connMap.getIdsConnectedToNet(e4) ?? [])].sort() })) : undefined, r2 = { cacheSchemaVersion: 5, node: { width: Tr(this.nodeWithPortPoints.width), height: Tr(this.nodeWithPortPoints.height), center: { x: Tr(this.nodeWithPortPoints.center.x), y: Tr(this.nodeWithPortPoints.center.y) }, availableZ: this.nodeWithPortPoints.availableZ ? [...this.nodeWithPortPoints.availableZ].sort() : undefined, portPoints: n2 }, normalizedConnections: t2, normalizedHyperParameters: o2, minDistBetweenEnteringPoints: Tr(this.minDistBetweenEnteringPoints), traceWidth: Tr(this.traceWidth), viaDiameter: Tr(this.viaDiameter), obstacleMargin: Tr(this.obstacleMargin), normalizedConnMap: i2 }, s2 = import_object_hash.default(r2, { algorithm: "passthrough", respectType: false, unorderedObjects: false }), a2 = `intranode-solver:${import_object_hash.default(s2)}`, c2 = {};
return this.cacheKey = a2, this.cacheToSolveSpaceTransform = c2, { cacheKey: a2, cacheToSolveSpaceTransform: c2 };
}
applyCachedSolution(e3) {
e3.success ? (this.solvedRoutes = Rr(e3.solvedRoutes), this.solved = true, this.failed = false) : (this.solvedRoutes = [], this.failedSubSolvers = [], this.solved = false, this.failed = true, this.error = e3.error ?? this.error), this.unsolvedConnections = [], this.activeSubSolver = null, this.cacheHit = true, this.progress = 1;
}
attemptToUseCacheSync() {
if (this.hasAttemptedToUseCache = true, !this.cacheProvider?.isSyncCache)
return false;
if (!this.cacheKey)
try {
this.computeCacheKeyAndTransform();
} catch (e3) {
return console.error("Error computing cache key:", e3), false;
}
if (!this.cacheKey)
return console.error("Failed to compute cache key."), false;
try {
const e3 = this.cacheProvider.getCachedSolutionSync(this.cacheKey);
if (e3 != null)
return this.applyCachedSolution(e3), true;
} catch (e3) {
console.error("Error attempting to use cache:", e3);
}
return false;
}
saveToCacheSync() {
if (!this.cacheProvider?.isSyncCache)
return;
if (!this.cacheKey)
try {
this.computeCacheKeyAndTransform();
} catch (e4) {
return void console.error("Error computing cache key during save:", e4);
}
if (!this.cacheKey)
return void console.error("Failed to compute cache key before saving.");
const e3 = this.failed ? { success: false, error: this.error ?? undefined } : { success: true, solvedRoutes: Rr(this.solvedRoutes) };
try {
this.cacheProvider.setCachedSolutionSync(this.cacheKey, e3);
} catch (e4) {
console.error("Error saving solution to cache:", e4);
}
}
};
var Ar = (e3, t2) => {
const n2 = {};
return e3.portPoints.forEach((t3, o2) => {
n2[t3.connectionName] = `hsl(${360 * o2 / e3.portPoints.length}, 100%, 50%)`;
}), n2;
};
var Or = class extends ai {
getSolverName() {
return "ViaPossibilitiesSolver2";
}
bounds;
maxViaCount;
portPairMap;
colorMap;
nodeWidth;
availableZ;
hyperParameters;
VIA_INTERSECTION_BUFFER_DISTANCE = 0.05;
PLACEHOLDER_WALL_BUFFER_DISTANCE = 0.1;
NEW_HEAD_WALL_BUFFER_DISTANCE = 0.05;
viaDiameter;
unprocessedConnections;
completedPaths = new Map;
placeholderPaths = new Map;
currentHead;
currentConnectionName;
currentPath;
currentViaCount;
constructor({ nodeWithPortPoints: e3, colorMap: t2, hyperParameters: n2, viaDiameter: o2 }) {
super(), this.MAX_ITERATIONS = 1e5, this.colorMap = t2 ?? Ar(e3), this.maxViaCount = 5, this.bounds = so(e3), this.nodeWidth = this.bounds.maxX - this.bounds.minX, this.portPairMap = ((e4) => {
const t3 = new Map;
return e4.portPoints.forEach((e5) => {
t3.has(e5.connectionName) ? t3.get(e5.connectionName).end = e5 : t3.set(e5.connectionName, { start: e5, end: null, connectionName: e5.connectionName });
}), t3;
})(e3), this.stats.solutionsFound = 0, this.availableZ = e3.availableZ ?? [0, 1], this.hyperParameters = n2 ?? { SHUFFLE_SEED: 0 }, this.viaDiameter = o2 ?? 0.3, this.unprocessedConnections = Array.from(this.portPairMap.keys()).sort(), n2?.SHUFFLE_SEED && (this.unprocessedConnections = mr(this.unprocessedConnections, n2.SHUFFLE_SEED));
for (const [e4, { start: t3, end: n3 }] of this.portPairMap.entries())
if (t3.z === n3.z) {
const o3 = Math.abs(t3.x - n3.x) < 0.000000001, i3 = Math.abs(t3.y - n3.y) < 0.000000001;
o3 || i3 ? this.placeholderPaths.set(e4, [t3, this._padByPlaceholderWallBuffer(t3), this._padByPlaceholderWallBuffer(n3), n3]) : this.placeholderPaths.set(e4, [t3, n3]);
} else {
const o3 = (t3.x + n3.x) / 2, i3 = (t3.y + n3.y) / 2, r2 = this._padByPlaceholderWallBuffer({ x: o3, y: i3, z: t3.z }), s2 = this._padByPlaceholderWallBuffer({ x: o3, y: i3, z: n3.z });
this.placeholderPaths.set(e4, [t3, this._padByPlaceholderWallBuffer(t3), r2, s2, this._padByPlaceholderWallBuffer(n3), n3]);
}
this.currentConnectionName = this.unprocessedConnections.pop();
const i2 = this.portPairMap.get(this.currentConnectionName).start;
this.currentHead = this._padByNewHeadWallBuffer(i2), this.currentPath = [i2, this.currentHead], this.currentViaCount = 0, this.placeholderPaths.delete(this.currentConnectionName);
}
_padByNewHeadWallBuffer(e3) {
return { x: Ot(e3.x, this.bounds.minX + this.NEW_HEAD_WALL_BUFFER_DISTANCE, this.bounds.maxX - this.NEW_HEAD_WALL_BUFFER_DISTANCE), y: Ot(e3.y, this.bounds.minY + this.NEW_HEAD_WALL_BUFFER_DISTANCE, this.bounds.maxY - this.NEW_HEAD_WALL_BUFFER_DISTANCE), z: e3.z };
}
_padByPlaceholderWallBuffer(e3) {
return { x: Ot(e3.x, this.bounds.minX + this.PLACEHOLDER_WALL_BUFFER_DISTANCE, this.bounds.maxX - this.PLACEHOLDER_WALL_BUFFER_DISTANCE), y: Ot(e3.y, this.bounds.minY + this.PLACEHOLDER_WALL_BUFFER_DISTANCE, this.bounds.maxY - this.PLACEHOLDER_WALL_BUFFER_DISTANCE), z: e3.z };
}
_step() {
if (this.solved)
return;
const e3 = this.portPairMap.get(this.currentConnectionName).end, t2 = [this.currentHead, e3];
let n2 = null, o2 = null;
const i2 = (e4) => {
for (const i3 of e4.values())
for (let e5 = 0;e5 < i3.length - 1; e5++) {
const r3 = [i3[e5], i3[e5 + 1]];
if (r3[0].x === r3[1].x && r3[0].y === r3[1].y)
continue;
if (r3[0].z !== this.currentHead.z)
continue;
const s2 = It(t2[0], t2[1], r3[0], r3[1]);
if (s2) {
const e6 = vt(this.currentHead, s2);
if (e6 < 0.000001)
continue;
(!n2 || e6 < n2.dist) && (n2 = { point: s2, dist: e6 }, o2 = r3[0].z);
}
}
};
i2(this.completedPaths), i2(this.placeholderPaths);
const r2 = this.currentHead.z !== e3.z;
if ((n2 || r2) && (this.currentViaCount++, this.currentViaCount >= this.maxViaCount))
return this.failed = true, void (this.error = `Exceeded max via count of ${this.maxViaCount}`);
if (n2) {
let e4;
const t3 = n2.dist;
if (t3 <= this.VIA_INTERSECTION_BUFFER_DISTANCE + 0.000001)
e4 = Yt(this.currentHead, n2.point);
else {
const o3 = n2.point, i4 = o3.x - this.currentHead.x, r4 = o3.y - this.currentHead.y, s3 = (t3 - this.VIA_INTERSECTION_BUFFER_DISTANCE) / t3;
e4 = { x: this.currentHead.x + i4 * s3, y: this.currentHead.y + r4 * s3 };
}
const i3 = this.availableZ.find((e5) => e5 !== o2);
if (i3 === undefined)
return this.error = "Could not determine next Z level for via placement!", void (this.failed = true);
const r3 = { ...e4, z: this.currentHead.z }, s2 = { ...e4, z: i3 };
this.currentPath.push(r3, s2), this.currentHead = s2;
} else if (r2) {
let t3;
const n3 = vt(this.currentHead, e3);
if (n3 < this.VIA_INTERSECTION_BUFFER_DISTANCE)
t3 = Yt(this.currentHead, e3);
else {
const o4 = e3.x - this.currentHead.x, i4 = e3.y - this.currentHead.y, r4 = (n3 - this.VIA_INTERSECTION_BUFFER_DISTANCE) / n3;
t3 = { x: this.currentHead.x + o4 * r4, y: this.currentHead.y + i4 * r4 };
}
const o3 = e3.z, i3 = { ...t3, z: this.currentHead.z }, r3 = { ...t3, z: o3 };
this.currentPath.push(i3, r3), this.currentHead = r3;
} else if (this.currentPath.push(e3), this.completedPaths.set(this.currentConnectionName, this.currentPath), this.unprocessedConnections.length === 0)
this.solved = true, this.stats.solutionsFound = 1;
else {
this.currentConnectionName = this.unprocessedConnections.pop();
const { start: e4 } = this.portPairMap.get(this.currentConnectionName);
this.currentHead = this._padByNewHeadWallBuffer(e4), this.currentPath = [e4, this.currentHead], this.currentViaCount = 0, this.placeholderPaths.delete(this.currentConnectionName);
}
}
visualize() {
const e3 = { points: [], lines: [], circles: [], rects: [], title: "Via Possibilities Solver State", coordinateSystem: "cartesian" }, t2 = this.colorMap;
e3.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: 0.01 });
for (const [t3, { start: n3, end: o2 }] of this.portPairMap.entries()) {
const i2 = this.colorMap[t3] ?? "black";
e3.points.push({ x: n3.x, y: n3.y, color: i2, label: `Port: ${t3} Start (z${n3.z})` }), e3.points.push({ x: o2.x, y: o2.y, color: i2, label: `Port: ${t3} End (z${o2.z})` });
}
const n2 = (n3, o2) => {
for (const [i2, r2] of n3.entries()) {
const n4 = t2[i2] ?? "black";
for (let t3 = 0;t3 < r2.length - 1; t3++) {
const s2 = r2[t3], a2 = r2[t3 + 1];
s2.x === a2.x && s2.y === a2.y && s2.z !== a2.z ? e3.circles.push({ center: { x: s2.x, y: s2.y }, radius: this.viaDiameter / 2, fill: Oo(n4, 0.5), label: `${o2}: ${i2} Via (z${s2.z}->z${a2.z})` }) : e3.lines.push({ points: [s2, a2], strokeColor: Oo(n4, 0.5), strokeDash: s2.z === 0 ? undefined : [0.1, 0.1], strokeWidth: 0.1, label: `${o2}: ${i2} (z${s2.z})` });
}
}
};
if (n2(this.placeholderPaths, "Placeholder"), n2(this.completedPaths, "Completed"), this.currentPath && this.currentPath.length > 0) {
const n3 = t2[this.currentConnectionName] ?? "orange";
for (let t3 = 0;t3 < this.currentPath.length - 1; t3++) {
const o2 = this.currentPath[t3], i2 = this.currentPath[t3 + 1];
o2.x === i2.x && o2.y === i2.y && o2.z !== i2.z ? e3.circles.push({ center: { x: o2.x, y: o2.y }, radius: this.viaDiameter / 2, fill: Oo(n3, 0.5), label: `Current: ${this.currentConnectionName} Via (z${o2.z}->z${i2.z})` }) : e3.lines.push({ points: [o2, i2], strokeColor: Oo(n3, 0.5), strokeWidth: 0.15, strokeDash: "2,2", label: `Current: ${this.currentConnectionName} (z${o2.z})` });
}
e3.points.push({ x: this.currentHead.x, y: this.currentHead.y, color: "green", label: `Current Head: ${this.currentConnectionName} (z${this.currentHead.z})` });
}
return e3;
}
};
var kr = (e3) => Math.round(1e4 * e3);
var Dr = (e3) => {
let t2 = 0, n2 = [];
const o2 = [];
for (const t3 of e3.portPoints) {
if (n2.some((e4) => e4.connectionName === t3.connectionName))
continue;
if (o2.some((e4) => e4.connectionName === t3.connectionName))
continue;
const i3 = { connectionName: t3.connectionName, z: t3.z, points: [{ x: kr(t3.x), y: kr(t3.y), z: t3.z }] };
for (const n3 of e3.portPoints)
t3.connectionName === n3.connectionName && (t3.x === n3.x && t3.y === n3.y || i3.points.push({ x: kr(n3.x), y: kr(n3.y), z: n3.z }));
i3.points.some((e4) => e4.z !== i3.z) ? o2.push(i3) : n2.push(i3);
}
n2 = n2.filter((e4) => e4.points.length > 1);
for (let e4 = 0;e4 < n2.length; e4++)
for (let o3 = e4 + 1;o3 < n2.length; o3++) {
const i3 = n2[e4], r2 = n2[o3];
i3.z === r2.z && _t(i3.points[0], i3.points[1], r2.points[0], r2.points[1]) && t2++;
}
let i2 = 0;
for (let e4 = 0;e4 < o2.length; e4++)
for (let t3 = e4 + 1;t3 < o2.length; t3++) {
const n3 = o2[e4], r2 = o2[t3];
_t(n3.points[0], n3.points[1], r2.points[0], r2.points[1]) && i2++;
}
return { numSameLayerCrossings: t2, numEntryExitLayerChanges: o2.length, numTransitionPairCrossings: i2 };
};
var Lr = (e3) => {
const { start: t2, end: n2, segmentsPerPolyline: o2, viaPositions: i2, viaCount: r2, availableZ: s2 } = e3, a2 = function(e4, t3) {
const n3 = new Array(e4).fill(0);
if (t3 === 0)
return n3;
if (t3 === e4)
return n3.fill(1);
if (t3 <= e4 / 2) {
const o3 = Math.floor(e4 / t3), i3 = Math.floor((e4 - (o3 * (t3 - 1) + 1)) / 2);
for (let e5 = 0;e5 < t3; e5++)
n3[i3 + e5 * o3] = 1;
} else {
const o3 = e4 - t3, i3 = Math.floor(e4 / o3), r3 = Math.floor((e4 - (i3 * (o3 - 1) + 1)) / 2);
n3.fill(1);
for (let e5 = 0;e5 < o3; e5++)
n3[r3 + e5 * i3] = 0;
}
return n3;
}(o2, r2), c2 = a2.map(() => null);
let l2 = 0, h2 = t2.z1;
const d2 = s2.indexOf(t2.z1);
for (let e4 = 0;e4 < a2.length; e4++)
if (a2[e4] === 1) {
const t3 = s2[(d2 + l2 + 1) % s2.length];
c2[e4] = { ...i2[l2], z1: h2, z2: t3 }, h2 = t3, l2++;
}
let u2 = t2;
for (let e4 = 0;e4 < c2.length; e4++) {
if (c2[e4]) {
u2 = c2[e4];
continue;
}
let t3 = n2, o3 = c2.length;
for (let n3 = e4 + 1;n3 < c2.length; n3++)
if (c2[n3]) {
t3 = c2[n3], o3 = n3;
break;
}
const i3 = o3 - e4, r3 = t3.x - u2.x, s3 = t3.y - u2.y;
for (let t4 = 1 / (i3 + 1), n3 = 0;e4 + n3 !== o3; t4 += 1 / (i3 + 1), n3++)
c2[e4 + n3] = { x: u2.x + r3 * t4, y: u2.y + s3 * t4, z1: u2.z2, z2: u2.z2 };
}
return c2;
};
var zr = 0.000000001;
function Br(e3, t2) {
return Math.abs(e3 - t2) < zr;
}
function Fr(e3) {
return `${Math.round(e3.x / zr)}:${Math.round(e3.y / zr)}`;
}
function jr(e3, t2, n2, o2) {
return e3 * o2 - t2 * n2;
}
function $r(e3, t2, n2, o2) {
const i2 = { x: t2.x - e3.x, y: t2.y - e3.y }, r2 = { x: o2.x - n2.x, y: o2.y - n2.y }, s2 = jr(i2.x, i2.y, r2.x, r2.y), a2 = { x: n2.x - e3.x, y: n2.y - e3.y };
if (Br(s2, 0))
return null;
const c2 = jr(a2.x, a2.y, r2.x, r2.y) / s2, l2 = jr(a2.x, a2.y, i2.x, i2.y) / s2;
return c2 >= -1e-9 && c2 <= 1 + zr && l2 >= -1e-9 && l2 <= 1 + zr ? { x: e3.x + c2 * i2.x, y: e3.y + c2 * i2.y } : null;
}
function Yr(e3, t2, n2) {
return Br(Math.hypot(e3.x - t2.x, e3.y - t2.y) + Math.hypot(e3.x - n2.x, e3.y - n2.y), Math.hypot(t2.x - n2.x, t2.y - n2.y));
}
function Xr(e3, t2) {
const n2 = [], o2 = new Map;
for (const t3 of e3) {
const e4 = [t3.start, ...t3.mPoints, t3.end];
for (let i4 = 0;i4 < e4.length - 1; i4++) {
const r3 = e4[i4], s3 = e4[i4 + 1], a3 = r3.z2;
if (n2.push({ start: { x: r3.x, y: r3.y }, end: { x: s3.x, y: s3.y }, connectionName: t3.connectionName, layer: a3 }), r3.z1 !== r3.z2) {
const e5 = Fr(r3);
o2.has(e5) || o2.set(e5, { point: r3, connectionName: t3.connectionName });
}
}
const i3 = e4[e4.length - 1];
if (i3.z1 !== i3.z2) {
const e5 = Fr(i3);
o2.has(e5) || o2.set(e5, { point: i3, connectionName: t3.connectionName });
}
}
const i2 = [{ start: { x: t2.minX, y: t2.minY }, end: { x: t2.maxX, y: t2.minY }, connectionName: null, layer: 0 }, { start: { x: t2.maxX, y: t2.minY }, end: { x: t2.maxX, y: t2.maxY }, connectionName: null, layer: 0 }, { start: { x: t2.maxX, y: t2.maxY }, end: { x: t2.minX, y: t2.maxY }, connectionName: null, layer: 0 }, { start: { x: t2.minX, y: t2.maxY }, end: { x: t2.minX, y: t2.minY }, connectionName: null, layer: 0 }];
n2.push(...i2);
const r2 = new Map;
let s2 = 0;
function a2(e4, t3) {
const n3 = Fr(e4);
let i3 = r2.get(n3);
if (!i3) {
const t4 = o2.has(n3);
i3 = { id: s2++, x: e4.x, y: e4.y, isVia: t4, connectionNames: new Set, outgoingEdges: [] }, r2.set(n3, i3), t4 && o2.get(n3) && i3.connectionNames.add(o2.get(n3).connectionName);
}
return t3 && i3.connectionNames.add(t3), i3;
}
for (const e4 of n2)
a2(e4.start, e4.connectionName), a2(e4.end, e4.connectionName);
const c2 = new Map;
for (const e4 of n2)
c2.set(e4, []);
for (let e4 = 0;e4 < n2.length; e4++)
for (let t3 = e4 + 1;t3 < n2.length; t3++) {
if (n2[e4].layer !== n2[t3].layer)
continue;
const o3 = $r(n2[e4].start, n2[e4].end, n2[t3].start, n2[t3].end);
o3 && (a2(o3), Yr(o3, n2[e4].start, n2[e4].end) && c2.get(n2[e4]).push(o3), Yr(o3, n2[t3].start, n2[t3].end) && c2.get(n2[t3]).push(o3));
}
const l2 = [];
let h2 = 0;
for (const e4 of n2) {
const t3 = [e4.start, ...c2.get(e4), e4.end];
t3.sort((t4, n4) => {
const o3 = e4.end.x - e4.start.x, i3 = e4.end.y - e4.start.y;
return Math.abs(o3) > Math.abs(i3) ? (t4.x - e4.start.x) / o3 - (n4.x - e4.start.x) / o3 : Math.abs(i3) < zr ? 0 : (t4.y - e4.start.y) / i3 - (n4.y - e4.start.y) / i3;
});
const n3 = [];
if (t3.length > 0) {
n3.push(t3[0]);
for (let e5 = 1;e5 < t3.length; e5++)
Br(t3[e5].x, t3[e5 - 1].x) && Br(t3[e5].y, t3[e5 - 1].y) || n3.push(t3[e5]);
}
for (let t4 = 0;t4 < n3.length - 1; t4++) {
const o3 = n3[t4], i3 = n3[t4 + 1], r3 = a2(o3, e4.connectionName), s3 = a2(i3, e4.connectionName);
if (r3 === s3)
continue;
const c3 = { id: h2++, origin: r3, twin: null, next: null, face: null, connectionName: e4.connectionName, layer: e4.layer, visited: false }, d3 = { id: h2++, origin: s3, twin: c3, next: null, face: null, connectionName: e4.connectionName, layer: e4.layer, visited: false };
c3.twin = d3, l2.push(c3, d3), r3.outgoingEdges.push(c3), s3.outgoingEdges.push(d3);
}
}
for (const e4 of r2.values()) {
e4.outgoingEdges.sort((t4, n3) => {
const o3 = t4.twin.origin, i3 = n3.twin.origin;
return Math.atan2(o3.y - e4.y, o3.x - e4.x) - Math.atan2(i3.y - e4.y, i3.x - e4.x);
});
const t3 = e4.outgoingEdges.length;
for (let n3 = 0;n3 < t3; n3++) {
const o3 = e4.outgoingEdges[n3], i3 = e4.outgoingEdges[(n3 - 1 + t3) % t3];
o3.twin && (o3.twin.next = i3);
}
}
let u2 = 0, p2 = null, m2 = -1 / 0;
for (const e4 of l2) {
if (e4.visited)
continue;
const t3 = { id: u2++, outerComponent: e4, innerComponents: [], isOuterFace: false };
let n3 = e4;
const o3 = [], i3 = [], r3 = new Set;
let s3 = 0;
do {
if (!n3 || n3.visited) {
console.warn("Face traversal encountered visited edge or null, breaking loop.", t3.id), o3.length = 0;
break;
}
n3.visited = true, n3.face = t3, o3.push(n3), i3.push(n3.origin), n3.connectionName !== null && r3.add(n3.connectionName);
const e5 = n3.origin, a3 = n3.twin.origin;
s3 += e5.x * a3.y - a3.x * e5.y, n3 = n3.next;
} while (n3 !== e4 && n3 !== null);
if (n3 === e4) {
if (s3 = 0.5 * Math.abs(s3), s3 > m2 && (m2 = s3, p2 && (p2.isOuterFace = false), p2 = t3, t3.isOuterFace = true), !t3.isOuterFace && o3.length > 0) {
if ([...r3].filter((e5) => e5 !== null).length > 1) {
let e5 = false;
for (const t4 of i3)
if (t4.isVia) {
e5 = true;
break;
}
if (!e5)
return true;
}
}
} else
console.warn(`Face ${t3.id} did not close properly.`), u2--;
}
return false;
}
var Wr = (e3) => {
if (e3.length === 0)
return [[]];
const t2 = [];
for (let n2 = 0;n2 < e3.length; n2++) {
const o2 = e3[n2], i2 = [...e3.slice(0, n2), ...e3.slice(n2 + 1)], r2 = Wr(i2);
for (const e4 of r2)
t2.push([o2, ...e4]);
}
return t2;
};
var Vr = 0.000000001;
function Hr(e3, t2, n2 = 0.000000001) {
return Math.abs(e3 - t2) < n2;
}
function Gr(e3, t2, n2, o2) {
return e3 * o2 - t2 * n2;
}
function Ur(e3, t2, n2, o2) {
const i2 = { x: t2.x - e3.x, y: t2.y - e3.y }, r2 = { x: o2.x - n2.x, y: o2.y - n2.y }, s2 = Gr(i2.x, i2.y, r2.x, r2.y);
if (Hr(s2, 0))
return null;
const a2 = { x: n2.x - e3.x, y: n2.y - e3.y }, c2 = Gr(a2.x, a2.y, r2.x, r2.y) / s2, l2 = Gr(a2.x, a2.y, i2.x, i2.y) / s2;
return c2 < -1e-9 || c2 > 1 + Vr || l2 < -1e-9 || l2 > 1 + Vr ? null : { x: e3.x + c2 * i2.x, y: e3.y + c2 * i2.y };
}
function Zr(e3) {
let t2 = 0;
for (let n2 = 0, o2 = e3.length;n2 < o2; ++n2) {
const i2 = (n2 + 1) % o2;
t2 += e3[n2].x * e3[i2].y - e3[i2].x * e3[n2].y;
}
return 0.5 * t2;
}
function qr(e3) {
let t2 = 0, n2 = 0, o2 = 0;
for (let i2 = 0, r2 = e3.length;i2 < r2; ++i2) {
const s2 = (i2 + 1) % r2, a2 = e3[i2].x * e3[s2].y - e3[s2].x * e3[i2].y;
t2 += a2, n2 += (e3[i2].x + e3[s2].x) * a2, o2 += (e3[i2].y + e3[s2].y) * a2;
}
return t2 *= 0.5, Hr(t2, 0) ? null : (n2 /= 6 * t2, o2 /= 6 * t2, { x: n2, y: o2 });
}
var Jr = class {
x;
y;
out;
connectionNames;
constructor(e3, t2) {
this.x = e3, this.y = t2, this.out = [], this.connectionNames = new Set;
}
};
var Qr = class {
orig;
dest;
twin;
next;
visited;
constructor(e3, t2) {
this.orig = e3, this.dest = t2, this.twin = null, this.next = null, this.visited = false;
}
};
function Kr(e3, t2) {
const n2 = [...t2, ...[{ start: { x: e3.minX, y: e3.minY }, end: { x: e3.maxX, y: e3.minY } }, { start: { x: e3.maxX, y: e3.minY }, end: { x: e3.maxX, y: e3.maxY } }, { start: { x: e3.maxX, y: e3.maxY }, end: { x: e3.minX, y: e3.maxY } }, { start: { x: e3.minX, y: e3.maxY }, end: { x: e3.minX, y: e3.minY } }]], o2 = n2.map(() => []);
for (let e4 = 0;e4 < n2.length; ++e4) {
const t3 = n2[e4];
o2[e4].push(t3.start, t3.end);
}
for (let e4 = 0;e4 < n2.length; ++e4)
for (let t3 = e4 + 1;t3 < n2.length; ++t3) {
const i3 = Ur(n2[e4].start, n2[e4].end, n2[t3].start, n2[t3].end);
i3 && (o2[e4].push(i3), o2[t3].push(i3));
}
const i2 = new Map, r2 = [];
function s2(e4) {
const t3 = function(e5, t4 = 0.000000001) {
return `${Math.round(e5.x / t4)}:${Math.round(e5.y / t4)}`;
}(e4);
if (!i2.has(t3)) {
const n3 = r2.length;
return i2.set(t3, n3), r2.push(new Jr(e4.x, e4.y)), n3;
}
return i2.get(t3);
}
const a2 = [];
for (let e4 = 0;e4 < n2.length; ++e4) {
const t3 = n2[e4], i3 = o2[e4].slice();
i3.sort((e5, n3) => {
const o3 = t3.end.x - t3.start.x, i4 = t3.end.y - t3.start.y;
return (Hr(Math.abs(o3), 0) ? (e5.y - t3.start.y) / i4 : (e5.x - t3.start.x) / o3) - (Hr(Math.abs(o3), 0) ? (n3.y - t3.start.y) / i4 : (n3.x - t3.start.x) / o3);
});
for (let e5 = 0;e5 < i3.length - 1; ++e5) {
const n3 = i3[e5], o3 = i3[e5 + 1], c3 = s2(n3), l3 = s2(o3);
c3 !== l3 && (a2.push([c3, l3]), t3.connectionName && (r2[c3].connectionNames.add(t3.connectionName), r2[l3].connectionNames.add(t3.connectionName)));
}
}
const c2 = [];
for (const [e4, t3] of a2) {
const n3 = new Qr(e4, t3), o3 = new Qr(t3, e4);
n3.twin = c2.length + 1, o3.twin = c2.length;
const i3 = c2.length;
c2.push(n3, o3), r2[e4].out.push(i3), r2[t3].out.push(i3 + 1);
}
for (let e4 = 0;e4 < r2.length; ++e4) {
const t3 = r2[e4];
t3.out.sort((e5, n4) => {
const o3 = c2[e5], i3 = c2[n4], s3 = r2[o3.dest], a3 = r2[i3.dest];
return Math.atan2(s3.y - t3.y, s3.x - t3.x) - Math.atan2(a3.y - t3.y, a3.x - t3.x);
});
const n3 = t3.out.length;
for (let e5 = 0;e5 < n3; ++e5) {
const o3 = t3.out[e5], i3 = t3.out[(e5 - 1 + n3) % n3], r3 = c2[o3];
r3.twin !== null && (c2[r3.twin].next = i3);
}
}
const l2 = [], h2 = [];
for (let e4 = 0;e4 < c2.length; ++e4) {
if (c2[e4].visited)
continue;
let t3 = e4;
const n3 = [];
do {
if (t3 === null)
break;
const e5 = c2[t3];
e5.visited = true, n3.push(r2[e5.orig]), t3 = e5.next;
} while (t3 !== null && t3 !== e4 && !c2[t3].visited);
if (n3.length < 3)
continue;
if (Zr(n3) > Vr) {
const e5 = qr(n3);
e5 && (l2.push(e5), h2.push({ vertices: n3.map((e6) => ({ x: e6.x, y: e6.y, connectionNames: e6.connectionNames.size > 0 ? e6.connectionNames : undefined })), centroid: e5 }));
}
}
return { centroids: l2, faces: h2, allVertices: r2 };
}
function es(e3, t2) {
if (e3 > t2)
throw new Error("oneCount cannot be greater than length");
if (e3 < 0 || t2 < 0)
throw new Error("oneCount and length must be non-negative");
const n2 = [];
return function e4(o2, i2, r2) {
r2 !== t2 ? (o2[r2] = 0, e4(o2, i2, r2 + 1), i2 > 0 && (o2[r2] = 1, e4(o2, i2 - 1, r2 + 1))) : i2 === 0 && n2.push([...o2]);
}(Array(t2).fill(0), e3, 0), n2;
}
var ts = class extends ai {
getSolverName() {
return "MultiHeadPolyLineIntraNodeSolver";
}
nodeWithPortPoints;
colorMap;
hyperParameters;
connMap;
candidates;
bounds;
solvedRoutes = [];
unsolvedConnections = [];
SEGMENTS_PER_POLYLINE;
cellSize;
MAX_CANDIDATES = 50000;
viaDiameter = 0.3;
obstacleMargin = 0.1;
traceWidth = 0.15;
availableZ = [];
uniqueConnections = 0;
BOUNDARY_PADDING;
lastCandidate = null;
maxViaCount;
minViaCount;
phase = "setup";
progress = 0;
constructor(e3) {
super(), this.MAX_ITERATIONS = 1e4, this.nodeWithPortPoints = e3.nodeWithPortPoints, this.colorMap = e3.colorMap ?? Ar(e3.nodeWithPortPoints), this.hyperParameters = e3.hyperParameters ?? {}, this.SEGMENTS_PER_POLYLINE = e3.hyperParameters?.SEGMENTS_PER_POLYLINE ?? 3, this.BOUNDARY_PADDING = e3.hyperParameters?.BOUNDARY_PADDING ?? 0.05, this.connMap = e3.connMap, this.viaDiameter = e3.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 t2 = this.nodeWithPortPoints.width * this.nodeWithPortPoints.height, n2 = (this.viaDiameter + 2 * this.obstacleMargin + this.traceWidth / 2) ** 2, o2 = new Set(this.nodeWithPortPoints.portPoints.map((e4) => e4.connectionName)).size;
this.uniqueConnections = o2;
const { numSameLayerCrossings: i2, numEntryExitLayerChanges: r2 } = Dr(this.nodeWithPortPoints);
if (this.minViaCount = 2 * i2 + r2, this.maxViaCount = Math.min(Math.floor(t2 / n2), Math.ceil(1.5 * o2)), this.minViaCount > this.SEGMENTS_PER_POLYLINE * (o2 / 2))
return this.failed = true, 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(e3) {
const t2 = [], n2 = [], o2 = [];
for (let t3 = 0;t3 < e3.length; t3++) {
const i2 = e3[t3], r2 = [i2.start, ...i2.mPoints, i2.end], s2 = new Map(this.availableZ.map((e4) => [e4, []]));
for (let e4 = 0;e4 < r2.length - 1; e4++) {
const t4 = [r2[e4], r2[e4 + 1]], n3 = t4[0].z2;
s2.has(n3) || s2.set(n3, []), s2.get(n3).push(t4);
}
n2.push(s2), o2.push(r2.filter((e4) => e4.z1 !== e4.z2));
}
for (let i2 = 0;i2 < e3.length; i2++) {
const r2 = n2[i2], s2 = o2[i2];
for (let a2 = i2 + 1;a2 < e3.length; a2++) {
if (this.connMap?.areIdsConnected(e3[i2].connectionName, e3[a2].connectionName))
continue;
const c2 = n2[a2], l2 = o2[a2];
let h2 = 1;
for (const e4 of this.availableZ) {
const t3 = r2.get(e4) ?? [], n3 = c2.get(e4) ?? [];
for (const e5 of t3)
for (const t4 of n3)
h2 = Math.min(h2, kt(e5[0], e5[1], t4[0], t4[1]) - this.traceWidth);
for (const e5 of s2)
for (const t4 of n3)
h2 = Math.min(h2, xt(e5, t4[0], t4[1]) - this.traceWidth / 2 - this.viaDiameter / 2);
for (const e5 of l2)
for (const n4 of t3)
h2 = Math.min(h2, xt(e5, n4[0], n4[1]) - this.traceWidth / 2 - this.viaDiameter / 2);
for (const e5 of s2)
for (const t4 of l2)
h2 = Math.min(h2, vt(e5, t4) - this.viaDiameter);
}
t2.push(h2);
}
}
return t2;
}
insertCandidate(e3) {
let t2 = 0, n2 = this.candidates.length - 1;
for (;t2 <= n2; ) {
const o2 = Math.floor((t2 + n2) / 2);
this.candidates[o2].f < e3.f ? t2 = o2 + 1 : n2 = o2 - 1;
}
this.candidates.splice(t2, 0, e3);
}
setupInitialPolyLines() {
const e3 = new Map;
this.nodeWithPortPoints.portPoints.forEach((t3) => {
e3.has(t3.connectionName) ? e3.get(t3.connectionName).end = { ...t3, z1: t3.z ?? 0, z2: t3.z ?? 0 } : e3.set(t3.connectionName, { start: { ...t3, z1: t3.z ?? 0, z2: t3.z ?? 0 }, end: null });
});
for (const [t3, n3] of e3.entries())
n3.end === null && e3.delete(t3);
if (e3.size === 0)
return this.failed = true, void (this.error = "No port pairs found, can't solve");
const t2 = Array.from(e3.entries()), n2 = ((e4, t3, n3, o3) => {
const i3 = [];
for (const [, n4] of e4) {
const e5 = n4.start.z1 !== n4.end.z1, o4 = [];
for (let n5 = 0;n5 <= t3; n5++) {
const t4 = n5 % 2 != 0;
e5 && t4 ? o4.push(n5) : e5 || t4 || o4.push(n5);
}
i3.push(o4);
}
if (i3.length === 0)
return [[]];
let r2 = ((e5) => {
if (!e5 || e5.length === 0)
return [[]];
let t4 = [[]];
for (const n4 of e5) {
const e6 = [];
for (const o4 of t4)
for (const t5 of n4)
e6.push([...o4, t5]);
t4 = e6;
}
return t4;
})(i3).filter((e5) => {
for (let t4 = 0;t4 < e5.length; t4++)
if (e5.reduce((e6, t5) => e6 + t5, 0) < o3)
return false;
return true;
});
return r2 = r2.filter((t4) => {
for (let n4 = 0;n4 < e4.length; n4++) {
const [, o4] = e4[n4];
if (o4.start.z1 !== o4.start.z2 && t4[n4] === 0)
return false;
}
return true;
}), r2 = r2.filter((t4) => {
for (let n4 = 0;n4 < e4.length; n4++) {
const [, o4] = e4[n4];
if (e4[n4][1].start.z1 === e4[n4][1].start.z2)
for (let i4 = n4 + 1;i4 < e4.length; i4++) {
if (e4[i4][1].start.z1 !== e4[i4][1].start.z2)
continue;
const [, r3] = e4[i4];
if (o4.start.z1 === o4.end.z1 && r3.start.z1 === r3.end.z1 && o4.start.z1 === r3.start.z1 && _t(o4.start, o4.end, r3.start, r3.end) && t4[n4] + t4[i4] < 2)
return false;
}
}
return true;
}), r2 = r2.filter((e5) => !(e5.reduce((e6, t4) => e6 + t4, 0) > n3)), r2;
})(t2, this.SEGMENTS_PER_POLYLINE, this.maxViaCount, this.minViaCount), o2 = ((e4) => {
const { bounds: t3, portPairsEntries: n3, viaCountVariants: o3 } = e4, { centroids: i3 } = Kr(t3, n3.map(([e5, t4]) => t4)), r2 = [];
for (const e5 of o3) {
const n4 = e5.reduce((e6, t4) => e6 + t4, 0);
let o4 = i3;
if (i3.length < n4) {
o4 = [];
const e6 = Math.ceil(Math.sqrt(n4)), i4 = e6;
for (let n5 = 0;n5 < e6; n5++)
for (let r3 = 0;r3 < i4; r3++)
o4.push({ x: t3.minX + (r3 + 1) / (i4 + 1) * (t3.maxX - t3.minX), y: t3.minY + (n5 + 1) / (e6 + 1) * (t3.maxY - t3.minY) });
}
const s2 = es(n4, o4.length);
for (const t4 of s2) {
const n5 = [];
for (let e6 = 0;e6 < t4.length; e6++)
t4[e6] === 1 && n5.push(o4[e6]);
r2.push({ viaPositions: n5, viaCountVariant: e5 });
}
}
return r2;
})({ portPairsEntries: t2, viaCountVariants: n2, bounds: this.bounds }), i2 = [];
for (const { viaCountVariant: e4, viaPositions: t3 } of o2) {
const n3 = Wr(t3);
for (const t4 of n3)
i2.push({ viaCountVariant: e4, viaPositions: t4 });
}
for (const { viaPositions: e4, viaCountVariant: n3 } of i2) {
const o3 = [];
let i3 = 0;
for (let r3 = 0;r3 < t2.length; r3++) {
const [s3, a3] = t2[r3], c2 = n3[r3], l2 = e4.slice(i3, i3 + c2), h2 = Lr({ start: a3.start, end: a3.end, segmentsPerPolyline: this.SEGMENTS_PER_POLYLINE, viaPositions: l2, viaCount: c2, availableZ: this.availableZ });
i3 += c2, o3.push({ connectionName: s3, start: a3.start, end: a3.end, mPoints: h2 });
}
if (Xr(o3, this.bounds))
continue;
const r2 = this.computeMinGapBtwPolyLines(o3), s2 = this.computeH({ minGaps: r2, forces: [] }), a2 = { polyLines: o3, g: 0, h: s2, f: s2, viaCount: n3.reduce((e5, t3) => e5 + t3, 0), minGaps: r2 };
if (this.checkIfSolved(a2))
return void (this.candidates = [a2]);
if (this.candidates.push(a2), this.candidates.length > this.MAX_CANDIDATES)
return;
}
this.candidates.sort((e4, t3) => e4.f - t3.f);
}
computeG(e3, t2) {
return t2.g + 0.000005 + 0.000005 * t2.viaCount * 100;
}
computeH(e3) {
let t2 = 0;
for (const n2 of e3.forces ?? [])
for (const e4 of n2)
for (const n3 of e4.values())
t2 += n3.fx * n3.fx + n3.fy * n3.fy;
return t2;
}
getNeighbors(e3) {
const { polyLines: t2 } = e3, n2 = t2.length, o2 = 0.02, i2 = 0.008, r2 = 0.000001, s2 = Array.from({ length: n2 }, (e4, n3) => Array.from({ length: t2[n3].mPoints.length }, () => new Map)), a2 = (e4, n3, o3, i3, r3) => {
if (n3 > 0 && n3 < t2[e4].mPoints.length + 1) {
const t3 = n3 - 1, a3 = s2[e4][t3], c3 = a3.get(o3) || { fx: 0, fy: 0 };
a3.set(o3, { fx: c3.fx + i3, fy: c3.fy + r3 });
}
};
for (let e4 = 0;e4 < n2; e4++)
for (let i3 = e4 + 1;i3 < n2; i3++) {
const n3 = t2[e4], s3 = t2[i3], c3 = [n3.start, ...n3.mPoints, n3.end], l3 = [s3.start, ...s3.mPoints, s3.end], h3 = [], d3 = [];
for (let e5 = 0;e5 < c3.length - 1; e5++)
h3.push({ p1: c3[e5], p2: c3[e5 + 1], layer: c3[e5].z2, p1Idx: e5, p2Idx: e5 + 1 });
c3.forEach((e5, t3) => {
e5.z1 !== e5.z2 && d3.push({ point: e5, layers: [e5.z1, e5.z2], index: t3 });
});
const u3 = [], p2 = [];
for (let e5 = 0;e5 < l3.length - 1; e5++)
u3.push({ p1: l3[e5], p2: l3[e5 + 1], layer: l3[e5].z2, p1Idx: e5, p2Idx: e5 + 1 });
l3.forEach((e5, t3) => {
e5.z1 !== e5.z2 && p2.push({ point: e5, layers: [e5.z1, e5.z2], index: t3 });
});
for (const t3 of h3)
for (const n4 of u3)
if (t3.layer === n4.layer) {
if (kt(t3.p1, t3.p2, n4.p1, n4.p2) < r2)
continue;
const o3 = { x: (t3.p1.x + t3.p2.x) / 2, y: (t3.p1.y + t3.p2.y) / 2 }, s4 = { x: (n4.p1.x + n4.p2.x) / 2, y: (n4.p1.y + n4.p2.y) / 2 }, c4 = o3.x - s4.x, l4 = o3.y - s4.y, h4 = c4 * c4 + l4 * l4;
if (h4 > r2) {
const s5 = (`seg:${i3}:${n4.p1Idx}:${n4.p2Idx}`), c5 = `seg:${e4}:${t3.p1Idx}:${t3.p2Idx}`, l5 = (e5, t4, n5, o5, i4, s6, c6) => {
const l6 = Bt(e5, n5.p1, n5.p2), h5 = e5.x - l6.x, d4 = e5.y - l6.y, u4 = h5 * h5 + d4 * d4;
if (u4 <= r2)
return;
const p3 = Math.sqrt(u4), m2 = 0.02 * Math.exp(-6 * p3), g2 = h5 / p3 * m2, f2 = d4 / p3 * m2;
a2(o5, t4, s6, g2, f2), a2(i4, n5.p1Idx, c6, -g2 / 2, -f2 / 2), a2(i4, n5.p2Idx, c6, -g2 / 2, -f2 / 2);
};
l5(t3.p1, t3.p1Idx, n4, e4, i3, s5, c5), l5(t3.p2, t3.p2Idx, n4, e4, i3, s5, c5), l5(n4.p1, n4.p1Idx, t3, i3, e4, c5, s5), l5(n4.p2, n4.p2Idx, t3, i3, e4, c5, s5);
}
}
for (const t3 of d3)
for (const n4 of u3)
if (t3.layers.includes(n4.layer)) {
const s4 = Bt(t3.point, n4.p1, n4.p2), c4 = t3.point.x - s4.x, l4 = t3.point.y - s4.y, h4 = c4 * c4 + l4 * l4;
if (h4 > r2) {
const s5 = Math.sqrt(h4);
let d4 = 2, u4 = s5;
s5 < this.viaDiameter / 2 ? (d4 *= 4, u4 = Math.max(r2, s5)) : u4 = Math.max(r2, s5 - this.viaDiameter / 2);
const p3 = d4 * o2 * Math.exp(-6 * u4), m2 = c4 / s5 * p3, g2 = l4 / s5 * p3, f2 = `seg:${i3}:${n4.p1Idx}:${n4.p2Idx}`;
a2(e4, t3.index, f2, m2, g2);
const _2 = `via:${e4}:${t3.index}`;
a2(i3, n4.p1Idx, _2, -m2 / 2, -g2 / 2), a2(i3, n4.p2Idx, _2, -m2 / 2, -g2 / 2);
}
}
for (const t3 of p2)
for (const n4 of h3)
if (t3.layers.includes(n4.layer)) {
const s4 = Bt(t3.point, n4.p1, n4.p2), c4 = t3.point.x - s4.x, l4 = t3.point.y - s4.y, h4 = c4 * c4 + l4 * l4;
if (h4 > r2) {
const s5 = Math.sqrt(h4);
let d4 = 2, u4 = s5;
s5 < this.viaDiameter / 2 ? (d4 *= 4, u4 = Math.max(r2, s5)) : u4 = Math.max(r2, s5 - this.viaDiameter / 2);
const p3 = d4 * o2 * Math.exp(-6 * u4), m2 = c4 / s5 * p3, g2 = l4 / s5 * p3, f2 = `seg:${e4}:${n4.p1Idx}:${n4.p2Idx}`;
a2(i3, t3.index, f2, m2, g2);
const _2 = `via:${i3}:${t3.index}`;
a2(e4, n4.p1Idx, _2, -m2 / 2, -g2 / 2), a2(e4, n4.p2Idx, _2, -m2 / 2, -g2 / 2);
}
}
for (const t3 of d3)
for (const n4 of p2) {
if (t3.layers.filter((e5) => n4.layers.includes(e5)).length > 0) {
const s4 = t3.point.x - n4.point.x, c4 = t3.point.y - n4.point.y, l4 = s4 * s4 + c4 * c4;
if (l4 > r2) {
const h4 = Math.sqrt(l4);
let d4 = 2, u4 = h4;
h4 < this.viaDiameter ? (d4 *= 4, u4 = Math.max(r2, h4)) : u4 = Math.max(r2, h4 - this.viaDiameter);
const p3 = d4 * o2 * Math.exp(-6 * u4), m2 = s4 / h4 * p3, g2 = c4 / h4 * p3, f2 = `via:${i3}:${n4.index}`, _2 = `via:${e4}:${t3.index}`;
a2(e4, t3.index, f2, m2, g2), a2(i3, n4.index, _2, -m2, -g2);
}
}
}
}
for (let e4 = 0;e4 < n2; e4++) {
const n3 = t2[e4], i3 = [n3.start, ...n3.mPoints, n3.end], s3 = [];
if (i3.forEach((e5, t3) => {
e5.z1 !== e5.z2 && s3.push({ point: e5, layers: [e5.z1, e5.z2], index: t3 });
}), !(s3.length < 2))
for (let t3 = 0;t3 < s3.length; t3++)
for (let n4 = t3 + 1;n4 < s3.length; n4++) {
const i4 = s3[t3], c3 = s3[n4], l3 = i4.point.x - c3.point.x, h3 = i4.point.y - c3.point.y, d3 = l3 * l3 + h3 * h3;
if (d3 > r2) {
const t4 = Math.sqrt(d3);
let n5 = 2, s4 = t4;
t4 < this.viaDiameter ? (n5 *= 4, s4 = Math.max(r2, t4)) : s4 = Math.max(r2, t4 - this.viaDiameter);
const u3 = n5 * o2 * Math.exp(-6 * s4), p2 = l3 / t4 * u3, m2 = h3 / t4 * u3, g2 = `via:${e4}:${c3.index}`, f2 = `via:${e4}:${i4.index}`;
a2(e4, i4.index, g2, p2, m2), a2(e4, c3.index, f2, -p2, -m2);
}
}
}
const c2 = t2.map((e4) => ({ ...e4, mPoints: e4.mPoints.map((e5) => ({ ...e5 })) }));
let l2 = false;
for (let e4 = 0;e4 < n2; e4++)
for (let t3 = 0;t3 < c2[e4].mPoints.length; t3++) {
const n3 = c2[e4].mPoints[t3], o3 = s2[e4][t3], a3 = { fx: 0, fy: 0 };
for (const e5 of o3.values())
a3.fx += e5.fx, a3.fy += e5.fy;
const h3 = n3.z1 !== n3.z2;
let d3 = n3.x + a3.fx, u3 = n3.y + a3.fy;
if (h3) {
const e5 = this.viaDiameter / 2;
let t4 = 0, o4 = 0;
const r3 = this.viaDiameter / 2 + this.BOUNDARY_PADDING, s3 = this.bounds.minX + r3, c3 = this.bounds.maxX - r3, l3 = this.bounds.minY + r3, h4 = this.bounds.maxY - r3, p2 = s3 + e5 - n3.x, m2 = n3.x - (c3 - e5), g2 = l3 + e5 - n3.y, f2 = n3.y - (h4 - e5);
p2 > 0 ? t4 = i2 * (Math.exp(p2 / (2 * this.obstacleMargin)) - 1) : m2 > 0 && (t4 = -8e-3 * (Math.exp(m2 / (2 * this.obstacleMargin)) - 1)), g2 > 0 ? o4 = i2 * (Math.exp(g2 / (2 * this.obstacleMargin)) - 1) : f2 > 0 && (o4 = -8e-3 * (Math.exp(f2 / (2 * this.obstacleMargin)) - 1)), a3.fx += t4, a3.fy += o4, d3 = n3.x + a3.fx, u3 = n3.y + a3.fy;
} else {
const e5 = this.traceWidth / 2 + this.BOUNDARY_PADDING;
d3 = Math.max(this.bounds.minX + e5, Math.min(this.bounds.maxX - e5, d3)), u3 = Math.max(this.bounds.minY + e5, Math.min(this.bounds.maxY - e5, u3));
}
Math.abs(a3.fx) < r2 && Math.abs(a3.fy) < r2 || (Math.abs(n3.x - d3) > r2 || Math.abs(n3.y - u3) > r2) && (n3.x = d3, n3.y = u3, l2 = true);
}
if (!l2)
return [];
const h2 = this.computeMinGapBtwPolyLines(c2), d2 = this.computeG(c2, e3), u2 = this.computeH({ minGaps: h2, forces: s2 });
return [{ polyLines: c2, g: d2, h: u2, f: Math.round(5 * d2) / 5 + u2, minGaps: h2, forces: s2, viaCount: e3.viaCount }];
}
checkIfSolved(e3) {
const t2 = e3.minGaps.every((e4) => e4 >= this.obstacleMargin), n2 = e3.polyLines.every((e4) => e4.mPoints.every((e5) => {
const t3 = (e5.z1 !== e5.z2 ? this.viaDiameter / 2 : this.traceWidth / 2) + this.BOUNDARY_PADDING;
return ((e6, t4, n3 = 0) => e6.x >= t4.minX + n3 && e6.x <= t4.maxX - n3 && e6.y >= t4.minY + n3 && e6.y <= t4.maxY - n3)(e5, this.bounds, t3);
}));
return t2 && n2;
}
tryFinalAcceptance() {
const e3 = this.hyperParameters?.MINIMUM_FINAL_ACCEPTANCE_GAP ?? undefined;
if (e3 === undefined || this.lastCandidate === null || this.lastCandidate.minGaps.length === 0)
return;
return Math.min(...this.lastCandidate.minGaps) >= e3 ? (this.solved = true, void this._setSolvedRoutes()) : undefined;
}
_step() {
if (this.phase === "setup")
return this.setupInitialPolyLines(), void (this.phase = "solving");
const e3 = this.candidates.shift();
if (!e3) {
if (this.tryFinalAcceptance(), this.solved)
return;
return this.failed = true, void (this.error = "No candidates left");
}
if (this.lastCandidate = e3, this.checkIfSolved(e3))
return this.solved = true, void this._setSolvedRoutes();
if (!e3)
return void (this.failed = true);
const t2 = this.getNeighbors(e3);
for (const e4 of t2)
this.insertCandidate(e4);
}
visualize() {
const e3 = { points: [], lines: [], rects: [], circles: [], coordinateSystem: "cartesian", title: "MultiHeadPolyLineIntraNodeSolver Visualization" };
e3.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 t2 = this.lastCandidate ?? this.candidates[0];
if (t2?.hasClosedSameLayerFace) {
const t3 = 0.1 * (this.bounds.maxX - this.bounds.minX), n2 = 0.1 * (this.bounds.maxY - this.bounds.minY);
e3.rects.push({ center: { x: this.bounds.maxX + 0.6 * t3, y: this.bounds.maxY + 0.6 * n2 }, width: t3, height: n2, fill: "red", label: "HAS CLOSED FACE" });
}
for (const t3 of this.nodeWithPortPoints.portPoints)
e3.points.push({ x: t3.x, y: t3.y, label: `${t3.connectionName} (Port z=${t3.z ?? 0})`, color: this.colorMap[t3.connectionName] ?? "blue" });
return t2 && t2.polyLines.forEach((n2, o2) => {
const i2 = this.colorMap[n2.connectionName] ?? "purple", r2 = [n2.start, ...n2.mPoints, n2.end];
for (let t3 = 0;t3 < r2.length - 1; t3++) {
const o3 = r2[t3], s2 = r2[t3 + 1], a2 = o3.z2, c2 = a2 === 0, l2 = c2 ? i2 : Oo(i2, 0.5);
e3.lines.push({ points: [o3, s2], strokeColor: l2, strokeWidth: this.traceWidth, strokeDash: c2 ? undefined : [0.15, 0.15], label: `${n2.connectionName} segment (z=${a2})` });
}
r2.forEach((s2, a2) => {
const c2 = s2.z1 !== s2.z2, l2 = s2.z1, h2 = a2 > 0 && a2 < r2.length - 1;
let d2 = "", u2 = "";
if (h2) {
const i3 = a2 - 1, r3 = t2.forces?.[o2]?.[i3];
if (r3 && r3.size > 0) {
const o3 = { fx: 0, fy: 0 };
r3.forEach((r4, a3) => {
if (o3.fx += r4.fx, o3.fy += r4.fy, Math.abs(r4.fx) > 0.000001 || Math.abs(r4.fy) > 0.000001) {
const o4 = a3.split(":"), c3 = o4[0], l3 = parseInt(o4[1], 10), h3 = t2.polyLines[l3], d3 = this.colorMap[h3.connectionName] ?? "gray", u3 = 20, p2 = { x: s2.x + r4.fx * u3, y: s2.y + r4.fy * u3 };
let m2 = h3.connectionName;
if (c3 === "via") {
m2 += ` Via ${parseInt(o4[2], 10)}`;
} else if (c3 === "seg") {
m2 += ` Seg ${parseInt(o4[2], 10)}-${parseInt(o4[3], 10)}`;
}
e3.lines.push({ points: [s2, p2], strokeColor: d3, strokeWidth: 0.02, strokeDash: "2,2", label: `Force by ${m2} on ${n2.connectionName} mPoint ${i3}` });
}
}), (Math.abs(o3.fx) > 0.000001 || Math.abs(o3.fy) > 0.000001) && (u2 = `
Net Force: (${o3.fx.toFixed(3)}, ${o3.fy.toFixed(3)})`);
}
}
if (c2)
d2 = `Via (${n2.connectionName} z=${s2.z1} -> z=${s2.z2})${u2}`, e3.circles.push({ center: s2, radius: this.viaDiameter / 2, fill: Oo(i2, 0.5), label: d2 });
else if (h2) {
const t3 = l2 === 0 ? i2 : Oo(i2, 0.5);
d2 = `mPoint (${n2.connectionName} z=${l2})${u2}`, e3.circles.push({ center: s2, radius: this.cellSize / 8, fill: t3, label: d2 });
}
});
}), e3;
}
_setSolvedRoutes() {
if (!this.solved || !this.lastCandidate)
return [];
const e3 = [];
for (const t2 of this.lastCandidate.polyLines) {
const n2 = [], o2 = [], i2 = [t2.start, ...t2.mPoints, t2.end];
for (let e4 = 0;e4 < i2.length; e4++) {
const t3 = i2[e4];
n2.push({ x: t3.x, y: t3.y, z: t3.z1 }), t3.z1 !== t3.z2 && (o2.push({ x: t3.x, y: t3.y }), n2.push({ x: t3.x, y: t3.y, z: t3.z2 }));
}
e3.push({ connectionName: t2.connectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, traceThickness: this.traceWidth, viaDiameter: this.viaDiameter, route: n2, vias: o2 });
}
this.solvedRoutes = e3;
}
};
var ns = class extends ts {
getSolverName() {
return "MultiHeadPolyLineIntraNodeSolver2";
}
computeG(e3, t2) {
return t2.g + 0.000005 + 0.000005 * t2.viaCount * 100;
}
computeH(e3) {
const { minGaps: t2 } = e3;
let n2 = 0;
for (const e4 of t2)
e4 < 0 && (n2 += this.obstacleMargin), e4 < this.obstacleMargin && (n2 += this.obstacleMargin - e4);
return 0.011 * n2;
}
_step() {
if (this.phase === "setup")
return this.setupInitialPolyLines(), void (this.phase = "solving");
const e3 = this.candidates.shift();
if (!e3) {
if (this.tryFinalAcceptance(), this.solved)
return;
return void (this.failed = true);
}
if (this.lastCandidate = e3, this.checkIfSolved(e3))
return this.solved = true, void this._setSolvedRoutes();
let t2 = false, n2 = 0;
const o2 = e3.magForceApplied === undefined ? 1 : 10;
for (let i2 = 0;i2 < o2; i2++) {
const o3 = this.applyForcesToPolyLines(e3.polyLines);
if (n2 += o3.magForceApplied, t2 = o3.lastStepMoved, !o3.lastStepMoved)
break;
}
if (e3.magForceApplied = n2, e3.minGaps = this.computeMinGapBtwPolyLines(e3.polyLines), this.checkIfSolved(e3))
return this.solved = true, void this._setSolvedRoutes();
e3.g = this.computeG(e3.polyLines, e3), e3.h = this.computeH(e3), e3.f = e3.g + e3.h, t2 && this.insertCandidate(e3);
}
applyForcesToPolyLines(e3) {
let t2 = 0;
const n2 = e3.length, o2 = 0.02, i2 = 0.008, r2 = 0.000001, s2 = Array.from({ length: n2 }, (t3, n3) => Array.from({ length: e3[n3].mPoints.length }, () => ({ fx: 0, fy: 0 }))), a2 = (t3, n3, o3, i3) => {
if (n3 > 0 && n3 < e3[t3].mPoints.length + 1) {
const e4 = n3 - 1;
s2[t3][e4].fx += o3, s2[t3][e4].fy += i3;
}
}, c2 = (e4, t3, n3, o3, i3) => {
let s3, c3;
if (n3.lastTargetLine === o3 && n3.lastEndpointIndex === t3) {
if (!n3.lastForceActive)
return;
s3 = n3.lastFx, c3 = n3.lastFy;
} else {
let i4 = n3.p1.x, a3 = n3.p1.y;
if (n3.lengthSquared !== 0) {
const t4 = Math.max(0, Math.min(1, ((e4.x - n3.p1.x) * n3.deltaX + (e4.y - n3.p1.y) * n3.deltaY) / n3.lengthSquared));
i4 += t4 * n3.deltaX, a3 += t4 * n3.deltaY;
}
const l3 = e4.x - i4, h3 = e4.y - a3, d2 = l3 * l3 + h3 * h3;
if (n3.lastTargetLine = o3, n3.lastEndpointIndex = t3, d2 <= r2)
return void (n3.lastForceActive = false);
const u2 = Math.sqrt(d2), p2 = 0.02 * Math.exp(-6 * u2);
s3 = l3 / u2 * p2, c3 = h3 / u2 * p2, n3.lastFx = s3, n3.lastFy = c3, n3.lastForceActive = true;
}
a2(o3, t3, s3, c3), a2(i3, n3.p1Idx, -s3 / 2, -c3 / 2), a2(i3, n3.p2Idx, -s3 / 2, -c3 / 2);
}, l2 = e3.map((e4) => {
const t3 = [e4.start, ...e4.mPoints, e4.end];
return { segments: t3.slice(0, -1).map((e5, n3) => {
const o3 = t3[n3 + 1], i3 = o3.x - e5.x, r3 = o3.y - e5.y;
return { p1: e5, p2: o3, deltaX: i3, deltaY: r3, lengthSquared: i3 * i3 + r3 * r3, layer: e5.z2, p1Idx: n3, p2Idx: n3 + 1, lastTargetLine: -1, lastEndpointIndex: -1, lastFx: 0, lastFy: 0, lastForceActive: false };
}), vias: t3.flatMap((e5, t4) => e5.z1 === e5.z2 ? [] : [{ point: e5, layers: [e5.z1, e5.z2], index: t4 }]) };
});
for (let e4 = 0;e4 < n2; e4++)
for (let t3 = e4 + 1;t3 < n2; t3++) {
const { segments: n3, vias: i3 } = l2[e4], { segments: s3, vias: h3 } = l2[t3];
for (const o3 of n3)
for (const n4 of s3)
o3.layer === n4.layer && (c2(o3.p1, o3.p1Idx, n4, e4, t3), c2(o3.p2, o3.p2Idx, n4, e4, t3), c2(n4.p1, n4.p1Idx, o3, t3, e4), c2(n4.p2, n4.p2Idx, o3, t3, e4));
for (const n4 of i3)
for (const i4 of s3)
if (n4.layers.includes(i4.layer)) {
const s4 = Bt(n4.point, i4.p1, i4.p2), c3 = n4.point.x - s4.x, l3 = n4.point.y - s4.y, h4 = c3 * c3 + l3 * l3;
if (h4 > r2) {
const s5 = Math.sqrt(h4);
let d2 = 2, u2 = s5;
s5 < this.viaDiameter / 2 ? (d2 *= 4, u2 = Math.max(r2, s5)) : u2 = Math.max(r2, s5 - this.viaDiameter / 2);
const p2 = d2 * o2 * Math.exp(-6 * u2), m2 = c3 / s5 * p2, g2 = l3 / s5 * p2;
a2(e4, n4.index, m2, g2), a2(t3, i4.p1Idx, -m2 / 2, -g2 / 2), a2(t3, i4.p2Idx, -m2 / 2, -g2 / 2);
}
}
for (const i4 of h3)
for (const s4 of n3)
if (i4.layers.includes(s4.layer)) {
const n4 = Bt(i4.point, s4.p1, s4.p2), c3 = i4.point.x - n4.x, l3 = i4.point.y - n4.y, h4 = c3 * c3 + l3 * l3;
if (h4 > r2) {
const n5 = Math.sqrt(h4);
let d2 = 2, u2 = n5;
n5 < this.viaDiameter / 2 ? (d2 *= 4, u2 = Math.max(r2, n5)) : u2 = Math.max(r2, n5 - this.viaDiameter / 2);
const p2 = d2 * o2 * Math.exp(-6 * u2), m2 = c3 / n5 * p2, g2 = l3 / n5 * p2;
a2(t3, i4.index, m2, g2), a2(e4, s4.p1Idx, -m2 / 2, -g2 / 2), a2(e4, s4.p2Idx, -m2 / 2, -g2 / 2);
}
}
for (const n4 of i3)
for (const i4 of h3) {
if (n4.layers.filter((e5) => i4.layers.includes(e5)).length > 0) {
const s4 = n4.point.x - i4.point.x, c3 = n4.point.y - i4.point.y, l3 = s4 * s4 + c3 * c3;
if (l3 > r2) {
const h4 = Math.sqrt(l3);
let d2 = 2, u2 = h4;
h4 < this.viaDiameter ? (d2 *= 4, u2 = Math.max(r2, h4)) : u2 = Math.max(r2, h4 - this.viaDiameter);
const p2 = d2 * o2 * Math.exp(-6 * u2), m2 = s4 / h4 * p2, g2 = c3 / h4 * p2;
a2(e4, n4.index, m2, g2), a2(t3, i4.index, -m2, -g2);
}
}
}
}
for (let e4 = 0;e4 < n2; e4++) {
const { vias: t3 } = l2[e4];
if (!(t3.length < 2))
for (let n3 = 0;n3 < t3.length; n3++)
for (let i3 = n3 + 1;i3 < t3.length; i3++) {
const s3 = t3[n3], c3 = t3[i3], l3 = s3.point.x - c3.point.x, h3 = s3.point.y - c3.point.y, d2 = l3 * l3 + h3 * h3;
if (d2 > r2) {
const t4 = Math.sqrt(d2);
let n4 = 2, i4 = t4;
t4 < this.viaDiameter ? (n4 *= 4, i4 = Math.max(r2, t4)) : i4 = Math.max(r2, t4 - this.viaDiameter);
const u2 = n4 * o2 * Math.exp(-6 * i4), p2 = l3 / t4 * u2, m2 = h3 / t4 * u2;
a2(e4, s3.index, p2, m2), a2(e4, c3.index, -p2, -m2);
}
}
}
let h2 = false;
for (let o3 = 0;o3 < n2; o3++)
for (let n3 = 0;n3 < e3[o3].mPoints.length; n3++) {
const a3 = e3[o3].mPoints[n3], c3 = s2[o3][n3], l3 = a3.z1 !== a3.z2;
let { fx: d2, fy: u2 } = c3, p2 = a3.x + d2, m2 = a3.y + u2;
if (l3) {
const e4 = this.viaDiameter / 2;
let t3 = 0, n4 = 0;
const o4 = this.viaDiameter / 2 + this.BOUNDARY_PADDING, r3 = this.bounds.minX + o4, s3 = this.bounds.maxX - o4, c4 = this.bounds.minY + o4, l4 = this.bounds.maxY - o4, h3 = r3 + e4 - a3.x, g2 = a3.x - (s3 - e4), f2 = c4 + e4 - a3.y, _2 = a3.y - (l4 - e4);
h3 > 0 ? t3 = i2 * (Math.exp(h3 / (2 * this.obstacleMargin)) - 1) : g2 > 0 && (t3 = -8e-3 * (Math.exp(g2 / (2 * this.obstacleMargin)) - 1)), f2 > 0 ? n4 = i2 * (Math.exp(f2 / (2 * this.obstacleMargin)) - 1) : _2 > 0 && (n4 = -8e-3 * (Math.exp(_2 / (2 * this.obstacleMargin)) - 1)), d2 += t3, u2 += n4, p2 = a3.x + d2, m2 = a3.y + u2;
} else {
const e4 = this.traceWidth / 2 + this.BOUNDARY_PADDING;
p2 = Math.max(this.bounds.minX + e4, Math.min(this.bounds.maxX - e4, p2)), m2 = Math.max(this.bounds.minY + e4, Math.min(this.bounds.maxY - e4, m2));
}
if (Math.abs(d2) < r2 && Math.abs(u2) < r2)
continue;
t2 += Math.sqrt(d2 * d2 + u2 * u2), (Math.abs(a3.x - p2) > r2 || Math.abs(a3.y - m2) > r2) && (a3.x = p2, a3.y = m2, h2 = true);
}
return { lastStepMoved: h2, magForceApplied: t2 };
}
};
var os = (e3) => e3.flatMap((e4) => `${e4.connectionName}-${e4.mPoints.map((e5) => `${e5.x.toFixed(2)},${e5.y.toFixed(2)},${e5.z1},${e5.z2}`)}`).sort().join("|");
var is = class extends ns {
getSolverName() {
return "MultiHeadPolyLineIntraNodeSolver3";
}
constructor(e3) {
super(e3), this.MAX_ITERATIONS = 1000;
}
createInitialCandidateFromSeed(e3, t2) {
const n2 = new Or({ nodeWithPortPoints: this.nodeWithPortPoints, colorMap: this.colorMap, hyperParameters: { SHUFFLE_SEED: e3 }, viaDiameter: this.viaDiameter });
if (n2.solve(), n2.failed || !n2.solved)
return this.failed = true, this.error = `ViaPossibilitiesSolver2 failed with: ${n2.error}`, null;
const o2 = [];
let i2 = 0;
for (const [e4, t3] of n2.completedPaths.entries()) {
if (t3.length < 2) {
console.warn(`Skipping connection "${e4}" due to insufficient points (${t3.length}) in ViaPossibilitiesSolver2 path.`);
continue;
}
const n3 = t3[0], r3 = t3[t3.length - 1], s3 = t3.slice(1, -1), a3 = [];
let c2 = 0, l2 = n3.z;
for (let e5 = 0;e5 < s3.length; e5++) {
const t4 = s3[e5], n4 = e5 + 1 < s3.length ? s3[e5 + 1] : r3, o3 = l2, i3 = e5 + 1 < s3.length && t4.x === n4.x && t4.y === n4.y && t4.z !== n4.z ? n4.z : t4.z;
a3.push({ x: t4.x, y: t4.y, z1: o3, z2: i3 }), o3 !== i3 ? (c2++, e5++, l2 = i3) : l2 = t4.z;
}
i2 += c2;
const h2 = this.SEGMENTS_PER_POLYLINE;
let d2 = a3.length + 1;
for (;d2 < h2; ) {
let t4 = -1, o3 = -1, i3 = null, s4 = null;
const c3 = [{ ...n3, z1: n3.z, z2: n3.z, connectionName: e4 }, ...a3, { ...r3, z1: r3.z, z2: r3.z, connectionName: e4 }];
for (let e5 = 0;e5 < c3.length - 1; e5++) {
const n4 = c3[e5], r4 = c3[e5 + 1];
if (n4.x === r4.x && n4.y === r4.y)
continue;
const a4 = vt(n4, r4);
a4 > t4 && (t4 = a4, o3 = e5, i3 = n4, s4 = r4);
}
if (o3 === -1 || !i3 || !s4) {
console.warn(`Could not find longest segment for ${e4} while trying to reach ${h2} segments.`);
break;
}
const l3 = (i3.x + s4.x) / 2, u2 = (i3.y + s4.y) / 2, p2 = i3.z2, m2 = { x: l3, y: u2, z1: p2, z2: p2 };
a3.splice(o3, 0, m2), d2++;
}
o2.push({ connectionName: e4, start: { ...n3, z1: n3.z, z2: n3.z }, end: { ...r3, z1: r3.z, z2: r3.z }, mPoints: a3 });
}
if (o2.length === 0)
return this.failed = true, this.error = "No valid polylines generated from ViaPossibilitiesSolver2.", console.error(this.error), null;
if (t2?.has(os(o2)))
return null;
const r2 = this.computeMinGapBtwPolyLines(o2), s2 = this.computeH({ minGaps: r2, forces: [] }), a2 = { polyLines: o2, g: 0, h: s2, f: 0 + s2, viaCount: i2, minGaps: r2 };
return a2.g = this.computeG(o2, a2), a2.f = a2.g + a2.h, a2;
}
setupInitialPolyLines() {
this.candidates = [];
const e3 = Math.min(2000, function(e4) {
if (!Number.isInteger(e4) || e4 < 0)
throw new RangeError("n must be a non-negative integer");
let t3 = 1;
for (let n3 = 2;n3 <= e4; n3++)
t3 *= n3;
return t3;
}(this.uniqueConnections)), t2 = new Set, n2 = this.createInitialCandidateFromSeed === rs && this.computeMinGapBtwPolyLines === ss && this.computeH === as && this.computeG === cs;
for (let o2 = 0;o2 < e3; o2++) {
const e4 = n2 ? this.createInitialCandidateFromSeed(o2, t2) : this.createInitialCandidateFromSeed(o2);
if (!e4)
continue;
const i2 = os(e4.polyLines);
t2.has(i2) || (t2.add(i2), this.candidates.push(e4));
}
this.candidates.sort((e4, t3) => e4.f - t3.f);
}
};
var rs = is.prototype.createInitialCandidateFromSeed;
var ss = ts.prototype.computeMinGapBtwPolyLines;
var as = ns.prototype.computeH;
var cs = ns.prototype.computeG;
var ls = (e3) => e3.portPointId ?? `${e3.connectionName}:${e3.x}:${e3.y}:${e3.z}`;
var hs = (e3, t2) => {
const [n2, o2] = e3;
if (n2 === o2)
return false;
const i2 = ((e4) => {
const [t3, n3] = e4, o3 = ls(t3), i3 = ls(n3);
return o3 < i3 ? `${o3}|${i3}` : `${i3}|${o3}`;
})(e3);
return !t2.seenPairKeys.has(i2) && (t2.seenPairKeys.add(i2), t2.pairs.push(e3), true);
};
var ds = (e3, t2) => {
for (let n2 = 0;n2 < e3.length - 1; n2++)
hs([e3[n2], e3[n2 + 1]], t2);
};
var us = (e3) => {
const t2 = [], n2 = new Set, o2 = new Map(e3.filter((e4) => typeof e4.portPointId == "string").map((e4) => [e4.portPointId, e4])), i2 = { pairs: t2, seenPairKeys: n2 };
for (const t3 of e3) {
if (t3.prevPortPointId) {
const e4 = o2.get(t3.prevPortPointId);
e4 && e4.connectionName === t3.connectionName && hs([e4, t3], i2);
}
if (t3.nextPortPointId) {
const e4 = o2.get(t3.nextPortPointId);
e4 && e4.connectionName === t3.connectionName && hs([t3, e4], i2);
}
}
if (t2.length === 0)
return ds(e3, i2), t2;
const r2 = new Set(t2.flatMap(([e4, t3]) => [e4.portPointId, t3.portPointId]).filter(Boolean)), s2 = e3.filter((e4) => !e4.portPointId || !r2.has(e4.portPointId));
return ds(s2, i2), t2;
};
var ps = 0.000001;
var ms = 0.02;
var gs = (e3) => `${e3.x.toFixed(6)},${e3.y.toFixed(6)}`;
var fs = (e3, t2) => Math.abs(e3.x - t2.x) < ps && Math.abs(e3.y - t2.y) < ps;
var _s = (e3) => ({ minX: e3.center.x - e3.width / 2, maxX: e3.center.x + e3.width / 2, minY: e3.center.y - e3.height / 2, maxY: e3.center.y + e3.height / 2 });
var ys = (e3, t2) => e3.x >= t2.minX - ps && e3.x <= t2.maxX + ps && e3.y >= t2.minY - ps && e3.y <= t2.maxY + ps;
var bs = (e3, t2, n2) => {
for (const o2 of n2)
if (!fs(o2, e3) && !fs(o2, t2) && xt(o2, e3, t2) < 0.0001)
return true;
return false;
};
var xs = (e3, t2, n2) => {
for (const o2 of n2)
if (!(fs(e3, o2.A) || fs(e3, o2.B) || fs(t2, o2.A) || fs(t2, o2.B)) && _t(e3, t2, o2.A, o2.B))
return true;
return false;
};
var vs = (e3, t2) => {
const n2 = [];
for (const o2 of e3) {
const e4 = o2.rootConnectionName ?? o2.connectionName;
if (e4 !== t2)
for (let t3 = 0;t3 < o2.route.length - 1; t3++) {
const i2 = o2.route[t3], r2 = o2.route[t3 + 1];
i2.z === r2.z && n2.push({ A: { x: i2.x, y: i2.y }, B: { x: r2.x, y: r2.y }, rootConnectionName: e4 });
}
}
return n2;
};
var Is = (e3, t2) => e3.portPoints.filter((e4) => (e4.rootConnectionName ?? e4.connectionName) !== t2).map((e4) => ({ x: e4.x, y: e4.y }));
function* Ss(e3, t2 = e3.length) {
if (t2 <= 1)
yield e3.slice();
else
for (let n2 = 0;n2 < t2; n2++)
[e3[n2], e3[t2 - 1]] = [e3[t2 - 1], e3[n2]], yield* Ss(e3, t2 - 1), [e3[n2], e3[t2 - 1]] = [e3[t2 - 1], e3[n2]];
}
var Cs = ({ A: e3, B: t2, bounds: n2, obstacleSegments: o2, foreignPorts: i2 }) => {
const r2 = [{ x: e3.x, y: e3.y }, { x: t2.x, y: t2.y }, { x: (n2.minX + n2.maxX) / 2, y: (n2.minY + n2.maxY) / 2 }, { x: n2.minX, y: n2.minY }, { x: n2.maxX, y: n2.minY }, { x: n2.maxX, y: n2.maxY }, { x: n2.minX, y: n2.maxY }], s2 = [...o2.flatMap((e4) => [e4.A, e4.B]), ...i2, { x: e3.x, y: e3.y }, { x: t2.x, y: t2.y }];
for (const e4 of s2)
for (const t3 of [-0.02, 0, ms])
for (const o3 of [-0.02, 0, ms]) {
const i3 = { x: e4.x + t3, y: e4.y + o3 };
ys(i3, n2) && r2.push(i3);
}
const a2 = ((e4) => {
const t3 = new Set, n3 = [];
for (const o3 of e4) {
const e5 = gs(o3);
t3.has(e5) || (t3.add(e5), n3.push(o3));
}
return n3;
})(r2), c2 = gs(e3), l2 = gs(t2), h2 = new Map(a2.map((e4) => [gs(e4), e4])), d2 = new Map, u2 = new Map, p2 = new Set;
for (const e4 of a2) {
const t3 = gs(e4);
d2.set(t3, t3 === c2 ? 0 : 1 / 0), u2.set(t3, null), p2.add(t3);
}
for (;p2.size > 0; ) {
let e4 = null, t3 = 1 / 0;
for (const n4 of p2) {
const o3 = d2.get(n4) ?? 1 / 0;
(o3 < t3 - ps || Math.abs(o3 - t3) <= ps && (e4 === null || n4 < e4)) && (t3 = o3, e4 = n4);
}
if (!e4 || t3 === 1 / 0)
break;
if (p2.delete(e4), e4 === l2)
break;
const n3 = h2.get(e4);
for (const r3 of p2) {
const s3 = h2.get(r3);
if (fs(n3, s3))
continue;
if (xs(n3, s3, o2))
continue;
if (bs(n3, s3, i2))
continue;
const a3 = t3 + vt(n3, s3), c3 = d2.get(r3) ?? 1 / 0, l3 = u2.get(r3);
(a3 < c3 - ps || Math.abs(a3 - c3) <= ps && (l3 == null || e4 < l3)) && (d2.set(r3, a3), u2.set(r3, e4));
}
}
if ((d2.get(l2) ?? 1 / 0) === 1 / 0)
return null;
const m2 = [];
let g2 = l2;
for (;g2; )
m2.push(h2.get(g2)), g2 = u2.get(g2) ?? null;
return m2.reverse(), m2.map((t3) => ({ x: t3.x, y: t3.y, z: e3.z }));
};
var Ps = class extends ai {
getSolverName() {
return "SingleLayerNoDifferentRootIntersectionsIntraNodeSolver";
}
nodeWithPortPoints;
traceWidth;
viaDiameter;
solvedRoutes = [];
constructor(e3) {
super(), this.nodeWithPortPoints = e3.nodeWithPortPoints, this.traceWidth = e3.traceWidth ?? 0.15, this.viaDiameter = e3.viaDiameter ?? 0.3, this.MAX_ITERATIONS = 1;
}
static isApplicable(e3) {
const t2 = ((e4) => e4.availableZ?.length ? [...new Set(e4.availableZ)].sort((e5, t3) => e5 - t3) : [...new Set(e4.portPoints.map((e5) => e5.z ?? 0))].sort((e5, t3) => e5 - t3))(e3);
if (t2.length !== 1)
return false;
if (e3.portPoints.length > 12)
return false;
const n2 = _s(e3);
if (e3.portPoints.some((e4) => ((e5, t3) => Math.abs(e5.y - t3.minY) < 0.001 ? "top" : Math.abs(e5.x - t3.maxX) < 0.001 ? "right" : Math.abs(e5.y - t3.maxY) < 0.001 ? "bottom" : Math.abs(e5.x - t3.minX) < 0.001 ? "left" : null)(e4, n2) === null))
return false;
const o2 = new Map;
for (const t3 of e3.portPoints)
o2.set(t3.connectionName, (o2.get(t3.connectionName) ?? 0) + 1);
return [...o2.values()].some((e4) => e4 > 2);
}
buildTaskGroups() {
const e3 = new Map;
for (const t2 of this.nodeWithPortPoints.portPoints) {
const n2 = e3.get(t2.connectionName) ?? [];
n2.push(t2), e3.set(t2.connectionName, n2);
}
return e3;
}
trySolveNode() {
const e3 = _s(this.nodeWithPortPoints), t2 = this.buildTaskGroups(), n2 = Array.from(t2.entries()).flatMap(([e4, t3]) => us(t3).map(([t4, n3]) => ({ connectionName: e4, rootConnectionName: t4.rootConnectionName ?? n3.rootConnectionName ?? e4, A: t4, B: n3 }))), o2 = n2.length <= 6 ? Ss(n2.slice()) : [n2];
for (const t3 of o2) {
const n3 = [];
let o3 = false;
for (const i2 of t3) {
const t4 = vs(n3, i2.rootConnectionName), r2 = Is(this.nodeWithPortPoints, i2.rootConnectionName), s2 = Cs({ A: i2.A, B: i2.B, bounds: e3, obstacleSegments: t4, foreignPorts: r2 });
if (!s2 || s2.length < 2) {
o3 = true;
break;
}
n3.push({ connectionName: i2.connectionName, rootConnectionName: i2.rootConnectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, traceThickness: this.traceWidth, viaDiameter: this.viaDiameter, route: s2, vias: [] });
}
if (!o3)
return n3;
}
return null;
}
_step() {
const e3 = this.trySolveNode();
if (!e3)
return this.failed = true, void (this.error = "Failed to find a single-layer route set without different-root intersections");
this.solvedRoutes = e3, this.stats = { routeCount: e3.length, distinctRoots: new Set(e3.map((e4) => e4.rootConnectionName ?? e4.connectionName)).size }, this.solved = true;
}
visualize() {
return { lines: this.solvedRoutes.map((e3) => ({ points: e3.route, strokeColor: "cyan", strokeWidth: e3.traceThickness, label: `${e3.connectionName}
root: ${e3.rootConnectionName ?? e3.connectionName}` })), points: this.nodeWithPortPoints.portPoints.map((e3) => ({ x: e3.x, y: e3.y, color: "blue", label: `${e3.connectionName}
root: ${e3.rootConnectionName ?? e3.connectionName}` })), rects: [], circles: [] };
}
};
var Ms = (e3) => e3.min <= e3.max ? Ot(e3.value, e3.min, e3.max) : e3.value;
var ws = class extends ai {
getSolverName() {
return "SingleTransitionIntraNodeSolver";
}
nodeWithPortPoints;
routes;
viaDiameter;
traceThickness;
obstacleMargin;
solvedRoutes = [];
bounds;
constructor(e3) {
if (super(), this.nodeWithPortPoints = e3.nodeWithPortPoints, this.viaDiameter = e3?.viaDiameter ?? 0.3, this.traceThickness = e3?.traceThickness ?? 0.15, this.obstacleMargin = e3?.obstacleMargin ?? 0.1, this.routes = this.extractRoutesFromNode(), this.bounds = this.calculateBounds(), this.routes.length !== 1)
return this.failed = true, void (this.error = `Expected 1 route, but got ${this.routes.length}`);
const t2 = this.routes[0];
if (t2.A.z === undefined || t2.B.z === undefined)
return this.failed = true, void (this.error = "Route points should have predefined z values");
if (t2.A.z === t2.B.z)
return this.failed = true, void (this.error = "Only one route provided, but it has no transition");
const n2 = this.viaDiameter / 2 + this.obstacleMargin, o2 = { x: Ms({ value: (t2.A.x + t2.B.x) / 2, min: this.bounds.minX + n2, max: this.bounds.maxX - n2 }), y: Ms({ value: (t2.A.y + t2.B.y) / 2, min: this.bounds.minY + n2, max: this.bounds.maxY - n2 }) };
this.solvedRoutes.push(this.createTransitionRoute({ start: t2.A, end: t2.B, via: o2, connectionName: t2.connectionName })), this.solved = true;
}
extractRoutesFromNode() {
const e3 = [], t2 = this.nodeWithPortPoints.portPoints, n2 = new Map;
for (const e4 of t2) {
const { connectionName: t3 } = e4;
n2.has(t3) || n2.set(t3, []), n2.get(t3).push(e4);
}
for (const [t3, o2] of n2.entries())
for (const [n3, i2] of us(o2))
e3.push({ A: { ...n3 }, B: { ...i2 }, connectionName: t3 });
return e3;
}
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(e3) {
const { start: t2, end: n2, via: o2, connectionName: i2 } = e3, r2 = [{ x: t2.x, y: t2.y, z: t2.z }, { x: o2.x, y: o2.y, z: t2.z }, { x: o2.x, y: o2.y, z: n2.z }, { x: n2.x, y: n2.y, z: n2.z }];
return { connectionName: i2, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: r2, traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [o2] };
}
_step() {
this.solved = true;
}
visualize() {
const e3 = { lines: [], points: [], rects: [], circles: [] };
if (e3.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 t2 of this.routes)
e3.points.push({ x: t2.A.x, y: t2.A.y, label: `${t2.connectionName} start (z=${t2.A.z})`, color: "orange" }), e3.points.push({ x: t2.B.x, y: t2.B.y, label: `${t2.connectionName} end (z=${t2.B.z})`, color: "orange" }), e3.lines.push({ points: [t2.A, t2.B], strokeColor: "rgba(255, 0, 0, 0.5)", label: `${t2.connectionName} direct` });
for (let t2 = 0;t2 < this.solvedRoutes.length; t2++) {
const n2 = this.solvedRoutes[t2], o2 = "rgba(0, 255, 0, 0.75)";
for (let t3 = 0;t3 < n2.route.length - 1; t3++) {
const i2 = n2.route[t3], r2 = n2.route[t3 + 1];
e3.lines.push({ points: [i2, r2], strokeColor: o2, strokeDash: i2.z !== n2.route[0].z ? [0.2, 0.2] : undefined, strokeWidth: n2.traceThickness, label: `${n2.connectionName} z=${i2.z}` });
}
for (const t3 of n2.vias)
e3.circles.push({ center: t3, radius: this.viaDiameter / 2, fill: "rgba(0, 0, 255, 0.8)", stroke: "black", label: "Solved Via" }), e3.circles.push({ center: t3, radius: this.viaDiameter / 2 + this.obstacleMargin, fill: "rgba(0, 0, 255, 0.3)", stroke: "black", label: "Via Margin" });
}
return e3;
}
};
var Ns = (e3, t2 = 2) => {
const n2 = Array.from({ length: t2 }, (e4, t3) => t3);
return e3.map((e4) => {
const o2 = fo(e4.__zLayers ?? (e4.layers ? _o(e4.layers, t2) : undefined) ?? n2, t2);
return { ...e4, __zLayers: o2.length > 0 ? o2 : n2 };
});
};
var Ts = 0.000001;
var Rs = (e3) => {
const { point: t2, obstacle: n2 } = e3, o2 = n2.width / 2 + Ts, i2 = n2.height / 2 + Ts;
return Math.abs(t2.x - n2.center.x) <= o2 && Math.abs(t2.y - n2.center.y) <= i2;
};
var Es = class e3 extends ai {
getSolverName() {
return "SingleTransitionThroughObstacleIntraNodeSolver";
}
nodeWithPortPoints;
routes;
obstacles;
viaDiameter;
traceThickness;
connMap;
solvedRoutes = [];
constructor(e4) {
if (super(), this.nodeWithPortPoints = e4.nodeWithPortPoints, this.obstacles = Ns(e4.obstacles ?? [], e4.layerCount ?? 2), this.connMap = e4.connMap, this.viaDiameter = e4.viaDiameter ?? 0.3, this.traceThickness = e4.traceThickness ?? 0.15, this.routes = this.extractRoutesFromNode(), this.routes.length === 0)
return this.failed = true, void (this.error = "Expected at least 1 route");
if (this.routes.some((e5) => e5.A.z === undefined || e5.B.z === undefined))
return this.failed = true, void (this.error = "Route points should have predefined z values");
if (!this.routes.some((e5) => e5.A.z !== e5.B.z))
return this.failed = true, void (this.error = "No route transitions through an obstacle");
const t2 = this.routes.map((e5) => this.getContainingThroughObstacle(e5));
if (t2.some((e5) => !e5))
return this.failed = true, void (this.error = "No same-net multilayer obstacle contains every route");
this.solvedRoutes.push(...this.routes.map((e5, n2) => ({ connectionName: e5.connectionName, rootConnectionName: e5.rootConnectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: [{ x: e5.A.x, y: e5.A.y, z: e5.A.z, ...e5.A.z !== e5.B.z ? { toNextSegmentType: "through_obstacle", ...t2[n2].circuitJsonMetadata ? { toNextSegmentCircuitJsonMetadata: t2[n2].circuitJsonMetadata } : {} } : {} }, { x: e5.B.x, y: e5.B.y, z: e5.B.z }], traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [] }))), this.solved = true;
}
static isApplicable(t2) {
return new e3(t2).solved;
}
extractRoutesFromNode() {
const e4 = [], t2 = new Map;
for (const e5 of this.nodeWithPortPoints.portPoints) {
const { connectionName: n2 } = e5;
t2.has(n2) || t2.set(n2, []), t2.get(n2).push(e5);
}
for (const [n2, o2] of t2.entries())
for (const [t3, i2] of us(o2))
e4.push({ A: { ...t3 }, B: { ...i2 }, connectionName: n2, rootConnectionName: t3.rootConnectionName ?? i2.rootConnectionName });
return e4;
}
getContainingThroughObstacle(e4) {
const t2 = e4.A.z, n2 = e4.B.z;
return t2 === undefined || n2 === undefined ? null : this.obstacles.find((o2) => {
return !(o2.__zLayers.length < 2) && (!(!o2.__zLayers.includes(t2) || !o2.__zLayers.includes(n2)) && (!!(i2 = { obstacle: o2, connectionName: e4.connectionName, connMap: this.connMap }).obstacle.connectedTo.some((e5) => e5 === i2.connectionName || (i2.connMap?.areIdsConnected(i2.connectionName, e5) ?? false)) && (Rs({ point: e4.A, obstacle: o2 }) && Rs({ point: e4.B, obstacle: o2 }))));
var i2;
}) ?? null;
}
_step() {
this.solved = true;
}
visualize() {
const e4 = { lines: [], points: [], rects: [], circles: [] };
for (const t2 of this.obstacles)
e4.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: "rgba(128, 0, 128, 0.2)", stroke: "rgba(128, 0, 128, 0.6)", label: `through obstacle candidate
z: ${t2.__zLayers.join(",")}` });
for (const t2 of this.solvedRoutes) {
e4.lines.push({ points: t2.route, strokeColor: "rgba(0, 180, 0, 0.8)", strokeDash: "4, 3", strokeWidth: t2.traceThickness, label: `${t2.connectionName} through_obstacle` });
for (const n2 of t2.route)
e4.points.push({ x: n2.x, y: n2.y, color: "green", label: `${t2.connectionName}
z: ${n2.z}` });
}
return e4;
}
};
var As = 0.000001;
var Os = ({ value: e4, min: t2, max: n2 }) => e4 >= t2 && e4 <= n2;
var ks = ({ value: e4, target: t2, epsilon: n2 }) => Math.abs(e4 - t2) <= n2;
var Ds = ({ point: e4, bounds: t2, epsilon: n2 = 0.000001 }) => {
if (![e4.x, e4.y, t2.minX, t2.maxX, t2.minY, t2.maxY].every((e5) => (({ value: e6 }) => Number.isFinite(e6))({ value: e5 })))
return "outside";
if (e4.x < t2.minX - n2 || e4.x > t2.maxX + n2 || e4.y < t2.minY - n2 || e4.y > t2.maxY + n2)
return "outside";
const o2 = ks({ value: e4.x, target: t2.minX, epsilon: n2 }), i2 = ks({ value: e4.x, target: t2.maxX, epsilon: n2 }), r2 = ks({ value: e4.y, target: t2.minY, epsilon: n2 }), s2 = ks({ value: e4.y, target: t2.maxY, epsilon: n2 }), a2 = o2 || i2, c2 = r2 || s2;
if (a2 && c2)
return "on-boundary";
const l2 = Os({ value: e4.y, min: t2.minY, max: t2.maxY }), h2 = Os({ value: e4.x, min: t2.minX, max: t2.maxX });
return a2 && l2 || c2 && h2 ? "on-boundary" : "inside";
};
function Ls(e4, t2, n2, o2, i2) {
const r2 = { x: (e4.x + t2.x + n2.x) / 3, y: (e4.y + t2.y + n2.y) / 3 }, s2 = (e5, t3) => Math.sqrt((t3.x - e5.x) ** 2 + (t3.y - e5.y) ** 2), a2 = (r3) => {
const a3 = s2(r3, e4), c3 = s2(r3, t2), l3 = s2(r3, n2), h3 = r3.x >= i2.minX && r3.x <= i2.maxX && r3.y >= i2.minY && r3.y <= i2.maxY;
return a3 >= o2 && c3 >= o2 && l3 >= o2 && h3;
};
if (a2(r2))
return r2;
const c2 = (e5, t3, n3) => {
const o3 = e5.x - t3.x, i3 = e5.y - t3.y, r3 = Math.sqrt(o3 * o3 + i3 * i3);
return r3 < 0.0000000001 ? { x: t3.x + n3, y: t3.y } : { x: t3.x + o3 / r3 * n3, y: t3.y + i3 / r3 * n3 };
}, l2 = (e5, t3, n3) => {
const o3 = t3.x - e5.x, i3 = t3.y - e5.y, r3 = Math.sqrt(o3 * o3 + i3 * i3);
if (r3 > 2 * n3 - 0.0000000001 || r3 < 0.0000000001)
return [];
const a3 = r3 * r3 / (2 * r3), c3 = Math.sqrt(Math.max(0, n3 * n3 - a3 * a3)), l3 = e5.x + o3 * a3 / r3, h3 = e5.y + i3 * a3 / r3, d3 = { x: l3 + c3 * i3 / r3, y: h3 - c3 * o3 / r3 }, u3 = { x: l3 - c3 * i3 / r3, y: h3 + c3 * o3 / r3 }, p3 = [], m3 = 0.000001;
return Math.abs(s2(d3, e5) - n3) < m3 && Math.abs(s2(d3, t3) - n3) < m3 && p3.push(d3), Math.abs(s2(u3, e5) - n3) < m3 && Math.abs(s2(u3, t3) - n3) < m3 && p3.push(u3), p3;
}, h2 = [c2(r2, e4, o2), c2(r2, t2, o2), c2(r2, n2, o2), ...l2(e4, t2, o2), ...l2(t2, n2, o2), ...l2(n2, e4, o2)], d2 = h2.filter(a2);
if (d2.length > 0) {
const e5 = d2.filter((e6) => !((e7) => {
const t3 = 0.000001;
return Math.abs(e7.x - i2.minX) < t3 || Math.abs(e7.x - i2.maxX) < t3 || Math.abs(e7.y - i2.minY) < t3 || Math.abs(e7.y - i2.maxY) < t3;
})(e6));
if (e5.length > 0)
return e5.sort((e6, t3) => s2(e6, r2) - s2(t3, r2)), e5[0];
}
let u2 = null, p2 = 1 / 0;
for (let e5 = i2.minX + 1;e5 < i2.maxX; e5 += 5)
for (let t3 = i2.minY + 1;t3 < i2.maxY; t3 += 5) {
const n3 = { x: e5, y: t3 };
if (a2(n3)) {
const e6 = s2(n3, r2);
e6 < p2 && (p2 = e6, u2 = n3);
}
}
if (u2 !== null)
return u2;
const m2 = [];
for (let e5 = 0;e5 <= 100; e5++) {
const t3 = e5 / 100;
m2.push({ x: i2.minX + t3 * (i2.maxX - i2.minX), y: i2.minY }), m2.push({ x: i2.maxX, y: i2.minY + t3 * (i2.maxY - i2.minY) }), m2.push({ x: i2.maxX - t3 * (i2.maxX - i2.minX), y: i2.maxY }), m2.push({ x: i2.minX, y: i2.maxY - t3 * (i2.maxY - i2.minY) });
}
const g2 = m2.filter(a2);
if (g2.length > 0)
return g2.sort((e5, t3) => s2(e5, r2) - s2(t3, r2)), g2[0];
let f2 = 1 / 0, _2 = { x: i2.minX, y: i2.minY };
for (const r3 of [...h2, ...m2])
if (r3.x >= i2.minX && r3.x <= i2.maxX && r3.y >= i2.minY && r3.y <= i2.maxY) {
const i3 = Math.max(0, o2 - s2(r3, e4)) + Math.max(0, o2 - s2(r3, t2)) + Math.max(0, o2 - s2(r3, n2));
i3 < f2 && (f2 = i3, _2 = r3);
}
return _2;
}
function zs(e4, t2, n2) {
const o2 = Bs(t2, e4, n2.center, n2.radius), i2 = Bs(e4, t2, n2.center, n2.radius), r2 = Fs(o2, t2), s2 = Fs(e4, i2), a2 = 0.000001;
let c2;
if (r2 > a2 && s2 > a2) {
c2 = { x: (o2.x + i2.x) / 2, y: (o2.y + i2.y) / 2 };
const r3 = Fs(o2, c2), s3 = Fs(i2, c2);
if (Math.abs(r3 - s3) > 0.5 * Math.min(r3, s3)) {
const n3 = Fs(e4, o2), r4 = Fs(t2, i2), s4 = n3 + r4;
if (s4 > a2) {
const e5 = r4 / s4, t3 = n3 / s4;
c2 = { x: o2.x * e5 + i2.x * t3, y: o2.y * e5 + i2.y * t3 };
}
}
const l2 = Fs(c2, n2.center);
if (l2 < 1.05 * n2.radius) {
const e5 = { x: (c2.x - n2.center.x) / l2, y: (c2.y - n2.center.y) / l2 };
c2 = { x: n2.center.x + e5.x * n2.radius * 1.2, y: n2.center.y + e5.y * n2.radius * 1.2 };
}
} else {
const o3 = { x: (e4.x + t2.x) / 2, y: (e4.y + t2.y) / 2 }, i3 = Fs(o3, n2.center);
if (i3 < 1.1 * n2.radius) {
const e5 = { x: (o3.x - n2.center.x) / i3, y: (o3.y - n2.center.y) / i3 };
c2 = { x: n2.center.x + e5.x * n2.radius * 1.2, y: n2.center.y + e5.y * n2.radius * 1.2 };
} else
c2 = o3;
}
return { B: o2, D: i2, E: c2 };
}
function Bs(e4, t2, n2, o2) {
const i2 = [n2.x - e4.x, n2.y - e4.y], r2 = Math.sqrt(i2[0] * i2[0] + i2[1] * i2[1]);
if (r2 <= o2) {
if (r2 < 0.00000001) {
const i3 = [t2.x - e4.x, t2.y - e4.y], r3 = Math.sqrt(i3[0] * i3[0] + i3[1] * i3[1]);
return r3 < 0.00000001 ? { x: n2.x + o2, y: n2.y } : { x: n2.x + i3[0] / r3 * o2, y: n2.y + i3[1] / r3 * o2 };
}
const s3 = [i2[0] / r2, i2[1] / r2];
return { x: n2.x - s3[0] * o2, y: n2.y - s3[1] * o2 };
}
const s2 = [t2.x - e4.x, t2.y - e4.y], a2 = Math.sqrt(r2 * r2 - o2 * o2), c2 = [i2[0] / r2, i2[1] / r2], l2 = [-c2[1], c2[0]], h2 = [c2[1], -c2[0]], d2 = s2[0] * l2[0] + s2[1] * l2[1] > s2[0] * h2[0] + s2[1] * h2[1] ? l2 : h2, u2 = o2 / r2, p2 = a2 / r2, m2 = [c2[0] * p2 + d2[0] * u2, c2[1] * p2 + d2[1] * u2];
return { x: e4.x + a2 * m2[0], y: e4.y + a2 * m2[1] };
}
function Fs(e4, t2) {
const n2 = t2.x - e4.x, o2 = t2.y - e4.y;
return Math.sqrt(n2 * n2 + o2 * o2);
}
var js = 0.000000001;
function $s(e4, t2, n2, o2 = "cw") {
const i2 = Ys(e4, n2), r2 = Ys(t2, n2);
return Math.abs(r2 - i2) < js ? { left: 0, top: 0, right: 0, bottom: 0 } : function(e5, t3, n3, o3) {
const i3 = n3.maxX - n3.minX, r3 = n3.maxY - n3.minY;
if (i3 < js && r3 < js)
return { left: 0, top: 0, right: 0, bottom: 0 };
const s2 = 2 * (i3 + r3);
if (s2 < js)
return { left: 0, top: 0, right: 0, bottom: 0 };
const a2 = i3 / s2 * (2 * Math.PI), c2 = (i3 + r3) / s2 * (2 * Math.PI), l2 = (i3 + i3 + r3) / s2 * (2 * Math.PI), h2 = 2 * Math.PI, d2 = [{ name: "top", start: 0, end: a2, length: i3 }, { name: "right", start: a2, end: c2, length: r3 }, { name: "bottom", start: c2, end: l2, length: i3 }, { name: "left", start: l2, end: h2, length: r3 }], u2 = { left: 0, top: 0, right: 0, bottom: 0 }, p2 = (e6, t4, n4, o4, i4) => {
const r4 = t4 > 2 * Math.PI - js ? 2 * Math.PI : t4;
if (r4 <= e6 + js)
return 0;
if (i4) {
const t5 = Math.max(e6, n4), i5 = Math.min(r4, 2 * Math.PI), s3 = Math.max(0, i5 - t5), a3 = Math.max(e6, 0), c3 = Math.min(r4, o4);
return s3 + Math.max(0, c3 - a3);
}
{
const t5 = Math.max(e6, n4), i5 = Math.min(r4, o4);
return Math.max(0, i5 - t5);
}
};
for (const n4 of d2) {
const i4 = n4.end - n4.start;
if (i4 < js || n4.length < js)
continue;
let r4 = 0;
if (o3 === "cw") {
const o4 = e5 > t3 + js;
r4 = p2(n4.start, n4.end, e5, t3, o4);
} else {
const o4 = t3 > e5 + js;
r4 = p2(n4.start, n4.end, t3, e5, o4);
}
if (r4 > js) {
const e6 = r4 / i4;
u2[n4.name] += Math.max(0, Number.isFinite(e6) ? e6 : 0);
}
}
for (const e6 in u2)
u2[e6] = Math.max(0, Math.min(1, u2[e6]));
return u2;
}(i2, r2, n2, o2);
}
function Ys(e4, t2) {
const n2 = t2.maxX - t2.minX, o2 = t2.maxY - t2.minY;
if (n2 < js && o2 < js)
return 0;
const i2 = 2 * (n2 + o2);
if (i2 < js)
return 0;
let r2 = 0;
if (Math.abs(e4.y - t2.maxY) <= As && e4.x >= t2.minX - As && e4.x <= t2.maxX + As)
r2 = Math.max(0, Math.min(n2, e4.x - t2.minX));
else if (Math.abs(e4.x - t2.maxX) <= As && e4.y >= t2.minY - As && e4.y <= t2.maxY + As)
r2 = n2 + Math.max(0, Math.min(o2, t2.maxY - e4.y));
else if (Math.abs(e4.y - t2.minY) <= As && e4.x >= t2.minX - As && e4.x <= t2.maxX + As)
r2 = n2 + o2 + Math.max(0, Math.min(n2, t2.maxX - e4.x));
else {
if (!(Math.abs(e4.x - t2.minX) <= As && e4.y >= t2.minY - As && e4.y <= t2.maxY + As))
throw new Error(`Point (${e4.x}, ${e4.y}) does not lie on the boundary defined by ${JSON.stringify(t2)}`);
r2 = n2 + o2 + n2 + Math.max(0, Math.min(o2, e4.y - t2.minY));
}
return r2 = Math.max(0, Math.min(i2, r2)), i2 > js ? r2 / i2 * (2 * Math.PI) : 0;
}
function Xs(e4, t2, n2, o2) {
return function({ angleA: e5, angleB: t3, angleC: n3 }) {
const o3 = Math.cos(e5), i2 = Math.sin(e5), r2 = Math.cos(t3), s2 = Math.sin(t3), a2 = Math.cos(n3);
return (r2 - o3) * (Math.sin(n3) - i2) - (s2 - i2) * (a2 - o3) < 0 ? "ccw" : "cw";
}({ angleA: Ys(e4, o2), angleB: Ys(t2, o2), angleC: Ys(n2, o2) });
}
var Ws = class extends ai {
getSolverName() {
return "SingleTransitionCrossingRouteSolver";
}
nodeWithPortPoints;
routes;
viaDiameter;
traceThickness;
obstacleMargin;
layerCount = 2;
debugViaPositions;
solvedRoutes = [];
bounds;
constructor(e4) {
if (super(), this.nodeWithPortPoints = e4.nodeWithPortPoints, this.viaDiameter = e4?.viaDiameter ?? 0.3, this.traceThickness = e4?.traceThickness ?? 0.15, this.obstacleMargin = e4?.obstacleMargin ?? 0.1, this.layerCount = e4?.layerCount ?? 2, this.debugViaPositions = [], this.routes = this.extractRoutesFromNode(), this.bounds = this.calculateBounds(), this.routes.length !== 2)
return this.failed = true, void (this.error = `Expected 2 routes, but got ${this.routes.length}`);
const t2 = this.routes.flatMap((e5) => [e5.A, e5.B]).map((e5) => this.getPortPointBoundsPosition(e5));
if (t2.includes("outside"))
return this.failed = true, void (this.error = "Invalid route input: SingleTransitionCrossingRouteSolver received port point(s) outside node bounds");
if (t2.includes("inside"))
return void (this.failed = true);
this.routes = this.routes.map((e5) => ({ ...e5, A: this.snapPortPointToBounds(e5.A), B: this.snapPortPointToBounds(e5.B) }));
const [n2, o2] = this.routes, i2 = n2.A.z !== n2.B.z, r2 = o2.A.z !== o2.B.z;
return i2 && r2 || !i2 && !r2 ? (this.failed = true, void (this.error = "Exactly one route must have a layer transition")) : undefined;
}
extractRoutesFromNode() {
const e4 = [], t2 = this.nodeWithPortPoints.portPoints, n2 = new Map;
for (const e5 of t2) {
const { connectionName: t3 } = e5;
n2.has(t3) || n2.set(t3, []), n2.get(t3)?.push(e5);
}
for (const [t3, o2] of n2.entries())
o2.length === 2 && e4.push({ A: { ...o2[0], z: o2[0].z ?? 0 }, B: { ...o2[1], z: o2[1].z ?? 0 }, connectionName: t3 });
return e4;
}
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(e4) {
return Ds({ point: e4, bounds: this.bounds });
}
snapPortPointToBounds(e4) {
const t2 = Ot(e4.x, this.bounds.minX, this.bounds.maxX), n2 = Ot(e4.y, this.bounds.minY, this.bounds.maxY);
return [{ distance: Math.abs(e4.y - this.bounds.maxY), point: { ...e4, x: t2, y: this.bounds.maxY } }, { distance: Math.abs(e4.x - this.bounds.maxX), point: { ...e4, x: this.bounds.maxX, y: n2 } }, { distance: Math.abs(e4.y - this.bounds.minY), point: { ...e4, x: t2, y: this.bounds.minY } }, { distance: Math.abs(e4.x - this.bounds.minX), point: { ...e4, x: this.bounds.minX, y: n2 } }].reduce((e5, t3) => t3.distance < e5.distance ? t3 : e5).point;
}
doRoutesCross(e4, t2) {
return _t(e4.A, e4.B, t2.A, t2.B);
}
calculateViaPosition(e4, t2) {
const n2 = t2.A.z, o2 = e4.A.z !== n2 ? e4.A : e4.B, i2 = 2 * this.obstacleMargin + this.viaDiameter / 2 + this.traceThickness, r2 = this.obstacleMargin + this.viaDiameter / 2, s2 = t2.A, a2 = o2, c2 = t2.B, l2 = Xs(s2, a2, c2, this.bounds), h2 = function(e5, t3, n3, o3, i3) {
const r3 = $s(e5, t3, o3, i3), s3 = $s(t3, n3, o3, i3), a3 = { left: Math.min(1, r3.left + s3.left), top: Math.min(1, r3.top + s3.top), right: Math.min(1, r3.right + s3.right), bottom: Math.min(1, r3.bottom + s3.bottom) };
for (const e6 in a3)
Math.abs(a3[e6]) < js && (a3[e6] = 0);
return a3;
}(s2, a2, c2, this.bounds, l2), d2 = { minX: this.bounds.minX + (h2.left > 0.5 ? i2 : r2), minY: this.bounds.minY + (h2.bottom > 0.5 ? i2 : r2), maxX: this.bounds.maxX - (h2.right > 0.5 ? i2 : r2), maxY: this.bounds.maxY - (h2.top > 0.5 ? i2 : r2) };
return d2.maxY < d2.minY && (d2.minY = (d2.minY + d2.maxY) / 2, d2.maxY = d2.minY), d2.maxX < d2.minX && (d2.minX = (d2.minX + d2.maxX) / 2, d2.maxX = d2.minX), Ls(s2, a2, c2, i2, d2);
}
createTransitionRoute(e4, t2, n2, o2) {
const i2 = [{ x: e4.x, y: e4.y, z: e4.z ?? 0 }, { x: n2.x, y: n2.y, z: e4.z ?? 0 }, { x: n2.x, y: n2.y, z: t2.z ?? 0 }, { x: t2.x, y: t2.y, z: t2.z ?? 0 }];
return { connectionName: o2, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: i2, traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [n2] };
}
createFlatRoute(e4, t2, n2, o2, i2, r2) {
o2.z, e4.z;
const s2 = this.viaDiameter / 2 + this.traceThickness / 2 + this.obstacleMargin, a2 = ((e5, t3, n3, o3) => {
const i3 = n3.x - e5.x, r3 = n3.y - e5.y;
return ((e6, t4) => ({ x: (e6.x + t4.x) / 2, y: (e6.y + t4.y) / 2 }))({ x: e5.x + i3 * t3, y: e5.y + r3 * t3 }, { x: n3.x - i3 * o3, y: n3.y - r3 * o3 });
})(n2, this.viaDiameter, o2.z !== e4.z ? o2 : i2, this.traceThickness), c2 = { center: { x: n2.x, y: n2.y }, radius: s2 }, l2 = zs(e4, a2, c2).E, h2 = zs(a2, t2, c2).E, d2 = zs(e4, l2, c2).E, u2 = zs(l2, a2, c2).E, p2 = zs(a2, h2, c2).E, m2 = zs(h2, t2, c2).E, g2 = zs(u2, p2, c2).E;
return { connectionName: r2, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: [{ x: e4.x, y: e4.y, z: e4.z ?? 0 }, { x: d2.x, y: d2.y, z: e4.z ?? 0 }, { x: l2.x, y: l2.y, z: e4.z ?? 0 }, { x: u2.x, y: u2.y, z: e4.z ?? 0 }, { x: g2.x, y: g2.y, z: e4.z ?? 0 }, { x: p2.x, y: p2.y, z: e4.z ?? 0 }, { x: h2.x, y: h2.y, z: e4.z ?? 0 }, { x: m2.x, y: m2.y, z: e4.z ?? 0 }, { x: t2.x, y: t2.y, z: t2.z ?? 0 }], traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [] };
}
trySolve() {
const [e4, t2] = this.routes, n2 = e4.A.z !== e4.B.z, o2 = n2 ? e4 : t2, i2 = n2 ? t2 : e4, r2 = this.calculateViaPosition(o2, i2);
if (!r2)
return false;
this.debugViaPositions.push({ via: r2 });
const s2 = this.createTransitionRoute(o2.A, o2.B, r2, o2.connectionName), a2 = this.createFlatRoute(i2.A, i2.B, r2, o2.A, o2.B, i2.connectionName);
return this.solvedRoutes.push(s2, a2), true;
}
_step() {
if (!this.doRoutesCross(this.routes[0], this.routes[1]))
return this.failed = true, void (this.error = "Can only solve routes that have a single transition crossing");
this.trySolve() ? this.solved = true : (this.failed = true, this.error = "Failed to find a valid via position and route path");
}
visualize() {
const e4 = { lines: [], points: [], rects: [], circles: [] };
e4.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 t2 of this.routes)
e4.points.push({ x: t2.A.x, y: t2.A.y, label: `${t2.connectionName} start (z=${t2.A.z})`, color: "orange" }), e4.points.push({ x: t2.B.x, y: t2.B.y, label: `${t2.connectionName} end (z=${t2.B.z})`, color: "orange" }), e4.lines.push({ points: [t2.A, t2.B], strokeColor: "rgba(255, 0, 0, 0.5)", label: `${t2.connectionName} direct` });
for (let t2 = 0;t2 < this.debugViaPositions.length; t2++) {
const { via: n2 } = this.debugViaPositions[t2];
e4.circles.push({ center: n2, radius: this.viaDiameter / 2, fill: "rgba(255, 165, 0, 0.7)", stroke: "rgba(0, 0, 0, 0.5)", label: `Computed Via (attempt ${t2 + 1})` });
const o2 = this.viaDiameter / 2 + this.obstacleMargin;
e4.circles.push({ center: n2, radius: o2, stroke: "rgba(255, 165, 0, 0.7)", fill: "rgba(0, 0, 0, 0)", label: "Safety Margin" });
}
for (let t2 = 0;t2 < this.solvedRoutes.length; t2++) {
const n2 = this.solvedRoutes[t2], o2 = t2 % 2 == 0 ? "rgba(0, 255, 0, 0.75)" : "rgba(255, 0, 255, 0.75)";
for (let t3 = 0;t3 < n2.route.length - 1; t3++) {
const i2 = n2.route[t3], r2 = n2.route[t3 + 1];
e4.lines.push({ points: [i2, r2], strokeColor: o2, strokeDash: i2.z !== n2.route[0].z ? [0.2, 0.2] : undefined, strokeWidth: n2.traceThickness, label: `${n2.connectionName} z=${i2.z}` });
}
for (const t3 of n2.vias)
e4.circles.push({ center: t3, radius: this.viaDiameter / 2, fill: "rgba(0, 0, 255, 0.8)", stroke: "black", label: "Solved Via" }), e4.circles.push({ center: t3, radius: this.viaDiameter / 2 + this.obstacleMargin, fill: "rgba(0, 0, 255, 0.3)", stroke: "black", label: "Via Margin" });
}
return e4;
}
getSolvedRoutes() {
return this.solvedRoutes;
}
};
function Vs({ A: e4, B: t2, C: n2, D: o2, E: i2, F: r2, radius: s2, margin: a2, subdivisions: c2 = 0 }) {
const l2 = (e5, t3) => ({ x: (e5.x + t3.x) / 2, y: (e5.y + t3.y) / 2 }), h2 = (e5, t3, n3) => {
const o3 = t3.x - e5.x, i3 = t3.y - e5.y, r3 = Math.sqrt(o3 * o3 + i3 * i3), s3 = o3 / r3, a3 = i3 / r3, c3 = -a3, l3 = s3;
return { midpoint: { x: (e5.x + t3.x) / 2, y: (e5.y + t3.y) / 2 }, A_Opp: { x: e5.x - s3 * n3, y: e5.y - a3 * n3 }, A_Right: { x: e5.x + c3 * n3, y: e5.y + l3 * n3 }, A_Left: { x: e5.x - c3 * n3, y: e5.y - l3 * n3 }, B_Opp: { x: t3.x + s3 * n3, y: t3.y + a3 * n3 }, B_Right: { x: t3.x + c3 * n3, y: t3.y + l3 * n3 }, B_Left: { x: t3.x - c3 * n3, y: t3.y - l3 * n3 } };
}, d2 = (e5, t3) => {
const n3 = vt(e5, t3.start), o3 = vt(e5, t3.end), i3 = vt(t3.start, t3.end);
return Math.abs(n3 + o3 - i3) < 0.0001;
}, u2 = (e5, t3) => {
const { start: n3, end: o3 } = e5, { start: i3, end: r3 } = t3;
if (d2(n3, t3) || d2(o3, t3) || d2(i3, e5) || d2(r3, e5))
return true;
const s3 = o3.x - n3.x, a3 = o3.y - n3.y, c3 = r3.x - i3.x, l3 = r3.y - i3.y, h3 = s3 * l3 - a3 * c3;
if (Math.abs(h3) < 0.0001)
return false;
const u3 = i3.x - n3.x, p3 = i3.y - n3.y, m3 = (u3 * l3 - p3 * c3) / h3, g3 = (u3 * a3 - p3 * s3) / h3;
return m3 > 0 && m3 < 1 && g3 > 0 && g3 < 1;
}, p2 = (e5, t3) => {
const n3 = [];
for (let t4 = 0;t4 < e5.length - 1; t4++)
n3.push({ start: e5[t4], end: e5[t4 + 1] });
const o3 = [];
for (let e6 = 0;e6 < t3.length - 1; e6++)
o3.push({ start: t3[e6], end: t3[e6 + 1] });
for (const e6 of n3)
for (const t4 of o3)
if (u2(e6, t4))
return true;
return false;
}, m2 = (e5) => {
let t3 = 0;
for (let n3 = 1;n3 < e5.length; n3++) {
const o3 = e5[n3].x - e5[n3 - 1].x, i3 = e5[n3].y - e5[n3 - 1].y;
t3 += Math.sqrt(o3 * o3 + i3 * i3);
}
return t3;
}, g2 = (e5, t3) => {
const { start: n3, end: o3 } = e5, i3 = o3.x - n3.x, r3 = o3.y - n3.y, s3 = i3 * i3 + r3 * r3;
if (s3 === 0)
return { ...n3, t: 0 };
const a3 = Math.max(0, Math.min(1, ((t3.x - n3.x) * i3 + (t3.y - n3.y) * r3) / s3));
return { x: n3.x + a3 * i3, y: n3.y + a3 * r3, t: a3 };
}, f2 = (t3, n3, o3) => {
const i3 = g2(t3, n3);
if (vt(i3, n3) >= o3)
return i3;
const r3 = i3.x - n3.x, s3 = i3.y - n3.y, a3 = Math.sqrt(r3 * r3 + s3 * s3);
if (a3 === 0) {
const r4 = t3.end.x - t3.start.x, s4 = t3.end.y - t3.start.y, a4 = Math.sqrt(r4 * r4 + s4 * s4);
return { x: n3.x + o3 * r4 / a4, y: n3.y + o3 * s4 / a4, t: i3.t, isSpecial: true, specialType: n3 === e4 ? "A" : "B" };
}
return { x: n3.x + o3 * r3 / a3, y: n3.y + o3 * s3 / a3, t: i3.t, isSpecial: true, specialType: n3 === e4 ? "A" : "B" };
}, _2 = h2(e4, t2, s2), y2 = h2(e4, t2, s2 + a2), b2 = (e5, t3, n3, o3, i3) => {
const r3 = e5.points;
if (r3.length < 2)
return r3;
const a3 = n3 + o3, c3 = [r3[0]];
for (let e6 = 0;e6 < r3.length - 1; e6++) {
const n4 = { start: r3[e6], end: r3[e6 + 1] };
if (xt(t3, n4.start, n4.end) < a3) {
const e7 = g2(n4, t3), o4 = e7.x - t3.x, i4 = e7.y - t3.y, r4 = Math.sqrt(o4 * o4 + i4 * i4);
let l3 = null;
if (r4 > 0.000001)
l3 = { x: t3.x + a3 * o4 / r4, y: t3.y + a3 * i4 / r4 };
else {
const e8 = n4.end.x - n4.start.x, o5 = n4.end.y - n4.start.y, i5 = Math.sqrt(e8 * e8 + o5 * o5);
i5 > 0.000001 && (l3 = { x: t3.x + a3 * e8 / i5, y: t3.y + a3 * o5 / i5 });
}
l3 && vt(n4.start, l3) > s2 / 10 && c3.push(l3);
}
vt(c3[c3.length - 1], n4.end) > s2 / 10 && c3.push(n4.end);
}
if (c3.length > 1) {
const e6 = [c3[0]];
for (let t4 = 1;t4 < c3.length; t4++)
vt(e6[e6.length - 1], c3[t4]) > s2 / 10 && e6.push(c3[t4]);
return e6;
}
return c3;
}, x2 = (() => {
const e5 = [[n2, _2.B_Left, _2.B_Opp, _2.B_Right, l2(_2.midpoint, l2(_2.B_Right, _2.A_Right)), l2(_2.midpoint, l2(_2.A_Left, _2.B_Left)), _2.A_Left, _2.A_Opp, _2.A_Right, o2], [n2, _2.B_Right, _2.B_Opp, _2.B_Left, l2(_2.midpoint, l2(_2.A_Left, _2.B_Left)), l2(_2.midpoint, l2(_2.A_Right, _2.B_Right)), _2.A_Right, _2.A_Opp, _2.A_Left, o2], [o2, _2.B_Left, _2.B_Opp, _2.B_Right, l2(_2.midpoint, l2(_2.A_Right, _2.B_Right)), l2(_2.midpoint, l2(_2.A_Left, _2.B_Left)), _2.A_Left, _2.A_Opp, _2.A_Right, n2], [o2, _2.B_Right, _2.B_Opp, _2.B_Left, l2(_2.midpoint, l2(_2.A_Left, _2.B_Left)), l2(_2.midpoint, l2(_2.A_Right, _2.B_Right)), _2.A_Right, _2.A_Opp, _2.A_Left, n2]], t3 = [];
for (let n3 = 0;n3 < e5.length; n3++) {
const o3 = e5[n3], i4 = { start: o3[0], end: o3[1] }, r4 = { start: o3[o3.length - 2], end: o3[o3.length - 1] }, s4 = { start: o3[3], end: o3[4] };
u2(i4, r4) || u2(i4, s4) || u2(r4, s4) || t3.push({ index: n3 + 1, path: o3, length: m2(o3) });
}
if (t3.length === 0)
return { index: 0, path: [] };
const i3 = t3.sort((e6, t4) => e6.length - t4.length)[0], r3 = [...i3.path], s3 = r3[0], a3 = vt(s3, r3[2]), c3 = vt(s3, r3[3]), h3 = a3 < c3 ? 2 : 3;
(a3 < vt(s3, r3[1]) || c3 < vt(s3, r3[1])) && r3.splice(1, h3 - 1);
const d3 = r3[r3.length - 1], p3 = vt(d3, r3[r3.length - 3]), g3 = vt(d3, r3[r3.length - 4]), f3 = p3 < g3 ? r3.length - 3 : r3.length - 4;
return (p3 < vt(d3, r3[r3.length - 2]) || g3 < vt(d3, r3[r3.length - 2])) && r3.splice(f3 + 1, r3.length - f3 - 2), { index: i3.index, path: r3, startsAt: r3[0] === n2 ? "C" : "D", goesTo: r3[r3.length - 1] === n2 ? "C" : "D" };
})(), v2 = c2 > 0 ? ((n3, o3) => {
if (n3.length < 2)
return n3;
const i3 = [n3[0]];
for (let r3 = 0;r3 < n3.length - 1; r3++) {
const a3 = { start: n3[r3], end: n3[r3 + 1] }, c3 = { x: (a3.start.x + a3.end.x) / 2, y: (a3.start.y + a3.end.y) / 2 }, l3 = vt(c3, e4), h3 = vt(c3, t2);
if ((l3 <= s2 || h3 <= s2) && Math.abs(l3 - h3) > 0.0001) {
const n4 = g2(a3, e4), r4 = g2(a3, t2), c4 = vt(n4, e4), l4 = vt(r4, t2) < s2, h4 = c4 < s2 ? f2(a3, e4, s2) : null, d3 = l4 ? f2(a3, t2, s2) : null;
let u3 = [];
if (vt(a3.start, a3.end) > s2 / 2 && o3 > 0)
for (let n5 = 1;n5 <= o3; n5++) {
const i4 = n5 / (o3 + 1), r5 = { x: a3.start.x + i4 * (a3.end.x - a3.start.x), y: a3.start.y + i4 * (a3.end.y - a3.start.y), t: i4, isSpecial: false }, c5 = vt(r5, e4), l5 = vt(r5, t2);
c5 < s2 || l5 < s2 || (h4 && Math.abs(r5.t - h4.t) < 0.1 || d3 && Math.abs(r5.t - d3.t) < 0.1 || u3.push(r5));
}
if (h4 && u3.push(h4), d3 && u3.push(d3), u3.sort((e5, t3) => e5.t - t3.t), u3.length > 1) {
const e5 = [u3[0]];
for (let t3 = 1;t3 < u3.length; t3++) {
const n5 = e5[e5.length - 1], o4 = u3[t3];
vt(n5, o4) > s2 / 10 && e5.push(o4);
}
u3 = e5;
}
u3.forEach((e5) => i3.push(e5));
}
i3.push(n3[r3 + 1]);
}
if (i3.length > 1) {
const e5 = [i3[0]];
for (let t3 = 1;t3 < i3.length; t3++) {
const n4 = e5[e5.length - 1], o4 = i3[t3];
vt(n4, o4) > s2 / 10 && e5.push(o4);
}
return e5;
}
return i3;
})(x2.path, c2) : x2.path;
let I2 = (() => {
if (x2.path.length === 0)
return null;
const n3 = (() => {
const n4 = l2(_2.A_Right, _2.B_Right), o4 = l2(_2.B_Left, _2.A_Left);
return [{ startsAt: "E", goesTo: "B", points: [i2, t2] }, { startsAt: "E", goesTo: "A", points: [i2, e4] }, { startsAt: "F", goesTo: "B", points: [r2, t2] }, { startsAt: "F", goesTo: "A", points: [r2, e4] }, { startsAt: "E", goesTo: "B", points: [i2, n4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, n4, e4] }, { startsAt: "F", goesTo: "B", points: [r2, n4, t2] }, { startsAt: "F", goesTo: "A", points: [r2, n4, e4] }, { startsAt: "E", goesTo: "B", points: [i2, o4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, o4, e4] }, { startsAt: "F", goesTo: "B", points: [r2, o4, t2] }, { startsAt: "F", goesTo: "A", points: [r2, o4, e4] }, { startsAt: "E", goesTo: "B", points: [i2, y2.A_Right, n4, t2] }, { startsAt: "F", goesTo: "B", points: [r2, y2.B_Right, n4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, y2.B_Left, o4, e4] }, { startsAt: "F", goesTo: "A", points: [r2, y2.A_Left, o4, e4] }, { startsAt: "E", goesTo: "B", points: [i2, y2.A_Left, o4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, y2.B_Right, n4, e4] }, { startsAt: "E", goesTo: "B", points: [i2, y2.A_Opp, y2.A_Right, n4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, y2.B_Opp, y2.B_Left, o4, e4] }, { startsAt: "F", goesTo: "B", points: [r2, y2.A_Opp, y2.A_Left, o4, t2] }, { startsAt: "F", goesTo: "A", points: [r2, y2.B_Opp, y2.B_Right, n4, e4] }, { startsAt: "F", goesTo: "A", points: [r2, y2.B_Opp, y2.B_Left, o4, e4] }, { startsAt: "E", goesTo: "B", points: [i2, y2.A_Opp, y2.A_Left, o4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, y2.B_Opp, y2.B_Right, n4, e4] }, { startsAt: "E", goesTo: "B", points: [i2, y2.A_Left, y2.A_Opp, y2.A_Right, n4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, y2.B_Right, y2.B_Opp, y2.B_Left, o4, e4] }, { startsAt: "F", goesTo: "B", points: [r2, y2.A_Right, y2.A_Opp, y2.A_Left, o4, t2] }, { startsAt: "F", goesTo: "A", points: [r2, y2.B_Left, y2.B_Opp, y2.B_Right, n4, e4] }, { startsAt: "F", goesTo: "A", points: [r2, y2.B_Right, y2.B_Opp, y2.B_Left, o4, e4] }, { startsAt: "E", goesTo: "B", points: [i2, y2.A_Right, y2.A_Opp, y2.A_Left, o4, t2] }, { startsAt: "E", goesTo: "A", points: [i2, y2.B_Left, y2.B_Opp, y2.B_Right, n4, e4] }].map((e5, t3) => ({ ...e5, index: t3 }));
})(), o3 = n3.filter((e5) => e5.startsAt === "E"), s3 = n3.filter((e5) => e5.startsAt === "F"), a3 = [], c3 = [];
for (const e5 of o3)
if (!p2(e5.points, x2.path)) {
a3.push(e5);
break;
}
for (const e5 of s3)
if (!p2(e5.points, x2.path)) {
c3.push(e5);
break;
}
return a3.length === 0 || c3.length === 0 ? null : { line1: a3[0], line2: c3[0] };
})();
if (I2) {
const n3 = I2.line1.goesTo === "A" ? t2 : e4, o3 = I2.line2.goesTo === "A" ? t2 : e4, i3 = b2(I2.line1, n3, s2, a2), r3 = b2(I2.line2, o3, s2, a2);
I2 = { line1: { ...I2.line1, points: i3 }, line2: { ...I2.line2, points: r3 } };
}
return { jPair: I2, optimalPath: { startsAt: x2.startsAt, goesTo: x2.goesTo, points: v2 } };
}
var Hs = class extends ai {
getSolverName() {
return "TwoCrossingRoutesHighDensitySolver";
}
nodeWithPortPoints;
routes;
viaDiameter;
traceThickness;
obstacleMargin;
layerCount = 2;
debugViaPositions;
escapeLayer = 1;
solvedRoutes = [];
bounds;
constructor(e4) {
if (super(), this.nodeWithPortPoints = e4.nodeWithPortPoints, this.viaDiameter = e4?.viaDiameter ?? 0.3, this.traceThickness = e4?.traceThickness ?? 0.15, this.obstacleMargin = e4?.obstacleMargin ?? 0.1, this.layerCount = e4?.layerCount ?? 2, this.debugViaPositions = [], this.routes = this.extractRoutesFromNode(), this.bounds = this.calculateBounds(), this.routes.length !== 2)
return this.failed = true, void (this.error = `Expected 2 routes, but got ${this.routes.length}`);
const [t2, n2] = this.routes;
if (!(t2.startPort.z === t2.endPort.z))
return this.failed = true, void (this.error = "Route A must start and end on the same layer");
if (!(n2.startPort.z === n2.endPort.z))
return this.failed = true, void (this.error = "Route B must start and end on the same layer");
if (!(t2.startPort.z === n2.startPort.z))
return this.failed = true, void (this.error = "Both routes must be on the same layer");
t2.startPort.z === 0 ? this.escapeLayer = 1 : this.escapeLayer = 0;
}
extractRoutesFromNode() {
const e4 = [], t2 = this.nodeWithPortPoints.portPoints, n2 = new Map;
for (const e5 of t2) {
const { connectionName: t3 } = e5;
n2.has(t3) || n2.set(t3, []), n2.get(t3)?.push(e5);
}
for (const [t3, o2] of n2.entries())
o2.length === 2 && e4.push({ startPort: { ...o2[0], z: o2[0].z ?? 0 }, endPort: { ...o2[1], z: o2[1].z ?? 0 }, connectionName: t3 });
return e4;
}
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(e4, t2) {
return _t(e4.startPort, e4.endPort, t2.startPort, t2.endPort);
}
calculateViaPositions(e4, t2) {
const n2 = this.bounds.maxX - this.bounds.minX, o2 = this.bounds.maxY - this.bounds.minY, i2 = this.bounds.minX, r2 = this.bounds.minY, s2 = { width: n2 - 2 * this.obstacleMargin - this.viaDiameter, height: o2 - 2 * this.obstacleMargin - this.viaDiameter, x: i2 + this.obstacleMargin + this.viaDiameter / 2, y: r2 + this.obstacleMargin + this.viaDiameter / 2 }, a2 = this.viaDiameter + this.obstacleMargin, c2 = t2.startPort, l2 = t2.endPort, h2 = [{ x: s2.x, y: s2.y }, { x: s2.x + s2.width, y: s2.y }, { x: s2.x + s2.width, y: s2.y + s2.height }, { x: s2.x, y: s2.y + s2.height }], d2 = (e5, t3) => vt(e5, t3), u2 = [];
h2.forEach((e5, t3) => {
d2(e5, c2) >= a2 && d2(e5, l2) >= a2 && u2.push({ ...e5, type: "corner", index: t3 });
});
const p2 = [{ p1: h2[0], p2: h2[1] }, { p1: h2[1], p2: h2[2] }, { p1: h2[2], p2: h2[3] }, { p1: h2[3], p2: h2[0] }];
if ([c2, l2].forEach((e5, t3) => {
p2.forEach((n3, o3) => {
((e6, t4) => {
const { x: n4, y: o4, r: i3 } = e6, r3 = t4.p1.x, s3 = t4.p1.y, a3 = t4.p2.x, c3 = t4.p2.y;
if (Math.abs(a3 - r3) < 0.001) {
const e7 = r3, t5 = i3 * i3 - (e7 - n4) ** 2;
if (t5 < 0)
return [];
if (Math.abs(t5) < 0.001) {
const t6 = o4;
return t6 >= Math.min(s3, c3) && t6 <= Math.max(s3, c3) ? [{ x: e7, y: t6 }] : [];
}
const a4 = o4 + Math.sqrt(t5), l4 = o4 - Math.sqrt(t5), h4 = [];
return a4 >= Math.min(s3, c3) && a4 <= Math.max(s3, c3) && h4.push({ x: e7, y: a4 }), l4 >= Math.min(s3, c3) && l4 <= Math.max(s3, c3) && h4.push({ x: e7, y: l4 }), h4;
}
const l3 = (c3 - s3) / (a3 - r3), h3 = s3 - l3 * r3, d3 = 1 + l3 * l3, u3 = 2 * (l3 * h3 - l3 * o4 - n4), p3 = u3 * u3 - 4 * d3 * (n4 * n4 + (h3 - o4) * (h3 - o4) - i3 * i3);
if (p3 < 0)
return [];
if (Math.abs(p3) < 0.001) {
const e7 = -u3 / (2 * d3), t5 = l3 * e7 + h3;
return e7 >= Math.min(r3, a3) && e7 <= Math.max(r3, a3) && t5 >= Math.min(s3, c3) && t5 <= Math.max(s3, c3) ? [{ x: e7, y: t5 }] : [];
}
const m3 = (-u3 + Math.sqrt(p3)) / (2 * d3), g3 = (-u3 - Math.sqrt(p3)) / (2 * d3), f3 = l3 * m3 + h3, _3 = l3 * g3 + h3, y3 = [];
return m3 >= Math.min(r3, a3) && m3 <= Math.max(r3, a3) && f3 >= Math.min(s3, c3) && f3 <= Math.max(s3, c3) && y3.push({ x: m3, y: f3 }), g3 >= Math.min(r3, a3) && g3 <= Math.max(r3, a3) && _3 >= Math.min(s3, c3) && _3 <= Math.max(s3, c3) && y3.push({ x: g3, y: _3 }), y3;
})({ ...e5, r: a2 }, n3).forEach((e6) => {
d2(e6, t3 === 0 ? l2 : c2) >= a2 && u2.push({ ...e6, type: "intersection", circle: t3, edge: o3 });
});
});
}), u2.length < 2) {
const e5 = 0.8 * a2;
if (h2.forEach((t3, n3) => {
d2(t3, c2) >= e5 && d2(t3, l2) >= e5 && !u2.some((e6) => e6.x === t3.x && e6.y === t3.y) && u2.push({ ...t3, type: "relaxed_corner", index: n3 });
}), u2.length < 2) {
const e6 = [...h2].sort((e7, t3) => {
const n3 = Math.min(d2(e7, c2), d2(e7, l2));
return Math.min(d2(t3, c2), d2(t3, l2)) - n3;
});
for (const t3 of e6)
if (!u2.some((e7) => e7.x === t3.x && e7.y === t3.y) && (u2.push({ ...t3, type: "forced_corner" }), u2.length >= 2))
break;
}
}
if (u2.length < 2)
return null;
let m2 = 0, g2 = [u2[0], u2[u2.length > 1 ? 1 : 0]];
for (let e5 = 0;e5 < u2.length; e5++)
for (let t3 = e5 + 1;t3 < u2.length; t3++) {
const n3 = d2(u2[e5], u2[t3]);
n3 > m2 && (m2 = n3, g2 = [u2[e5], u2[t3]]);
}
let f2 = { x: g2[0].x, y: g2[0].y }, _2 = { x: g2[1].x, y: g2[1].y };
const y2 = vt(f2, e4.startPort);
return vt(_2, e4.startPort) < y2 && ([f2, _2] = [_2, f2]), { via1: f2, via2: _2 };
}
trySolveAOverB(e4, t2, n2 = false) {
const o2 = n2 ? this.calculateViaPositions(e4, t2) : this.calculateViaPositions(t2, e4);
if (!o2)
return false;
this.debugViaPositions.push(o2);
const { via1: i2, via2: r2 } = this.pushViasFromEndpoints(this.moveViasAsCloseAsPossible(o2));
this.debugViaPositions.push({ via1: i2, via2: r2 });
const { jPair: s2, optimalPath: a2 } = Vs({ A: i2, B: r2, C: e4.startPort, D: e4.endPort, E: t2.startPort, F: t2.endPort, radius: this.viaDiameter / 2 + this.obstacleMargin + this.traceThickness / 2 * 1.5, margin: 2 * this.obstacleMargin + this.traceThickness / 2 * 1.5, subdivisions: 1 });
if (!s2)
return false;
const c2 = { connectionName: e4.connectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: a2.points.map((t3) => ({ x: t3.x, y: t3.y, z: e4.startPort.z ?? 0 })), traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [] };
s2.line2.points.reverse();
const l2 = { connectionName: t2.connectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: [...s2.line1.points.map((e5) => ({ x: e5.x, y: e5.y, z: t2.startPort.z ?? 0 })), { ...s2.line1.points[s2.line1.points.length - 1], z: this.escapeLayer }, { ...s2.line2.points[0], z: this.escapeLayer }, ...s2.line2.points.map((e5) => ({ x: e5.x, y: e5.y, z: t2.startPort.z ?? 0 }))], traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [i2, r2] };
return this.solvedRoutes.push(c2, l2), true;
}
pushViasFromEndpoints(e4) {
const t2 = { ...e4.via1 }, n2 = { ...e4.via2 }, o2 = [this.routes[0].startPort, this.routes[0].endPort, this.routes[1].startPort, this.routes[1].endPort], i2 = this.getMinDistanceBetweenViaCenters(), r2 = this.viaDiameter / 2 + 2 * this.traceThickness + 2 * this.obstacleMargin;
for (let e5 = 0;e5 < 10; e5++) {
let s3 = false, a2 = false;
const c2 = 0.9 ** e5;
for (const e6 of o2) {
const o3 = vt(t2, e6);
if (o3 < r2) {
const n3 = (r2 - o3) * c2, i4 = t2.x - e6.x, a3 = t2.y - e6.y, l3 = Math.sqrt(i4 * i4 + a3 * a3);
l3 > 0.000001 && (t2.x += i4 / l3 * n3, t2.y += a3 / l3 * n3, s3 = true);
}
const i3 = vt(n2, e6);
if (i3 < r2) {
const t3 = (r2 - i3) * c2, o4 = n2.x - e6.x, s4 = n2.y - e6.y, l3 = Math.sqrt(o4 * o4 + s4 * s4);
l3 > 0.000001 && (n2.x += o4 / l3 * t3, n2.y += s4 / l3 * t3, a2 = true);
}
}
const l2 = vt(t2, n2);
if (l2 < i2) {
const e6 = (i2 - l2) / 2, o3 = n2.x - t2.x, r3 = n2.y - t2.y, c3 = Math.sqrt(o3 * o3 + r3 * r3);
c3 > 0.000001 ? (t2.x -= o3 / c3 * e6, t2.y -= r3 / c3 * e6, n2.x += o3 / c3 * e6, n2.y += r3 / c3 * e6, s3 = true, a2 = true) : (t2.x -= e6, n2.x += e6, s3 = true, a2 = true);
}
if (!s3 && !a2)
break;
}
const s2 = vt(t2, n2);
if (s2 < i2) {
const e5 = (i2 - s2) / 2, o3 = n2.x - t2.x, r3 = n2.y - t2.y, a2 = Math.sqrt(o3 * o3 + r3 * r3);
a2 > 0.000001 ? (t2.x -= o3 / a2 * e5, t2.y -= r3 / a2 * e5, n2.x += o3 / a2 * e5, n2.y += r3 / a2 * e5) : (t2.x -= e5, n2.x += e5);
}
return { via1: t2, via2: n2 };
}
getMinDistanceBetweenViaCenters() {
return this.viaDiameter + this.traceThickness + 2 * this.obstacleMargin;
}
moveViasAsCloseAsPossible(e4) {
const { via1: t2, via2: n2 } = e4, o2 = this.getMinDistanceBetweenViaCenters(), i2 = vt(t2, n2);
if (i2 <= o2)
return e4;
const r2 = n2.x - t2.x, s2 = n2.y - t2.y, a2 = Math.sqrt(r2 * r2 + s2 * s2), c2 = r2 / a2, l2 = s2 / a2, h2 = (t2.x, n2.x, t2.y, n2.y, (i2 - o2) / 2);
return { via1: { x: t2.x + c2 * h2, y: t2.y + l2 * h2 }, via2: { x: n2.x - c2 * h2, y: n2.y - l2 * h2 } };
}
handleRoutesDontCross() {
const [e4, t2] = this.routes, n2 = { connectionName: e4.connectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: [{ x: e4.startPort.x, y: e4.startPort.y, z: e4.startPort.z ?? 0 }, { x: e4.endPort.x, y: e4.endPort.y, z: e4.endPort.z ?? 0 }], traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [] }, o2 = { connectionName: t2.connectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, route: [{ x: t2.startPort.x, y: t2.startPort.y, z: t2.startPort.z ?? 0 }, { x: t2.endPort.x, y: t2.endPort.y, z: t2.endPort.z ?? 0 }], traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, vias: [] };
this.solvedRoutes.push(n2, o2), this.solved = true;
}
_step() {
if (this.routes.length !== 2)
return void (this.failed = true);
const [e4, t2] = this.routes;
this.doRoutesCross(e4, t2) ? this.trySolveAOverB(e4, t2) || this.trySolveAOverB(t2, e4) || this.trySolveAOverB(e4, t2, true) || this.trySolveAOverB(t2, e4, true) ? this.solved = true : (this.failed = true, this.error = "All crossover strategies failed") : this.handleRoutesDontCross();
}
visualize() {
const e4 = { lines: [], points: [], rects: [], circles: [] };
e4.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 [t2, n2] of [["Route A", this.routes[0]], ["Route B", this.routes[1]]])
e4.points.push({ x: n2.startPort.x, y: n2.startPort.y, label: `${t2}
${n2.connectionName} start`, color: "orange" }), e4.points.push({ x: n2.endPort.x, y: n2.endPort.y, label: `${t2}
${n2.connectionName} end`, color: "orange" }), e4.lines.push({ points: [n2.startPort, n2.endPort], strokeColor: "rgba(255, 0, 0, 0.5)", label: `${t2}
${n2.connectionName} direct` });
for (let t2 = 0;t2 < this.debugViaPositions.length; t2++) {
const { via1: n2, via2: o2 } = this.debugViaPositions[t2], i2 = ["rgba(255, 165, 0, 0.3)", "rgba(128, 0, 128, 0.3)"], r2 = i2[t2 % i2.length];
e4.circles.push({ center: n2, radius: this.viaDiameter / 2, fill: r2, stroke: "rgba(0, 0, 0, 0.3)", label: `Computed Via A (attempt ${t2 + 1})` }), e4.circles.push({ center: o2, radius: this.viaDiameter / 2, fill: r2, stroke: "rgba(0, 0, 0, 0.3)", label: `Computed Via B (attempt ${t2 + 1})` });
const s2 = this.viaDiameter / 2 + this.obstacleMargin;
e4.circles.push({ center: n2, radius: s2, stroke: r2, fill: "rgba(0, 0, 0, 0)", label: `Debug Via 1 Safety Margin (attempt ${t2 + 1})` }), e4.circles.push({ center: o2, radius: s2, stroke: r2, fill: "rgba(0, 0, 0, 0)", label: `Debug Via 2 Safety Margin (attempt ${t2 + 1})` }), e4.lines.push({ points: [this.routes[t2 % 2].startPort, n2, o2, this.routes[t2 % 2].endPort], strokeColor: `${r2.substring(0, r2.lastIndexOf(","))}, 0.3)`, strokeDash: [5, 5], label: `Potential Route (attempt ${t2 + 1})` });
}
for (let t2 = 0;t2 < this.solvedRoutes.length; t2++) {
const n2 = this.solvedRoutes[t2], o2 = t2 % 2 == 0 ? "rgba(0, 255, 0, 0.75)" : "rgba(255, 0, 255, 0.75)";
for (let t3 = 0;t3 < n2.route.length - 1; t3++) {
const i2 = n2.route[t3], r2 = n2.route[t3 + 1];
e4.lines.push({ points: [i2, r2], strokeColor: o2, strokeDash: i2.z === 1 ? [0.2, 0.2] : undefined, strokeWidth: n2.traceThickness, label: `${n2.connectionName} z=${i2.z}` }), i2._label && e4.points.push({ x: i2.x, y: i2.y, label: i2._label });
}
for (const t3 of n2.vias)
e4.circles.push({ center: t3, radius: this.viaDiameter / 2, fill: "rgba(0, 0, 255, 0.8)", stroke: "black", label: "Solved Via" }), e4.circles.push({ center: t3, radius: this.viaDiameter / 2 + this.obstacleMargin, fill: "rgba(0, 0, 255, 0.3)", stroke: "black", label: "Solved Via Margin" });
}
return e4;
}
getSolvedRoutes() {
return this.solvedRoutes;
}
};
var Gs = class extends ai {
getSolverName() {
return "HyperParameterSupervisorSolver";
}
GREEDY_MULTIPLIER = 1.2;
MIN_SUBSTEPS = 1;
supervisedSolvers;
winningSolver;
getHyperParameterDefs() {
throw new Error("Not implemented");
}
getCombinationDefs() {
return null;
}
getHyperParameterCombinations(e4) {
e4 || (e4 = this.getHyperParameterDefs());
const t2 = [];
if (e4.length === 0)
return [{}];
const [n2, ...o2] = e4, i2 = this.getHyperParameterCombinations(o2);
return n2.possibleValues.forEach((e5) => {
i2.forEach((n3) => {
t2.push({ ...n3, ...e5 });
});
}), t2;
}
initializeSolvers() {
const e4 = this.getHyperParameterDefs(), t2 = this.getCombinationDefs() ?? [e4.map((e5) => e5.name)];
this.supervisedSolvers = [];
for (const n2 of t2) {
const t3 = this.getHyperParameterCombinations(e4.filter((e5) => n2.includes(e5.name)));
for (const e5 of t3) {
const t4 = this.generateSolver(e5), n3 = this.computeG(t4);
this.supervisedSolvers.push({ hyperParameters: e5, solver: t4, h: 0, g: n3, f: n3 });
}
}
}
generateSolver(e4) {
throw new Error("Not implemented");
}
computeG(e4) {
return e4.iterations / e4.MAX_ITERATIONS;
}
computeH(e4) {
return 1 - (e4.progress || 0);
}
computeF(e4, t2) {
return e4 + t2 * this.GREEDY_MULTIPLIER;
}
getSupervisedSolverWithBestFitness() {
let e4 = 1 / 0, t2 = null;
for (const n2 of this.supervisedSolvers ?? []) {
if (n2.solver.solved)
return n2;
if (n2.solver.failed)
continue;
const o2 = n2.f;
o2 < e4 && (e4 = o2, t2 = n2);
}
return t2;
}
getFailureMessage() {
return `All solvers failed in hyper solver. Example failures: ${this.supervisedSolvers?.sort((e4, t2) => t2.f - e4.f)?.slice(0, 5).map((e4) => e4.solver.error).join(", ")}`;
}
_step() {
this.supervisedSolvers || this.initializeSolvers();
const e4 = this.getSupervisedSolverWithBestFitness();
if (!e4)
return this.failed = true, void (this.error = this.getFailureMessage());
for (let t2 = 0;t2 < this.MIN_SUBSTEPS; t2++)
e4.solver.step();
this.activeSubSolver = e4.solver, e4.g = this.computeG(e4.solver), e4.h = this.computeH(e4.solver), e4.f = this.computeF(e4.g, e4.h), e4.solver.solved && (this.solved = true, this.winningSolver = e4.solver, this.onSolve?.(e4));
}
onSolve(e4) {}
visualize() {
const e4 = this.getSupervisedSolverWithBestFitness();
let t2 = { lines: [], circles: [], points: [], rects: [] };
return e4 && (t2 = e4.solver.visualize()), t2;
}
};
function Us(e4, t2, n2) {
const o2 = t2.z !== n2.z && e4.allowBlindAndBuriedVias !== true;
return { minZ: o2 ? 0 : Math.min(t2.z, n2.z), maxZ: o2 ? e4.layerCount - 1 : Math.max(t2.z, n2.z) };
}
var Zs = class {
values = [];
positions;
constructor(e4) {
if (e4 === undefined)
this.positions = new Map;
else {
if (!Number.isSafeInteger(e4) || e4 <= 0)
throw new Error("repair04: dense path queue requires a positive grid size");
const t2 = new Int32Array(e4);
this.positions = { get: (e5) => t2[e5] === 0 ? undefined : t2[e5] - 1, set: (e5, n2) => {
t2[e5] = n2 + 1;
}, delete: (e5) => {
t2[e5] = 0;
} };
}
}
get length() {
return this.values.length;
}
push(e4) {
let t2 = this.positions.get(e4.id);
if (t2 === undefined)
t2 = this.values.length, this.values.push(e4);
else if (e4.priority > this.values[t2].priority)
throw new Error("repair04: queued path priorities may only decrease");
for (;t2 > 0; ) {
const n2 = Math.floor((t2 - 1) / 2), o2 = this.values[n2];
if (o2.priority <= e4.priority)
break;
this.values[t2] = o2, this.positions.set(o2.id, t2), t2 = n2;
}
this.values[t2] = e4, this.positions.set(e4.id, t2);
}
pop() {
const e4 = this.values[0];
if (!e4)
throw new Error("repair04: cannot pop an empty path queue");
const t2 = this.values.pop();
if (this.positions.delete(e4.id), this.values.length) {
let e5 = 0;
for (;2 * e5 + 1 < this.values.length; ) {
let n2 = 2 * e5 + 1;
n2 + 1 < this.values.length && this.values[n2 + 1].priority < this.values[n2].priority && n2++;
const o2 = this.values[n2];
if (o2.priority >= t2.priority)
break;
this.values[e5] = o2, this.positions.set(o2.id, e5), e5 = n2;
}
this.values[e5] = t2, this.positions.set(t2.id, e5);
}
return e4;
}
};
var qs = (e4, t2) => {
const n2 = [];
for (let o2 = 0;o2 < e4.route.length; o2 += 1) {
const i2 = e4.route[o2];
if (i2.route_type !== "via") {
n2.push(structuredClone(i2));
continue;
}
const r2 = n2[n2.length - 1], s2 = e4.route[o2 + 1], a2 = r2?.route_type === "wire" ? r2.width : s2?.route_type === "wire" ? s2.width : t2, c2 = s2?.route_type === "wire" ? s2.width : a2;
r2?.route_type === "wire" && r2.x === i2.x && r2.y === i2.y && r2.layer === i2.from_layer || n2.push({ route_type: "wire", x: i2.x, y: i2.y, layer: i2.from_layer, width: a2 }), n2.push(structuredClone(i2)), s2?.route_type === "wire" && s2.x === i2.x && s2.y === i2.y && s2.layer === i2.to_layer || n2.push({ route_type: "wire", x: i2.x, y: i2.y, layer: i2.to_layer, width: c2 });
}
return { ...structuredClone(e4), route: n2 };
};
function Js(e4, t2, n2) {
return Math.max(n2 ? 0 : t2, e4.defaultObstacleMargin ?? 0, e4.minViaEdgeToPadEdgeClearance ?? 0);
}
var Qs = 0.00000001;
var Ks = (e4, t2, n2 = 0) => e4.x >= t2.minX + n2 - Qs && e4.x <= t2.maxX - n2 + Qs && e4.y >= t2.minY + n2 - Qs && e4.y <= t2.maxY - n2 + Qs;
var ea = (e4, t2, n2) => {
let o2 = 0, i2 = 1;
for (const [r2, s2, a2, c2] of [[e4.x, t2.x - e4.x, n2.minX, n2.maxX], [e4.y, t2.y - e4.y, n2.minY, n2.maxY]]) {
if (r2 === undefined || s2 === undefined || a2 === undefined || c2 === undefined)
throw new Error("Invalid segment clipping axis");
if (Math.abs(s2) <= Qs) {
if (r2 < a2 - Qs || r2 > c2 + Qs)
return;
continue;
}
const e5 = (a2 - r2) / s2, t3 = (c2 - r2) / s2;
if (o2 = Math.max(o2, Math.min(e5, t3)), i2 = Math.min(i2, Math.max(e5, t3)), i2 < o2 - Qs)
return;
}
return [Math.max(0, o2), Math.min(1, i2)];
};
var ta = (e4, t2, n2) => {
if (n2 <= Qs)
return structuredClone(e4);
if (n2 >= 0.99999999)
return structuredClone(t2);
const o2 = { ...structuredClone(e4), x: e4.x + (t2.x - e4.x) * n2, y: e4.y + (t2.y - e4.y) * n2 };
return delete o2.pcb_port_id, o2;
};
var na = (e4, t2) => Math.abs(e4.x - t2.x) <= Qs && Math.abs(e4.y - t2.y) <= Qs && e4.z === t2.z;
var oa = (e4) => Array.isArray(e4) ? `[${e4.map(oa).join(",")}]` : e4 !== null && typeof e4 == "object" ? `{${Object.keys(e4).filter((t2) => e4[t2] !== undefined).sort().map((t2) => `${JSON.stringify(t2)}:${oa(e4[t2])}`).join(",")}}` : JSON.stringify(e4) ?? "undefined";
var ia = (e4, t2, n2) => {
if (e4.route.length === 1)
return structuredClone(e4.route);
const o2 = (t3) => {
const n3 = Math.min(Math.floor(t3), e4.route.length - 2);
return ta(e4.route[n3], e4.route[n3 + 1], t3 - n3);
}, i2 = [o2(t2)];
for (let o3 = Math.floor(t2) + 1;o3 < n2 - Qs; o3 += 1)
i2.push(structuredClone(e4.route[o3]));
return n2 > t2 + Qs && i2.push(o2(n2)), i2;
};
var ra = (e4, t2, n2) => {
const o2 = ia(e4, t2, n2), i2 = Object.fromEntries(Object.entries(e4).filter(([e5]) => e5 !== "route" && e5 !== "vias")), r2 = e4.vias.filter((e5) => o2.some((t3) => Math.hypot(t3.x - e5.x, t3.y - e5.y) <= Qs));
return oa({ metadata: i2, points: o2, vias: r2 });
};
var sa = {};
a(sa, { all_layers: () => Id, any_circuit_element: () => Dm, any_soup_element: () => Lm, any_source_component: () => pd, asset: () => dh, base_circuit_json_error: () => wh, battery_capacity: () => nh, brep_shape: () => du, cadModelDefaultDirectionMap: () => _m, cad_component: () => ym, cad_model_axis_directions: () => fm, cad_model_formats: () => gm, capacitance: () => Wl, circuit_json_footprint_load_error: () => Yp, current: () => ql, distance: () => Zl, duration_ms: () => Jl, experiment_type: () => Nm, external_footprint_load_error: () => $p, frequency: () => Ul, getZodPrefixedIdWithDefault: () => ch, inductance: () => Vl, kicadAt: () => uh, kicadEffects: () => mh, kicadFont: () => ph, kicadFootprintAttributes: () => _h, kicadFootprintMetadata: () => xh, kicadFootprintModel: () => bh, kicadFootprintPad: () => yh, kicadFootprintProperties: () => fh, kicadProperty: () => gh, kicadSymbolEffects: () => Sh, kicadSymbolMetadata: () => Mh, kicadSymbolPinNames: () => Ih, kicadSymbolPinNumbers: () => vh, kicadSymbolProperties: () => Ph, kicadSymbolProperty: () => Ch, layer_ref: () => Cd, layer_string: () => Sd, length: () => Gl, manufacturing_drc_properties: () => gu, ms: () => Kl, ninePointAnchor: () => lh, pcbRenderLayer: () => hh, pcb_autorouting_error: () => Wp, pcb_board: () => lp, pcb_breakout_point: () => Zp, pcb_component: () => fu, pcb_component_invalid_layer_error: () => sm, pcb_component_not_on_board_edge_error: () => rm, pcb_component_outside_board_error: () => im, pcb_connector_not_in_accessible_orientation_warning: () => Gp, pcb_copper_pour: () => om, pcb_copper_pour_brep: () => tm, pcb_copper_pour_polygon: () => nm, pcb_copper_pour_rect: () => em, pcb_copper_text: () => _p, pcb_courtyard_circle: () => mm, pcb_courtyard_outline: () => um, pcb_courtyard_overlap_error: () => Ap, pcb_courtyard_polygon: () => pm, pcb_courtyard_rect: () => dm, pcb_cutout: () => Fp, pcb_cutout_circle: () => Lp, pcb_cutout_path: () => Bp, pcb_cutout_polygon: () => zp, pcb_cutout_rect: () => Dp, pcb_fabrication_note_dimension: () => Pp, pcb_fabrication_note_path: () => Sp, pcb_fabrication_note_rect: () => Cp, pcb_fabrication_note_text: () => Ip, pcb_footprint_overlap_error: () => Ep, pcb_ground_plane: () => qp, pcb_ground_plane_region: () => Jp, pcb_group: () => Xp, pcb_hole: () => Tu, pcb_hole_circle_or_square_shape: () => Iu, pcb_hole_circle_shape: () => yu, pcb_hole_oval_shape: () => Cu, pcb_hole_pill_shape: () => Mu, pcb_hole_rect_shape: () => xu, pcb_hole_rotated_pill_shape: () => Nu, pcb_keepout: () => Op, pcb_manual_edit_conflict_warning: () => Vp, pcb_missing_footprint_error: () => jp, pcb_net: () => ap, pcb_note_dimension: () => Rp, pcb_note_line: () => Tp, pcb_note_path: () => Np, pcb_note_rect: () => wp, pcb_note_text: () => Mp, pcb_pad_pad_clearance_error: () => lm, pcb_pad_trace_clearance_error: () => hm, pcb_panel: () => hp, pcb_panelization_placement_error: () => up, pcb_placement_error: () => dp, pcb_plated_hole: () => Lu, pcb_port: () => zu, pcb_port_not_connected_error: () => sp, pcb_port_not_matched_error: () => rp, pcb_route_hint: () => uu, pcb_route_hints: () => pu, pcb_silkscreen_circle: () => bp, pcb_silkscreen_line: () => mp, pcb_silkscreen_oval: () => xp, pcb_silkscreen_path: () => gp, pcb_silkscreen_pill: () => vp, pcb_silkscreen_rect: () => yp, pcb_silkscreen_text: () => fp, pcb_smtpad: () => Wu, pcb_smtpad_pill: () => $u, pcb_solder_paste: () => qu, pcb_text: () => Ju, pcb_thermal_spoke: () => Qp, pcb_trace: () => tp, pcb_trace_error: () => op, pcb_trace_hint: () => pp, pcb_trace_missing_error: () => ip, pcb_trace_route_point: () => ep, pcb_trace_route_point_via: () => Ku, pcb_trace_route_point_wire: () => Qu, pcb_trace_warning: () => np, pcb_via: () => cp, pcb_via_clearance_error: () => am, pcb_via_trace_clearance_error: () => cm, point: () => oh, point3: () => rh, point_with_bulge: () => lu, port_arrangement: () => zd, position: () => ih, position3: () => sh, resistance: () => Xl, ring: () => hu, rotation: () => th, route_hint_point: () => mu, schematic_arc: () => Wd, schematic_box: () => Ad, schematic_circle: () => Xd, schematic_component: () => Bd, schematic_component_port_arrangement_by_sides: () => Ld, schematic_component_port_arrangement_by_size: () => Dd, schematic_debug_line: () => eu, schematic_debug_object: () => nu, schematic_debug_object_base: () => Qd, schematic_debug_point: () => tu, schematic_debug_rect: () => Kd, schematic_error: () => qd, schematic_group: () => ru, schematic_layout_error: () => Jd, schematic_line: () => $d, schematic_manual_edit_conflict_warning: () => iu, schematic_net_label: () => Zd, schematic_path: () => Od, schematic_pin_styles: () => kd, schematic_port: () => Ud, schematic_rect: () => Yd, schematic_sheet: () => cu, schematic_symbol: () => jd, schematic_table: () => su, schematic_table_cell: () => au, schematic_text: () => Gd, schematic_trace: () => Vd, schematic_voltage_probe: () => ou, simulation_ac_current_source: () => Mm, simulation_ac_voltage_source: () => Im, simulation_current_source: () => wm, simulation_dc_current_source: () => Pm, simulation_dc_voltage_source: () => vm, simulation_experiment: () => Tm, simulation_op_amp: () => km, simulation_switch: () => Em, simulation_transient_voltage_graph: () => Rm, simulation_unknown_experiment_error: () => Om, simulation_voltage_probe: () => Am, simulation_voltage_source: () => Sm, size: () => ah, source_ambiguous_port_reference: () => xd, source_board: () => bd, source_component_base: () => Th, source_component_internal_connection: () => gd, source_component_pins_underspecified_warning: () => Td, source_failed_to_create_component_error: () => od, source_group: () => _d, source_i2c_misconfigured_error: () => dd, source_interconnect: () => hd, source_invalid_component_property_error: () => id, source_manually_placed_via: () => Md, source_missing_manufacturer_part_number_warning: () => cd, source_missing_property_error: () => nd, source_net: () => yd, source_no_ground_pin_defined_warning: () => Nd, source_no_power_pin_defined_warning: () => wd, source_pcb_ground_plane: () => vd, source_pin_attributes: () => Fh, source_pin_missing_trace_warning: () => ad, source_pin_must_be_connected_error: () => Rd, source_port: () => md, source_project_metadata: () => td, source_property_ignored_warning: () => sd, source_simple_battery: () => $h, source_simple_capacitor: () => Rh, source_simple_chip: () => Lh, source_simple_connector: () => Gh, source_simple_crystal: () => Vh, source_simple_current_source: () => Bh, source_simple_diode: () => Ah, source_simple_fiducial: () => Oh, source_simple_ground: () => Dh, source_simple_inductor: () => Yh, source_simple_led: () => kh, source_simple_mosfet: () => Qh, source_simple_op_amp: () => Kh, source_simple_pin_header: () => Hh, source_simple_pinout: () => Uh, source_simple_potentiometer: () => Wh, source_simple_power_source: () => zh, source_simple_push_button: () => Xh, source_simple_resistor: () => Eh, source_simple_resonator: () => Zh, source_simple_switch: () => ed, source_simple_test_point: () => Jh, source_simple_transistor: () => qh, source_simple_voltage_probe: () => ld, source_simple_voltage_source: () => ud, source_trace: () => fd, source_trace_not_connected_error: () => rd, supplier_footprint_mismatch_warning: () => Up, supplier_name: () => Nh, time: () => Ql, timestamp: () => eh, unknown_error_finding_part: () => Ed, visible_layer: () => Pd, voltage: () => Hl, wave_shape: () => bm });
var aa;
var ca;
var la;
var ha = {};
a(ha, { BRAND: () => Wc, DIRTY: () => wa, EMPTY_PATH: () => va, INVALID: () => Ma, NEVER: () => Bl, OK: () => Na, ParseStatus: () => Pa, Schema: () => za, ZodAny: () => gc, ZodArray: () => bc, ZodBigInt: () => lc, ZodBoolean: () => hc, ZodBranded: () => Vc, ZodCatch: () => Yc, ZodDate: () => dc, ZodDefault: () => $c, ZodDiscriminatedUnion: () => Cc, ZodEffects: () => Bc, ZodEnum: () => Dc, ZodError: () => ga, ZodFirstPartyTypeKind: () => qc, ZodFunction: () => Ec, ZodIntersection: () => Mc, ZodIssueCode: () => pa, ZodLazy: () => Ac, ZodLiteral: () => Oc, ZodMap: () => Tc, ZodNaN: () => Xc, ZodNativeEnum: () => Lc, ZodNever: () => _c, ZodNull: () => mc, ZodNullable: () => jc, ZodNumber: () => cc, ZodObject: () => vc, ZodOptional: () => Fc, ZodParsedType: () => da, ZodPipeline: () => Hc, ZodPromise: () => zc, ZodReadonly: () => Gc, ZodRecord: () => Nc, ZodSchema: () => za, ZodSet: () => Rc, ZodString: () => sc, ZodSymbol: () => uc, ZodTransformer: () => Bc, ZodTuple: () => wc, ZodType: () => za, ZodUndefined: () => pc, ZodUnion: () => Ic, ZodUnknown: () => fc, ZodVoid: () => yc, addIssueToContext: () => Ia, any: () => ll, array: () => pl, bigint: () => ol, boolean: () => il, coerce: () => zl, custom: () => Zc, date: () => rl, datetimeRegex: () => nc, defaultErrorMap: () => fa, discriminatedUnion: () => _l, effect: () => Tl, enum: () => Ml, function: () => Sl, getErrorMap: () => ba, getParsedType: () => ua, instanceof: () => Kc, intersection: () => yl, isAborted: () => Ta, isAsync: () => Aa, isDirty: () => Ra, isValid: () => Ea, late: () => Qc, lazy: () => Cl, literal: () => Pl, makeIssue: () => xa, map: () => vl, nan: () => nl, nativeEnum: () => wl, never: () => dl, null: () => cl, nullable: () => El, number: () => tl, object: () => ml, objectUtil: () => la, oboolean: () => Ll, onumber: () => Dl, optional: () => Rl, ostring: () => kl, pipeline: () => Ol, preprocess: () => Al, promise: () => Nl, quotelessJson: () => ma, record: () => xl, set: () => Il, setErrorMap: () => ya, strictObject: () => gl, string: () => el, symbol: () => sl, transformer: () => Tl, tuple: () => bl, undefined: () => al, union: () => fl, unknown: () => hl, util: () => aa, void: () => ul }), (ca = aa || (aa = {})).assertEqual = (e4) => {}, ca.assertIs = function(e4) {}, ca.assertNever = function(e4) {
throw new Error;
}, ca.arrayToEnum = (e4) => {
const t2 = {};
for (const n2 of e4)
t2[n2] = n2;
return t2;
}, ca.getValidEnumValues = (e4) => {
const t2 = ca.objectKeys(e4).filter((t3) => typeof e4[e4[t3]] != "number"), n2 = {};
for (const o2 of t2)
n2[o2] = e4[o2];
return ca.objectValues(n2);
}, ca.objectValues = (e4) => ca.objectKeys(e4).map(function(t2) {
return e4[t2];
}), ca.objectKeys = typeof Object.keys == "function" ? (e4) => Object.keys(e4) : (e4) => {
const t2 = [];
for (const n2 in e4)
Object.prototype.hasOwnProperty.call(e4, n2) && t2.push(n2);
return t2;
}, ca.find = (e4, t2) => {
for (const n2 of e4)
if (t2(n2))
return n2;
}, ca.isInteger = typeof Number.isInteger == "function" ? (e4) => Number.isInteger(e4) : (e4) => typeof e4 == "number" && Number.isFinite(e4) && Math.floor(e4) === e4, ca.joinValues = function(e4, t2 = " | ") {
return e4.map((e5) => typeof e5 == "string" ? `'${e5}'` : e5).join(t2);
}, ca.jsonStringifyReplacer = (e4, t2) => typeof t2 == "bigint" ? t2.toString() : t2, (la || (la = {})).mergeShapes = (e4, t2) => ({ ...e4, ...t2 });
var da = aa.arrayToEnum(["string", "nan", "number", "integer", "float", "boolean", "date", "bigint", "symbol", "function", "undefined", "null", "array", "object", "unknown", "promise", "void", "never", "map", "set"]);
var ua = (e4) => {
switch (typeof e4) {
case "undefined":
return da.undefined;
case "string":
return da.string;
case "number":
return Number.isNaN(e4) ? da.nan : da.number;
case "boolean":
return da.boolean;
case "function":
return da.function;
case "bigint":
return da.bigint;
case "symbol":
return da.symbol;
case "object":
return Array.isArray(e4) ? da.array : e4 === null ? da.null : e4.then && typeof e4.then == "function" && e4.catch && typeof e4.catch == "function" ? da.promise : typeof Map != "undefined" && e4 instanceof Map ? da.map : typeof Set != "undefined" && e4 instanceof Set ? da.set : typeof Date != "undefined" && e4 instanceof Date ? da.date : da.object;
default:
return da.unknown;
}
};
var pa = aa.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"]);
var ma = (e4) => JSON.stringify(e4, null, 2).replace(/"([^"]+)":/g, "$1:");
var ga = class e4 extends Error {
get errors() {
return this.issues;
}
constructor(e5) {
super(), this.issues = [], this.addIssue = (e6) => {
this.issues = [...this.issues, e6];
}, this.addIssues = (e6 = []) => {
this.issues = [...this.issues, ...e6];
};
const t2 = new.target.prototype;
Object.setPrototypeOf ? Object.setPrototypeOf(this, t2) : this.__proto__ = t2, this.name = "ZodError", this.issues = e5;
}
format(e5) {
const t2 = e5 || function(e6) {
return e6.message;
}, n2 = { _errors: [] }, o2 = (e6) => {
for (const i2 of e6.issues)
if (i2.code === "invalid_union")
i2.unionErrors.map(o2);
else if (i2.code === "invalid_return_type")
o2(i2.returnTypeError);
else if (i2.code === "invalid_arguments")
o2(i2.argumentsError);
else if (i2.path.length === 0)
n2._errors.push(t2(i2));
else {
let e7 = n2, o3 = 0;
for (;o3 < i2.path.length; ) {
const n3 = i2.path[o3];
o3 === i2.path.length - 1 ? (e7[n3] = e7[n3] || { _errors: [] }, e7[n3]._errors.push(t2(i2))) : e7[n3] = e7[n3] || { _errors: [] }, e7 = e7[n3], o3++;
}
}
};
return o2(this), n2;
}
static assert(t2) {
if (!(t2 instanceof e4))
throw new Error(`Not a ZodError: ${t2}`);
}
toString() {
return this.message;
}
get message() {
return JSON.stringify(this.issues, aa.jsonStringifyReplacer, 2);
}
get isEmpty() {
return this.issues.length === 0;
}
flatten(e5 = (e6) => e6.message) {
const t2 = {}, n2 = [];
for (const o2 of this.issues)
if (o2.path.length > 0) {
const n3 = o2.path[0];
t2[n3] = t2[n3] || [], t2[n3].push(e5(o2));
} else
n2.push(e5(o2));
return { formErrors: n2, fieldErrors: t2 };
}
get formErrors() {
return this.flatten();
}
};
ga.create = (e5) => new ga(e5);
var fa = (e5, t2) => {
let n2;
switch (e5.code) {
case pa.invalid_type:
n2 = e5.received === da.undefined ? "Required" : `Expected ${e5.expected}, received ${e5.received}`;
break;
case pa.invalid_literal:
n2 = `Invalid literal value, expected ${JSON.stringify(e5.expected, aa.jsonStringifyReplacer)}`;
break;
case pa.unrecognized_keys:
n2 = `Unrecognized key(s) in object: ${aa.joinValues(e5.keys, ", ")}`;
break;
case pa.invalid_union:
n2 = "Invalid input";
break;
case pa.invalid_union_discriminator:
n2 = `Invalid discriminator value. Expected ${aa.joinValues(e5.options)}`;
break;
case pa.invalid_enum_value:
n2 = `Invalid enum value. Expected ${aa.joinValues(e5.options)}, received '${e5.received}'`;
break;
case pa.invalid_arguments:
n2 = "Invalid function arguments";
break;
case pa.invalid_return_type:
n2 = "Invalid function return type";
break;
case pa.invalid_date:
n2 = "Invalid date";
break;
case pa.invalid_string:
typeof e5.validation == "object" ? "includes" in e5.validation ? (n2 = `Invalid input: must include "${e5.validation.includes}"`, typeof e5.validation.position == "number" && (n2 = `${n2} at one or more positions greater than or equal to ${e5.validation.position}`)) : ("startsWith" in e5.validation) ? n2 = `Invalid input: must start with "${e5.validation.startsWith}"` : ("endsWith" in e5.validation) ? n2 = `Invalid input: must end with "${e5.validation.endsWith}"` : aa.assertNever(e5.validation) : n2 = e5.validation !== "regex" ? `Invalid ${e5.validation}` : "Invalid";
break;
case pa.too_small:
n2 = e5.type === "array" ? `Array must contain ${e5.exact ? "exactly" : e5.inclusive ? "at least" : "more than"} ${e5.minimum} element(s)` : e5.type === "string" ? `String must contain ${e5.exact ? "exactly" : e5.inclusive ? "at least" : "over"} ${e5.minimum} character(s)` : e5.type === "number" || e5.type === "bigint" ? `Number must be ${e5.exact ? "exactly equal to " : e5.inclusive ? "greater than or equal to " : "greater than "}${e5.minimum}` : e5.type === "date" ? `Date must be ${e5.exact ? "exactly equal to " : e5.inclusive ? "greater than or equal to " : "greater than "}${new Date(Number(e5.minimum))}` : "Invalid input";
break;
case pa.too_big:
n2 = e5.type === "array" ? `Array must contain ${e5.exact ? "exactly" : e5.inclusive ? "at most" : "less than"} ${e5.maximum} element(s)` : e5.type === "string" ? `String must contain ${e5.exact ? "exactly" : e5.inclusive ? "at most" : "under"} ${e5.maximum} character(s)` : e5.type === "number" ? `Number must be ${e5.exact ? "exactly" : e5.inclusive ? "less than or equal to" : "less than"} ${e5.maximum}` : e5.type === "bigint" ? `BigInt must be ${e5.exact ? "exactly" : e5.inclusive ? "less than or equal to" : "less than"} ${e5.maximum}` : e5.type === "date" ? `Date must be ${e5.exact ? "exactly" : e5.inclusive ? "smaller than or equal to" : "smaller than"} ${new Date(Number(e5.maximum))}` : "Invalid input";
break;
case pa.custom:
n2 = "Invalid input";
break;
case pa.invalid_intersection_types:
n2 = "Intersection results could not be merged";
break;
case pa.not_multiple_of:
n2 = `Number must be a multiple of ${e5.multipleOf}`;
break;
case pa.not_finite:
n2 = "Number must be finite";
break;
default:
n2 = t2.defaultError, aa.assertNever(e5);
}
return { message: n2 };
};
var _a = fa;
function ya(e5) {
_a = e5;
}
function ba() {
return _a;
}
var xa = (e5) => {
const { data: t2, path: n2, errorMaps: o2, issueData: i2 } = e5, r2 = [...n2, ...i2.path || []], s2 = { ...i2, path: r2 };
if (i2.message !== undefined)
return { ...i2, path: r2, message: i2.message };
let a2 = "";
const c2 = o2.filter((e6) => !!e6).slice().reverse();
for (const e6 of c2)
a2 = e6(s2, { data: t2, defaultError: a2 }).message;
return { ...i2, path: r2, message: a2 };
};
var va = [];
function Ia(e5, t2) {
const n2 = ba(), o2 = xa({ issueData: t2, data: e5.data, path: e5.path, errorMaps: [e5.common.contextualErrorMap, e5.schemaErrorMap, n2, n2 === fa ? undefined : fa].filter((e6) => !!e6) });
e5.common.issues.push(o2);
}
var Sa;
var Ca;
var Pa = class e5 {
constructor() {
this.value = "valid";
}
dirty() {
this.value === "valid" && (this.value = "dirty");
}
abort() {
this.value !== "aborted" && (this.value = "aborted");
}
static mergeArray(e6, t2) {
const n2 = [];
for (const o2 of t2) {
if (o2.status === "aborted")
return Ma;
o2.status === "dirty" && e6.dirty(), n2.push(o2.value);
}
return { status: e6.value, value: n2 };
}
static async mergeObjectAsync(t2, n2) {
const o2 = [];
for (const e6 of n2) {
const t3 = await e6.key, n3 = await e6.value;
o2.push({ key: t3, value: n3 });
}
return e5.mergeObjectSync(t2, o2);
}
static mergeObjectSync(e6, t2) {
const n2 = {};
for (const o2 of t2) {
const { key: t3, value: i2 } = o2;
if (t3.status === "aborted")
return Ma;
if (i2.status === "aborted")
return Ma;
t3.status === "dirty" && e6.dirty(), i2.status === "dirty" && e6.dirty(), t3.value === "__proto__" || i2.value === undefined && !o2.alwaysSet || (n2[t3.value] = i2.value);
}
return { status: e6.value, value: n2 };
}
};
var Ma = Object.freeze({ status: "aborted" });
var wa = (e6) => ({ status: "dirty", value: e6 });
var Na = (e6) => ({ status: "valid", value: e6 });
var Ta = (e6) => e6.status === "aborted";
var Ra = (e6) => e6.status === "dirty";
var Ea = (e6) => e6.status === "valid";
var Aa = (e6) => typeof Promise != "undefined" && e6 instanceof Promise;
(Ca = Sa || (Sa = {})).errToObj = (e6) => typeof e6 == "string" ? { message: e6 } : e6 || {}, Ca.toString = (e6) => typeof e6 == "string" ? e6 : e6?.message;
var Oa = class {
constructor(e6, t2, n2, o2) {
this._cachedPath = [], this.parent = e6, this.data = t2, this._path = n2, this._key = o2;
}
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;
}
};
var ka = (e6, t2) => {
if (Ea(t2))
return { success: true, data: t2.value };
if (!e6.common.issues.length)
throw new Error("Validation failed but no issues detected.");
return { success: false, get error() {
if (this._error)
return this._error;
const t3 = new ga(e6.common.issues);
return this._error = t3, this._error;
} };
};
function Da(e6) {
if (!e6)
return {};
const { errorMap: t2, invalid_type_error: n2, required_error: o2, description: i2 } = e6;
if (t2 && (n2 || o2))
throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
if (t2)
return { errorMap: t2, description: i2 };
return { errorMap: (t3, i3) => {
const { message: r2 } = e6;
return t3.code === "invalid_enum_value" ? { message: r2 ?? i3.defaultError } : i3.data === undefined ? { message: r2 ?? o2 ?? i3.defaultError } : t3.code !== "invalid_type" ? { message: i3.defaultError } : { message: r2 ?? n2 ?? i3.defaultError };
}, description: i2 };
}
var La;
var za = class {
get description() {
return this._def.description;
}
_getType(e6) {
return ua(e6.data);
}
_getOrReturnCtx(e6, t2) {
return t2 || { common: e6.parent.common, data: e6.data, parsedType: ua(e6.data), schemaErrorMap: this._def.errorMap, path: e6.path, parent: e6.parent };
}
_processInputParams(e6) {
return { status: new Pa, ctx: { common: e6.parent.common, data: e6.data, parsedType: ua(e6.data), schemaErrorMap: this._def.errorMap, path: e6.path, parent: e6.parent } };
}
_parseSync(e6) {
const t2 = this._parse(e6);
if (Aa(t2))
throw new Error("Synchronous parse encountered promise.");
return t2;
}
_parseAsync(e6) {
const t2 = this._parse(e6);
return Promise.resolve(t2);
}
parse(e6, t2) {
const n2 = this.safeParse(e6, t2);
if (n2.success)
return n2.data;
throw n2.error;
}
safeParse(e6, t2) {
const n2 = { common: { issues: [], async: t2?.async ?? false, contextualErrorMap: t2?.errorMap }, path: t2?.path || [], schemaErrorMap: this._def.errorMap, parent: null, data: e6, parsedType: ua(e6) }, o2 = this._parseSync({ data: e6, path: n2.path, parent: n2 });
return ka(n2, o2);
}
"~validate"(e6) {
const t2 = { common: { issues: [], async: !!this["~standard"].async }, path: [], schemaErrorMap: this._def.errorMap, parent: null, data: e6, parsedType: ua(e6) };
if (!this["~standard"].async)
try {
const n2 = this._parseSync({ data: e6, path: [], parent: t2 });
return Ea(n2) ? { value: n2.value } : { issues: t2.common.issues };
} catch (e7) {
e7?.message?.toLowerCase()?.includes("encountered") && (this["~standard"].async = true), t2.common = { issues: [], async: true };
}
return this._parseAsync({ data: e6, path: [], parent: t2 }).then((e7) => Ea(e7) ? { value: e7.value } : { issues: t2.common.issues });
}
async parseAsync(e6, t2) {
const n2 = await this.safeParseAsync(e6, t2);
if (n2.success)
return n2.data;
throw n2.error;
}
async safeParseAsync(e6, t2) {
const n2 = { common: { issues: [], contextualErrorMap: t2?.errorMap, async: true }, path: t2?.path || [], schemaErrorMap: this._def.errorMap, parent: null, data: e6, parsedType: ua(e6) }, o2 = this._parse({ data: e6, path: n2.path, parent: n2 }), i2 = await (Aa(o2) ? o2 : Promise.resolve(o2));
return ka(n2, i2);
}
refine(e6, t2) {
const n2 = (e7) => typeof t2 == "string" || t2 === undefined ? { message: t2 } : typeof t2 == "function" ? t2(e7) : t2;
return this._refinement((t3, o2) => {
const i2 = e6(t3), r2 = () => o2.addIssue({ code: pa.custom, ...n2(t3) });
return typeof Promise != "undefined" && i2 instanceof Promise ? i2.then((e7) => !!e7 || (r2(), false)) : !!i2 || (r2(), false);
});
}
refinement(e6, t2) {
return this._refinement((n2, o2) => !!e6(n2) || (o2.addIssue(typeof t2 == "function" ? t2(n2, o2) : t2), false));
}
_refinement(e6) {
return new Bc({ schema: this, typeName: qc.ZodEffects, effect: { type: "refinement", refinement: e6 } });
}
superRefine(e6) {
return this._refinement(e6);
}
constructor(e6) {
this.spa = this.safeParseAsync, this._def = e6, 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: (e7) => this["~validate"](e7) };
}
optional() {
return Fc.create(this, this._def);
}
nullable() {
return jc.create(this, this._def);
}
nullish() {
return this.nullable().optional();
}
array() {
return bc.create(this);
}
promise() {
return zc.create(this, this._def);
}
or(e6) {
return Ic.create([this, e6], this._def);
}
and(e6) {
return Mc.create(this, e6, this._def);
}
transform(e6) {
return new Bc({ ...Da(this._def), schema: this, typeName: qc.ZodEffects, effect: { type: "transform", transform: e6 } });
}
default(e6) {
const t2 = typeof e6 == "function" ? e6 : () => e6;
return new $c({ ...Da(this._def), innerType: this, defaultValue: t2, typeName: qc.ZodDefault });
}
brand() {
return new Vc({ typeName: qc.ZodBranded, type: this, ...Da(this._def) });
}
catch(e6) {
const t2 = typeof e6 == "function" ? e6 : () => e6;
return new Yc({ ...Da(this._def), innerType: this, catchValue: t2, typeName: qc.ZodCatch });
}
describe(e6) {
return new (this.constructor)({ ...this._def, description: e6 });
}
pipe(e6) {
return Hc.create(this, e6);
}
readonly() {
return Gc.create(this);
}
isOptional() {
return this.safeParse(undefined).success;
}
isNullable() {
return this.safeParse(null).success;
}
};
var Ba = /^c[^\s-]{8,}$/i;
var Fa = /^[0-9a-z]+$/;
var ja = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
var $a = /^[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;
var Ya = /^[a-z0-9_-]{21}$/i;
var Xa = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
var Wa = /^[-+]?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)?)??$/;
var Va = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
var Ha = /^(?:(?: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])$/;
var Ga = /^(?:(?: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])$/;
var Ua = /^(([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]))$/;
var Za = /^(([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])$/;
var qa = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
var Ja = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
var Qa = "((\\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])))";
var Ka = new RegExp(`^${Qa}$`);
function ec(e6) {
let t2 = "[0-5]\\d";
e6.precision ? t2 = `${t2}\\.\\d{${e6.precision}}` : e6.precision == null && (t2 = `${t2}(\\.\\d+)?`);
return `([01]\\d|2[0-3]):[0-5]\\d(:${t2})${e6.precision ? "+" : "?"}`;
}
function tc(e6) {
return new RegExp(`^${ec(e6)}$`);
}
function nc(e6) {
let t2 = `${Qa}T${ec(e6)}`;
const n2 = [];
return n2.push(e6.local ? "Z?" : "Z"), e6.offset && n2.push("([+-]\\d{2}:?\\d{2})"), t2 = `${t2}(${n2.join("|")})`, new RegExp(`^${t2}$`);
}
function oc(e6, t2) {
return !(t2 !== "v4" && t2 || !Ha.test(e6)) || !(t2 !== "v6" && t2 || !Ua.test(e6));
}
function ic(e6, t2) {
if (!Xa.test(e6))
return false;
try {
const [n2] = e6.split(".");
if (!n2)
return false;
const o2 = n2.replace(/-/g, "+").replace(/_/g, "/").padEnd(n2.length + (4 - n2.length % 4) % 4, "="), i2 = JSON.parse(atob(o2));
return typeof i2 == "object" && i2 !== null && ((!("typ" in i2) || i2?.typ === "JWT") && (!!i2.alg && (!t2 || i2.alg === t2)));
} catch {
return false;
}
}
function rc(e6, t2) {
return !(t2 !== "v4" && t2 || !Ga.test(e6)) || !(t2 !== "v6" && t2 || !Za.test(e6));
}
var sc = class e6 extends za {
_parse(e7) {
this._def.coerce && (e7.data = String(e7.data));
if (this._getType(e7) !== da.string) {
const t3 = this._getOrReturnCtx(e7);
return Ia(t3, { code: pa.invalid_type, expected: da.string, received: t3.parsedType }), Ma;
}
const t2 = new Pa;
let n2;
for (const o2 of this._def.checks)
if (o2.kind === "min")
e7.data.length < o2.value && (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.too_small, minimum: o2.value, type: "string", inclusive: true, exact: false, message: o2.message }), t2.dirty());
else if (o2.kind === "max")
e7.data.length > o2.value && (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.too_big, maximum: o2.value, type: "string", inclusive: true, exact: false, message: o2.message }), t2.dirty());
else if (o2.kind === "length") {
const i2 = e7.data.length > o2.value, r2 = e7.data.length < o2.value;
(i2 || r2) && (n2 = this._getOrReturnCtx(e7, n2), i2 ? Ia(n2, { code: pa.too_big, maximum: o2.value, type: "string", inclusive: true, exact: true, message: o2.message }) : r2 && Ia(n2, { code: pa.too_small, minimum: o2.value, type: "string", inclusive: true, exact: true, message: o2.message }), t2.dirty());
} else if (o2.kind === "email")
Va.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "email", code: pa.invalid_string, message: o2.message }), t2.dirty());
else if (o2.kind === "emoji")
La || (La = new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$", "u")), La.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "emoji", code: pa.invalid_string, message: o2.message }), t2.dirty());
else if (o2.kind === "uuid")
$a.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "uuid", code: pa.invalid_string, message: o2.message }), t2.dirty());
else if (o2.kind === "nanoid")
Ya.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "nanoid", code: pa.invalid_string, message: o2.message }), t2.dirty());
else if (o2.kind === "cuid")
Ba.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "cuid", code: pa.invalid_string, message: o2.message }), t2.dirty());
else if (o2.kind === "cuid2")
Fa.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "cuid2", code: pa.invalid_string, message: o2.message }), t2.dirty());
else if (o2.kind === "ulid")
ja.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "ulid", code: pa.invalid_string, message: o2.message }), t2.dirty());
else if (o2.kind === "url")
try {
new URL(e7.data);
} catch {
n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "url", code: pa.invalid_string, message: o2.message }), t2.dirty();
}
else if (o2.kind === "regex") {
o2.regex.lastIndex = 0;
o2.regex.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "regex", code: pa.invalid_string, message: o2.message }), t2.dirty());
} else if (o2.kind === "trim")
e7.data = e7.data.trim();
else if (o2.kind === "includes")
e7.data.includes(o2.value, o2.position) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.invalid_string, validation: { includes: o2.value, position: o2.position }, message: o2.message }), t2.dirty());
else if (o2.kind === "toLowerCase")
e7.data = e7.data.toLowerCase();
else if (o2.kind === "toUpperCase")
e7.data = e7.data.toUpperCase();
else if (o2.kind === "startsWith")
e7.data.startsWith(o2.value) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.invalid_string, validation: { startsWith: o2.value }, message: o2.message }), t2.dirty());
else if (o2.kind === "endsWith")
e7.data.endsWith(o2.value) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.invalid_string, validation: { endsWith: o2.value }, message: o2.message }), t2.dirty());
else if (o2.kind === "datetime") {
nc(o2).test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.invalid_string, validation: "datetime", message: o2.message }), t2.dirty());
} else if (o2.kind === "date") {
Ka.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.invalid_string, validation: "date", message: o2.message }), t2.dirty());
} else if (o2.kind === "time") {
tc(o2).test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { code: pa.invalid_string, validation: "time", message: o2.message }), t2.dirty());
} else
o2.kind === "duration" ? Wa.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "duration", code: pa.invalid_string, message: o2.message }), t2.dirty()) : o2.kind === "ip" ? oc(e7.data, o2.version) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "ip", code: pa.invalid_string, message: o2.message }), t2.dirty()) : o2.kind === "jwt" ? ic(e7.data, o2.alg) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "jwt", code: pa.invalid_string, message: o2.message }), t2.dirty()) : o2.kind === "cidr" ? rc(e7.data, o2.version) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "cidr", code: pa.invalid_string, message: o2.message }), t2.dirty()) : o2.kind === "base64" ? qa.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "base64", code: pa.invalid_string, message: o2.message }), t2.dirty()) : o2.kind === "base64url" ? Ja.test(e7.data) || (n2 = this._getOrReturnCtx(e7, n2), Ia(n2, { validation: "base64url", code: pa.invalid_string, message: o2.message }), t2.dirty()) : aa.assertNever(o2);
return { status: t2.value, value: e7.data };
}
_regex(e7, t2, n2) {
return this.refinement((t3) => e7.test(t3), { validation: t2, code: pa.invalid_string, ...Sa.errToObj(n2) });
}
_addCheck(t2) {
return new e6({ ...this._def, checks: [...this._def.checks, t2] });
}
email(e7) {
return this._addCheck({ kind: "email", ...Sa.errToObj(e7) });
}
url(e7) {
return this._addCheck({ kind: "url", ...Sa.errToObj(e7) });
}
emoji(e7) {
return this._addCheck({ kind: "emoji", ...Sa.errToObj(e7) });
}
uuid(e7) {
return this._addCheck({ kind: "uuid", ...Sa.errToObj(e7) });
}
nanoid(e7) {
return this._addCheck({ kind: "nanoid", ...Sa.errToObj(e7) });
}
cuid(e7) {
return this._addCheck({ kind: "cuid", ...Sa.errToObj(e7) });
}
cuid2(e7) {
return this._addCheck({ kind: "cuid2", ...Sa.errToObj(e7) });
}
ulid(e7) {
return this._addCheck({ kind: "ulid", ...Sa.errToObj(e7) });
}
base64(e7) {
return this._addCheck({ kind: "base64", ...Sa.errToObj(e7) });
}
base64url(e7) {
return this._addCheck({ kind: "base64url", ...Sa.errToObj(e7) });
}
jwt(e7) {
return this._addCheck({ kind: "jwt", ...Sa.errToObj(e7) });
}
ip(e7) {
return this._addCheck({ kind: "ip", ...Sa.errToObj(e7) });
}
cidr(e7) {
return this._addCheck({ kind: "cidr", ...Sa.errToObj(e7) });
}
datetime(e7) {
return typeof e7 == "string" ? this._addCheck({ kind: "datetime", precision: null, offset: false, local: false, message: e7 }) : this._addCheck({ kind: "datetime", precision: e7?.precision === undefined ? null : e7?.precision, offset: e7?.offset ?? false, local: e7?.local ?? false, ...Sa.errToObj(e7?.message) });
}
date(e7) {
return this._addCheck({ kind: "date", message: e7 });
}
time(e7) {
return typeof e7 == "string" ? this._addCheck({ kind: "time", precision: null, message: e7 }) : this._addCheck({ kind: "time", precision: e7?.precision === undefined ? null : e7?.precision, ...Sa.errToObj(e7?.message) });
}
duration(e7) {
return this._addCheck({ kind: "duration", ...Sa.errToObj(e7) });
}
regex(e7, t2) {
return this._addCheck({ kind: "regex", regex: e7, ...Sa.errToObj(t2) });
}
includes(e7, t2) {
return this._addCheck({ kind: "includes", value: e7, position: t2?.position, ...Sa.errToObj(t2?.message) });
}
startsWith(e7, t2) {
return this._addCheck({ kind: "startsWith", value: e7, ...Sa.errToObj(t2) });
}
endsWith(e7, t2) {
return this._addCheck({ kind: "endsWith", value: e7, ...Sa.errToObj(t2) });
}
min(e7, t2) {
return this._addCheck({ kind: "min", value: e7, ...Sa.errToObj(t2) });
}
max(e7, t2) {
return this._addCheck({ kind: "max", value: e7, ...Sa.errToObj(t2) });
}
length(e7, t2) {
return this._addCheck({ kind: "length", value: e7, ...Sa.errToObj(t2) });
}
nonempty(e7) {
return this.min(1, Sa.errToObj(e7));
}
trim() {
return new e6({ ...this._def, checks: [...this._def.checks, { kind: "trim" }] });
}
toLowerCase() {
return new e6({ ...this._def, checks: [...this._def.checks, { kind: "toLowerCase" }] });
}
toUpperCase() {
return new e6({ ...this._def, checks: [...this._def.checks, { kind: "toUpperCase" }] });
}
get isDatetime() {
return !!this._def.checks.find((e7) => e7.kind === "datetime");
}
get isDate() {
return !!this._def.checks.find((e7) => e7.kind === "date");
}
get isTime() {
return !!this._def.checks.find((e7) => e7.kind === "time");
}
get isDuration() {
return !!this._def.checks.find((e7) => e7.kind === "duration");
}
get isEmail() {
return !!this._def.checks.find((e7) => e7.kind === "email");
}
get isURL() {
return !!this._def.checks.find((e7) => e7.kind === "url");
}
get isEmoji() {
return !!this._def.checks.find((e7) => e7.kind === "emoji");
}
get isUUID() {
return !!this._def.checks.find((e7) => e7.kind === "uuid");
}
get isNANOID() {
return !!this._def.checks.find((e7) => e7.kind === "nanoid");
}
get isCUID() {
return !!this._def.checks.find((e7) => e7.kind === "cuid");
}
get isCUID2() {
return !!this._def.checks.find((e7) => e7.kind === "cuid2");
}
get isULID() {
return !!this._def.checks.find((e7) => e7.kind === "ulid");
}
get isIP() {
return !!this._def.checks.find((e7) => e7.kind === "ip");
}
get isCIDR() {
return !!this._def.checks.find((e7) => e7.kind === "cidr");
}
get isBase64() {
return !!this._def.checks.find((e7) => e7.kind === "base64");
}
get isBase64url() {
return !!this._def.checks.find((e7) => e7.kind === "base64url");
}
get minLength() {
let e7 = null;
for (const t2 of this._def.checks)
t2.kind === "min" && (e7 === null || t2.value > e7) && (e7 = t2.value);
return e7;
}
get maxLength() {
let e7 = null;
for (const t2 of this._def.checks)
t2.kind === "max" && (e7 === null || t2.value < e7) && (e7 = t2.value);
return e7;
}
};
function ac(e7, t2) {
const n2 = (e7.toString().split(".")[1] || "").length, o2 = (t2.toString().split(".")[1] || "").length, i2 = n2 > o2 ? n2 : o2;
return Number.parseInt(e7.toFixed(i2).replace(".", "")) % Number.parseInt(t2.toFixed(i2).replace(".", "")) / 10 ** i2;
}
sc.create = (e7) => new sc({ checks: [], typeName: qc.ZodString, coerce: e7?.coerce ?? false, ...Da(e7) });
var cc = class e7 extends za {
constructor() {
super(...arguments), this.min = this.gte, this.max = this.lte, this.step = this.multipleOf;
}
_parse(e8) {
this._def.coerce && (e8.data = Number(e8.data));
if (this._getType(e8) !== da.number) {
const t3 = this._getOrReturnCtx(e8);
return Ia(t3, { code: pa.invalid_type, expected: da.number, received: t3.parsedType }), Ma;
}
let t2;
const n2 = new Pa;
for (const o2 of this._def.checks)
if (o2.kind === "int")
aa.isInteger(e8.data) || (t2 = this._getOrReturnCtx(e8, t2), Ia(t2, { code: pa.invalid_type, expected: "integer", received: "float", message: o2.message }), n2.dirty());
else if (o2.kind === "min") {
(o2.inclusive ? e8.data < o2.value : e8.data <= o2.value) && (t2 = this._getOrReturnCtx(e8, t2), Ia(t2, { code: pa.too_small, minimum: o2.value, type: "number", inclusive: o2.inclusive, exact: false, message: o2.message }), n2.dirty());
} else if (o2.kind === "max") {
(o2.inclusive ? e8.data > o2.value : e8.data >= o2.value) && (t2 = this._getOrReturnCtx(e8, t2), Ia(t2, { code: pa.too_big, maximum: o2.value, type: "number", inclusive: o2.inclusive, exact: false, message: o2.message }), n2.dirty());
} else
o2.kind === "multipleOf" ? ac(e8.data, o2.value) !== 0 && (t2 = this._getOrReturnCtx(e8, t2), Ia(t2, { code: pa.not_multiple_of, multipleOf: o2.value, message: o2.message }), n2.dirty()) : o2.kind === "finite" ? Number.isFinite(e8.data) || (t2 = this._getOrReturnCtx(e8, t2), Ia(t2, { code: pa.not_finite, message: o2.message }), n2.dirty()) : aa.assertNever(o2);
return { status: n2.value, value: e8.data };
}
gte(e8, t2) {
return this.setLimit("min", e8, true, Sa.toString(t2));
}
gt(e8, t2) {
return this.setLimit("min", e8, false, Sa.toString(t2));
}
lte(e8, t2) {
return this.setLimit("max", e8, true, Sa.toString(t2));
}
lt(e8, t2) {
return this.setLimit("max", e8, false, Sa.toString(t2));
}
setLimit(t2, n2, o2, i2) {
return new e7({ ...this._def, checks: [...this._def.checks, { kind: t2, value: n2, inclusive: o2, message: Sa.toString(i2) }] });
}
_addCheck(t2) {
return new e7({ ...this._def, checks: [...this._def.checks, t2] });
}
int(e8) {
return this._addCheck({ kind: "int", message: Sa.toString(e8) });
}
positive(e8) {
return this._addCheck({ kind: "min", value: 0, inclusive: false, message: Sa.toString(e8) });
}
negative(e8) {
return this._addCheck({ kind: "max", value: 0, inclusive: false, message: Sa.toString(e8) });
}
nonpositive(e8) {
return this._addCheck({ kind: "max", value: 0, inclusive: true, message: Sa.toString(e8) });
}
nonnegative(e8) {
return this._addCheck({ kind: "min", value: 0, inclusive: true, message: Sa.toString(e8) });
}
multipleOf(e8, t2) {
return this._addCheck({ kind: "multipleOf", value: e8, message: Sa.toString(t2) });
}
finite(e8) {
return this._addCheck({ kind: "finite", message: Sa.toString(e8) });
}
safe(e8) {
return this._addCheck({ kind: "min", inclusive: true, value: Number.MIN_SAFE_INTEGER, message: Sa.toString(e8) })._addCheck({ kind: "max", inclusive: true, value: Number.MAX_SAFE_INTEGER, message: Sa.toString(e8) });
}
get minValue() {
let e8 = null;
for (const t2 of this._def.checks)
t2.kind === "min" && (e8 === null || t2.value > e8) && (e8 = t2.value);
return e8;
}
get maxValue() {
let e8 = null;
for (const t2 of this._def.checks)
t2.kind === "max" && (e8 === null || t2.value < e8) && (e8 = t2.value);
return e8;
}
get isInt() {
return !!this._def.checks.find((e8) => e8.kind === "int" || e8.kind === "multipleOf" && aa.isInteger(e8.value));
}
get isFinite() {
let e8 = null, t2 = null;
for (const n2 of this._def.checks) {
if (n2.kind === "finite" || n2.kind === "int" || n2.kind === "multipleOf")
return true;
n2.kind === "min" ? (t2 === null || n2.value > t2) && (t2 = n2.value) : n2.kind === "max" && (e8 === null || n2.value < e8) && (e8 = n2.value);
}
return Number.isFinite(t2) && Number.isFinite(e8);
}
};
cc.create = (e8) => new cc({ checks: [], typeName: qc.ZodNumber, coerce: e8?.coerce || false, ...Da(e8) });
var lc = class e8 extends za {
constructor() {
super(...arguments), this.min = this.gte, this.max = this.lte;
}
_parse(e9) {
if (this._def.coerce)
try {
e9.data = BigInt(e9.data);
} catch {
return this._getInvalidInput(e9);
}
if (this._getType(e9) !== da.bigint)
return this._getInvalidInput(e9);
let t2;
const n2 = new Pa;
for (const o2 of this._def.checks)
if (o2.kind === "min") {
(o2.inclusive ? e9.data < o2.value : e9.data <= o2.value) && (t2 = this._getOrReturnCtx(e9, t2), Ia(t2, { code: pa.too_small, type: "bigint", minimum: o2.value, inclusive: o2.inclusive, message: o2.message }), n2.dirty());
} else if (o2.kind === "max") {
(o2.inclusive ? e9.data > o2.value : e9.data >= o2.value) && (t2 = this._getOrReturnCtx(e9, t2), Ia(t2, { code: pa.too_big, type: "bigint", maximum: o2.value, inclusive: o2.inclusive, message: o2.message }), n2.dirty());
} else
o2.kind === "multipleOf" ? e9.data % o2.value !== BigInt(0) && (t2 = this._getOrReturnCtx(e9, t2), Ia(t2, { code: pa.not_multiple_of, multipleOf: o2.value, message: o2.message }), n2.dirty()) : aa.assertNever(o2);
return { status: n2.value, value: e9.data };
}
_getInvalidInput(e9) {
const t2 = this._getOrReturnCtx(e9);
return Ia(t2, { code: pa.invalid_type, expected: da.bigint, received: t2.parsedType }), Ma;
}
gte(e9, t2) {
return this.setLimit("min", e9, true, Sa.toString(t2));
}
gt(e9, t2) {
return this.setLimit("min", e9, false, Sa.toString(t2));
}
lte(e9, t2) {
return this.setLimit("max", e9, true, Sa.toString(t2));
}
lt(e9, t2) {
return this.setLimit("max", e9, false, Sa.toString(t2));
}
setLimit(t2, n2, o2, i2) {
return new e8({ ...this._def, checks: [...this._def.checks, { kind: t2, value: n2, inclusive: o2, message: Sa.toString(i2) }] });
}
_addCheck(t2) {
return new e8({ ...this._def, checks: [...this._def.checks, t2] });
}
positive(e9) {
return this._addCheck({ kind: "min", value: BigInt(0), inclusive: false, message: Sa.toString(e9) });
}
negative(e9) {
return this._addCheck({ kind: "max", value: BigInt(0), inclusive: false, message: Sa.toString(e9) });
}
nonpositive(e9) {
return this._addCheck({ kind: "max", value: BigInt(0), inclusive: true, message: Sa.toString(e9) });
}
nonnegative(e9) {
return this._addCheck({ kind: "min", value: BigInt(0), inclusive: true, message: Sa.toString(e9) });
}
multipleOf(e9, t2) {
return this._addCheck({ kind: "multipleOf", value: e9, message: Sa.toString(t2) });
}
get minValue() {
let e9 = null;
for (const t2 of this._def.checks)
t2.kind === "min" && (e9 === null || t2.value > e9) && (e9 = t2.value);
return e9;
}
get maxValue() {
let e9 = null;
for (const t2 of this._def.checks)
t2.kind === "max" && (e9 === null || t2.value < e9) && (e9 = t2.value);
return e9;
}
};
lc.create = (e9) => new lc({ checks: [], typeName: qc.ZodBigInt, coerce: e9?.coerce ?? false, ...Da(e9) });
var hc = class extends za {
_parse(e9) {
this._def.coerce && (e9.data = Boolean(e9.data));
if (this._getType(e9) !== da.boolean) {
const t2 = this._getOrReturnCtx(e9);
return Ia(t2, { code: pa.invalid_type, expected: da.boolean, received: t2.parsedType }), Ma;
}
return Na(e9.data);
}
};
hc.create = (e9) => new hc({ typeName: qc.ZodBoolean, coerce: e9?.coerce || false, ...Da(e9) });
var dc = class e9 extends za {
_parse(e10) {
this._def.coerce && (e10.data = new Date(e10.data));
if (this._getType(e10) !== da.date) {
const t3 = this._getOrReturnCtx(e10);
return Ia(t3, { code: pa.invalid_type, expected: da.date, received: t3.parsedType }), Ma;
}
if (Number.isNaN(e10.data.getTime())) {
return Ia(this._getOrReturnCtx(e10), { code: pa.invalid_date }), Ma;
}
const t2 = new Pa;
let n2;
for (const o2 of this._def.checks)
o2.kind === "min" ? e10.data.getTime() < o2.value && (n2 = this._getOrReturnCtx(e10, n2), Ia(n2, { code: pa.too_small, message: o2.message, inclusive: true, exact: false, minimum: o2.value, type: "date" }), t2.dirty()) : o2.kind === "max" ? e10.data.getTime() > o2.value && (n2 = this._getOrReturnCtx(e10, n2), Ia(n2, { code: pa.too_big, message: o2.message, inclusive: true, exact: false, maximum: o2.value, type: "date" }), t2.dirty()) : aa.assertNever(o2);
return { status: t2.value, value: new Date(e10.data.getTime()) };
}
_addCheck(t2) {
return new e9({ ...this._def, checks: [...this._def.checks, t2] });
}
min(e10, t2) {
return this._addCheck({ kind: "min", value: e10.getTime(), message: Sa.toString(t2) });
}
max(e10, t2) {
return this._addCheck({ kind: "max", value: e10.getTime(), message: Sa.toString(t2) });
}
get minDate() {
let e10 = null;
for (const t2 of this._def.checks)
t2.kind === "min" && (e10 === null || t2.value > e10) && (e10 = t2.value);
return e10 != null ? new Date(e10) : null;
}
get maxDate() {
let e10 = null;
for (const t2 of this._def.checks)
t2.kind === "max" && (e10 === null || t2.value < e10) && (e10 = t2.value);
return e10 != null ? new Date(e10) : null;
}
};
dc.create = (e10) => new dc({ checks: [], coerce: e10?.coerce || false, typeName: qc.ZodDate, ...Da(e10) });
var uc = class extends za {
_parse(e10) {
if (this._getType(e10) !== da.symbol) {
const t2 = this._getOrReturnCtx(e10);
return Ia(t2, { code: pa.invalid_type, expected: da.symbol, received: t2.parsedType }), Ma;
}
return Na(e10.data);
}
};
uc.create = (e10) => new uc({ typeName: qc.ZodSymbol, ...Da(e10) });
var pc = class extends za {
_parse(e10) {
if (this._getType(e10) !== da.undefined) {
const t2 = this._getOrReturnCtx(e10);
return Ia(t2, { code: pa.invalid_type, expected: da.undefined, received: t2.parsedType }), Ma;
}
return Na(e10.data);
}
};
pc.create = (e10) => new pc({ typeName: qc.ZodUndefined, ...Da(e10) });
var mc = class extends za {
_parse(e10) {
if (this._getType(e10) !== da.null) {
const t2 = this._getOrReturnCtx(e10);
return Ia(t2, { code: pa.invalid_type, expected: da.null, received: t2.parsedType }), Ma;
}
return Na(e10.data);
}
};
mc.create = (e10) => new mc({ typeName: qc.ZodNull, ...Da(e10) });
var gc = class extends za {
constructor() {
super(...arguments), this._any = true;
}
_parse(e10) {
return Na(e10.data);
}
};
gc.create = (e10) => new gc({ typeName: qc.ZodAny, ...Da(e10) });
var fc = class extends za {
constructor() {
super(...arguments), this._unknown = true;
}
_parse(e10) {
return Na(e10.data);
}
};
fc.create = (e10) => new fc({ typeName: qc.ZodUnknown, ...Da(e10) });
var _c = class extends za {
_parse(e10) {
const t2 = this._getOrReturnCtx(e10);
return Ia(t2, { code: pa.invalid_type, expected: da.never, received: t2.parsedType }), Ma;
}
};
_c.create = (e10) => new _c({ typeName: qc.ZodNever, ...Da(e10) });
var yc = class extends za {
_parse(e10) {
if (this._getType(e10) !== da.undefined) {
const t2 = this._getOrReturnCtx(e10);
return Ia(t2, { code: pa.invalid_type, expected: da.void, received: t2.parsedType }), Ma;
}
return Na(e10.data);
}
};
yc.create = (e10) => new yc({ typeName: qc.ZodVoid, ...Da(e10) });
var bc = class e10 extends za {
_parse(e11) {
const { ctx: t2, status: n2 } = this._processInputParams(e11), o2 = this._def;
if (t2.parsedType !== da.array)
return Ia(t2, { code: pa.invalid_type, expected: da.array, received: t2.parsedType }), Ma;
if (o2.exactLength !== null) {
const e12 = t2.data.length > o2.exactLength.value, i3 = t2.data.length < o2.exactLength.value;
(e12 || i3) && (Ia(t2, { code: e12 ? pa.too_big : pa.too_small, minimum: i3 ? o2.exactLength.value : undefined, maximum: e12 ? o2.exactLength.value : undefined, type: "array", inclusive: true, exact: true, message: o2.exactLength.message }), n2.dirty());
}
if (o2.minLength !== null && t2.data.length < o2.minLength.value && (Ia(t2, { code: pa.too_small, minimum: o2.minLength.value, type: "array", inclusive: true, exact: false, message: o2.minLength.message }), n2.dirty()), o2.maxLength !== null && t2.data.length > o2.maxLength.value && (Ia(t2, { code: pa.too_big, maximum: o2.maxLength.value, type: "array", inclusive: true, exact: false, message: o2.maxLength.message }), n2.dirty()), t2.common.async)
return Promise.all([...t2.data].map((e12, n3) => o2.type._parseAsync(new Oa(t2, e12, t2.path, n3)))).then((e12) => Pa.mergeArray(n2, e12));
const i2 = [...t2.data].map((e12, n3) => o2.type._parseSync(new Oa(t2, e12, t2.path, n3)));
return Pa.mergeArray(n2, i2);
}
get element() {
return this._def.type;
}
min(t2, n2) {
return new e10({ ...this._def, minLength: { value: t2, message: Sa.toString(n2) } });
}
max(t2, n2) {
return new e10({ ...this._def, maxLength: { value: t2, message: Sa.toString(n2) } });
}
length(t2, n2) {
return new e10({ ...this._def, exactLength: { value: t2, message: Sa.toString(n2) } });
}
nonempty(e11) {
return this.min(1, e11);
}
};
function xc(e11) {
if (e11 instanceof vc) {
const t2 = {};
for (const n2 in e11.shape) {
const o2 = e11.shape[n2];
t2[n2] = Fc.create(xc(o2));
}
return new vc({ ...e11._def, shape: () => t2 });
}
return e11 instanceof bc ? new bc({ ...e11._def, type: xc(e11.element) }) : e11 instanceof Fc ? Fc.create(xc(e11.unwrap())) : e11 instanceof jc ? jc.create(xc(e11.unwrap())) : e11 instanceof wc ? wc.create(e11.items.map((e12) => xc(e12))) : e11;
}
bc.create = (e11, t2) => new bc({ type: e11, minLength: null, maxLength: null, exactLength: null, typeName: qc.ZodArray, ...Da(t2) });
var vc = class e11 extends za {
constructor() {
super(...arguments), this._cached = null, this.nonstrict = this.passthrough, this.augment = this.extend;
}
_getCached() {
if (this._cached !== null)
return this._cached;
const e12 = this._def.shape(), t2 = aa.objectKeys(e12);
return this._cached = { shape: e12, keys: t2 }, this._cached;
}
_parse(e12) {
if (this._getType(e12) !== da.object) {
const t3 = this._getOrReturnCtx(e12);
return Ia(t3, { code: pa.invalid_type, expected: da.object, received: t3.parsedType }), Ma;
}
const { status: t2, ctx: n2 } = this._processInputParams(e12), { shape: o2, keys: i2 } = this._getCached(), r2 = [];
if (!(this._def.catchall instanceof _c && this._def.unknownKeys === "strip"))
for (const e13 in n2.data)
i2.includes(e13) || r2.push(e13);
const s2 = [];
for (const e13 of i2) {
const t3 = o2[e13], i3 = n2.data[e13];
s2.push({ key: { status: "valid", value: e13 }, value: t3._parse(new Oa(n2, i3, n2.path, e13)), alwaysSet: e13 in n2.data });
}
if (this._def.catchall instanceof _c) {
const e13 = this._def.unknownKeys;
if (e13 === "passthrough")
for (const e14 of r2)
s2.push({ key: { status: "valid", value: e14 }, value: { status: "valid", value: n2.data[e14] } });
else if (e13 === "strict")
r2.length > 0 && (Ia(n2, { code: pa.unrecognized_keys, keys: r2 }), t2.dirty());
else if (e13 !== "strip")
throw new Error("Internal ZodObject error: invalid unknownKeys value.");
} else {
const e13 = this._def.catchall;
for (const t3 of r2) {
const o3 = n2.data[t3];
s2.push({ key: { status: "valid", value: t3 }, value: e13._parse(new Oa(n2, o3, n2.path, t3)), alwaysSet: t3 in n2.data });
}
}
return n2.common.async ? Promise.resolve().then(async () => {
const e13 = [];
for (const t3 of s2) {
const n3 = await t3.key, o3 = await t3.value;
e13.push({ key: n3, value: o3, alwaysSet: t3.alwaysSet });
}
return e13;
}).then((e13) => Pa.mergeObjectSync(t2, e13)) : Pa.mergeObjectSync(t2, s2);
}
get shape() {
return this._def.shape();
}
strict(t2) {
return Sa.errToObj, new e11({ ...this._def, unknownKeys: "strict", ...t2 !== undefined ? { errorMap: (e12, n2) => {
const o2 = this._def.errorMap?.(e12, n2).message ?? n2.defaultError;
return e12.code === "unrecognized_keys" ? { message: Sa.errToObj(t2).message ?? o2 } : { message: o2 };
} } : {} });
}
strip() {
return new e11({ ...this._def, unknownKeys: "strip" });
}
passthrough() {
return new e11({ ...this._def, unknownKeys: "passthrough" });
}
extend(t2) {
return new e11({ ...this._def, shape: () => ({ ...this._def.shape(), ...t2 }) });
}
merge(t2) {
return new e11({ unknownKeys: t2._def.unknownKeys, catchall: t2._def.catchall, shape: () => ({ ...this._def.shape(), ...t2._def.shape() }), typeName: qc.ZodObject });
}
setKey(e12, t2) {
return this.augment({ [e12]: t2 });
}
catchall(t2) {
return new e11({ ...this._def, catchall: t2 });
}
pick(t2) {
const n2 = {};
for (const e12 of aa.objectKeys(t2))
t2[e12] && this.shape[e12] && (n2[e12] = this.shape[e12]);
return new e11({ ...this._def, shape: () => n2 });
}
omit(t2) {
const n2 = {};
for (const e12 of aa.objectKeys(this.shape))
t2[e12] || (n2[e12] = this.shape[e12]);
return new e11({ ...this._def, shape: () => n2 });
}
deepPartial() {
return xc(this);
}
partial(t2) {
const n2 = {};
for (const e12 of aa.objectKeys(this.shape)) {
const o2 = this.shape[e12];
t2 && !t2[e12] ? n2[e12] = o2 : n2[e12] = o2.optional();
}
return new e11({ ...this._def, shape: () => n2 });
}
required(t2) {
const n2 = {};
for (const e12 of aa.objectKeys(this.shape))
if (t2 && !t2[e12])
n2[e12] = this.shape[e12];
else {
let t3 = this.shape[e12];
for (;t3 instanceof Fc; )
t3 = t3._def.innerType;
n2[e12] = t3;
}
return new e11({ ...this._def, shape: () => n2 });
}
keyof() {
return kc(aa.objectKeys(this.shape));
}
};
vc.create = (e12, t2) => new vc({ shape: () => e12, unknownKeys: "strip", catchall: _c.create(), typeName: qc.ZodObject, ...Da(t2) }), vc.strictCreate = (e12, t2) => new vc({ shape: () => e12, unknownKeys: "strict", catchall: _c.create(), typeName: qc.ZodObject, ...Da(t2) }), vc.lazycreate = (e12, t2) => new vc({ shape: e12, unknownKeys: "strip", catchall: _c.create(), typeName: qc.ZodObject, ...Da(t2) });
var Ic = class extends za {
_parse(e12) {
const { ctx: t2 } = this._processInputParams(e12), n2 = this._def.options;
if (t2.common.async)
return Promise.all(n2.map(async (e13) => {
const n3 = { ...t2, common: { ...t2.common, issues: [] }, parent: null };
return { result: await e13._parseAsync({ data: t2.data, path: t2.path, parent: n3 }), ctx: n3 };
})).then(function(e13) {
for (const t3 of e13)
if (t3.result.status === "valid")
return t3.result;
for (const n4 of e13)
if (n4.result.status === "dirty")
return t2.common.issues.push(...n4.ctx.common.issues), n4.result;
const n3 = e13.map((e14) => new ga(e14.ctx.common.issues));
return Ia(t2, { code: pa.invalid_union, unionErrors: n3 }), Ma;
});
{
let e13;
const o2 = [];
for (const i3 of n2) {
const n3 = { ...t2, common: { ...t2.common, issues: [] }, parent: null }, r2 = i3._parseSync({ data: t2.data, path: t2.path, parent: n3 });
if (r2.status === "valid")
return r2;
r2.status !== "dirty" || e13 || (e13 = { result: r2, ctx: n3 }), n3.common.issues.length && o2.push(n3.common.issues);
}
if (e13)
return t2.common.issues.push(...e13.ctx.common.issues), e13.result;
const i2 = o2.map((e14) => new ga(e14));
return Ia(t2, { code: pa.invalid_union, unionErrors: i2 }), Ma;
}
}
get options() {
return this._def.options;
}
};
Ic.create = (e12, t2) => new Ic({ options: e12, typeName: qc.ZodUnion, ...Da(t2) });
var Sc = (e12) => e12 instanceof Ac ? Sc(e12.schema) : e12 instanceof Bc ? Sc(e12.innerType()) : e12 instanceof Oc ? [e12.value] : e12 instanceof Dc ? e12.options : e12 instanceof Lc ? aa.objectValues(e12.enum) : e12 instanceof $c ? Sc(e12._def.innerType) : e12 instanceof pc ? [undefined] : e12 instanceof mc ? [null] : e12 instanceof Fc ? [undefined, ...Sc(e12.unwrap())] : e12 instanceof jc ? [null, ...Sc(e12.unwrap())] : e12 instanceof Vc || e12 instanceof Gc ? Sc(e12.unwrap()) : e12 instanceof Yc ? Sc(e12._def.innerType) : [];
var Cc = class e12 extends za {
_parse(e13) {
const { ctx: t2 } = this._processInputParams(e13);
if (t2.parsedType !== da.object)
return Ia(t2, { code: pa.invalid_type, expected: da.object, received: t2.parsedType }), Ma;
const n2 = this.discriminator, o2 = t2.data[n2], i2 = this.optionsMap.get(o2);
return i2 ? t2.common.async ? i2._parseAsync({ data: t2.data, path: t2.path, parent: t2 }) : i2._parseSync({ data: t2.data, path: t2.path, parent: t2 }) : (Ia(t2, { code: pa.invalid_union_discriminator, options: Array.from(this.optionsMap.keys()), path: [n2] }), Ma);
}
get discriminator() {
return this._def.discriminator;
}
get options() {
return this._def.options;
}
get optionsMap() {
return this._def.optionsMap;
}
static create(t2, n2, o2) {
const i2 = new Map;
for (const e13 of n2) {
const n3 = Sc(e13.shape[t2]);
if (!n3.length)
throw new Error(`A discriminator value for key \`${t2}\` could not be extracted from all schema options`);
for (const o3 of n3) {
if (i2.has(o3))
throw new Error(`Discriminator property ${String(t2)} has duplicate value ${String(o3)}`);
i2.set(o3, e13);
}
}
return new e12({ typeName: qc.ZodDiscriminatedUnion, discriminator: t2, options: n2, optionsMap: i2, ...Da(o2) });
}
};
function Pc(e13, t2) {
const n2 = ua(e13), o2 = ua(t2);
if (e13 === t2)
return { valid: true, data: e13 };
if (n2 === da.object && o2 === da.object) {
const n3 = aa.objectKeys(t2), o3 = aa.objectKeys(e13).filter((e14) => n3.indexOf(e14) !== -1), i2 = { ...e13, ...t2 };
for (const n4 of o3) {
const o4 = Pc(e13[n4], t2[n4]);
if (!o4.valid)
return { valid: false };
i2[n4] = o4.data;
}
return { valid: true, data: i2 };
}
if (n2 === da.array && o2 === da.array) {
if (e13.length !== t2.length)
return { valid: false };
const n3 = [];
for (let o3 = 0;o3 < e13.length; o3++) {
const i2 = Pc(e13[o3], t2[o3]);
if (!i2.valid)
return { valid: false };
n3.push(i2.data);
}
return { valid: true, data: n3 };
}
return n2 === da.date && o2 === da.date && +e13 === +t2 ? { valid: true, data: e13 } : { valid: false };
}
var Mc = class extends za {
_parse(e13) {
const { status: t2, ctx: n2 } = this._processInputParams(e13), o2 = (e14, o3) => {
if (Ta(e14) || Ta(o3))
return Ma;
const i2 = Pc(e14.value, o3.value);
return i2.valid ? ((Ra(e14) || Ra(o3)) && t2.dirty(), { status: t2.value, value: i2.data }) : (Ia(n2, { code: pa.invalid_intersection_types }), Ma);
};
return n2.common.async ? Promise.all([this._def.left._parseAsync({ data: n2.data, path: n2.path, parent: n2 }), this._def.right._parseAsync({ data: n2.data, path: n2.path, parent: n2 })]).then(([e14, t3]) => o2(e14, t3)) : o2(this._def.left._parseSync({ data: n2.data, path: n2.path, parent: n2 }), this._def.right._parseSync({ data: n2.data, path: n2.path, parent: n2 }));
}
};
Mc.create = (e13, t2, n2) => new Mc({ left: e13, right: t2, typeName: qc.ZodIntersection, ...Da(n2) });
var wc = class e13 extends za {
_parse(e14) {
const { status: t2, ctx: n2 } = this._processInputParams(e14);
if (n2.parsedType !== da.array)
return Ia(n2, { code: pa.invalid_type, expected: da.array, received: n2.parsedType }), Ma;
if (n2.data.length < this._def.items.length)
return Ia(n2, { code: pa.too_small, minimum: this._def.items.length, inclusive: true, exact: false, type: "array" }), Ma;
!this._def.rest && n2.data.length > this._def.items.length && (Ia(n2, { code: pa.too_big, maximum: this._def.items.length, inclusive: true, exact: false, type: "array" }), t2.dirty());
const o2 = [...n2.data].map((e15, t3) => {
const o3 = this._def.items[t3] || this._def.rest;
return o3 ? o3._parse(new Oa(n2, e15, n2.path, t3)) : null;
}).filter((e15) => !!e15);
return n2.common.async ? Promise.all(o2).then((e15) => Pa.mergeArray(t2, e15)) : Pa.mergeArray(t2, o2);
}
get items() {
return this._def.items;
}
rest(t2) {
return new e13({ ...this._def, rest: t2 });
}
};
wc.create = (e14, t2) => {
if (!Array.isArray(e14))
throw new Error("You must pass an array of schemas to z.tuple([ ... ])");
return new wc({ items: e14, typeName: qc.ZodTuple, rest: null, ...Da(t2) });
};
var Nc = class e14 extends za {
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_parse(e15) {
const { status: t2, ctx: n2 } = this._processInputParams(e15);
if (n2.parsedType !== da.object)
return Ia(n2, { code: pa.invalid_type, expected: da.object, received: n2.parsedType }), Ma;
const o2 = [], i2 = this._def.keyType, r2 = this._def.valueType;
for (const e16 in n2.data)
o2.push({ key: i2._parse(new Oa(n2, e16, n2.path, e16)), value: r2._parse(new Oa(n2, n2.data[e16], n2.path, e16)), alwaysSet: e16 in n2.data });
return n2.common.async ? Pa.mergeObjectAsync(t2, o2) : Pa.mergeObjectSync(t2, o2);
}
get element() {
return this._def.valueType;
}
static create(t2, n2, o2) {
return new e14(n2 instanceof za ? { keyType: t2, valueType: n2, typeName: qc.ZodRecord, ...Da(o2) } : { keyType: sc.create(), valueType: t2, typeName: qc.ZodRecord, ...Da(n2) });
}
};
var Tc = class extends za {
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_parse(e15) {
const { status: t2, ctx: n2 } = this._processInputParams(e15);
if (n2.parsedType !== da.map)
return Ia(n2, { code: pa.invalid_type, expected: da.map, received: n2.parsedType }), Ma;
const o2 = this._def.keyType, i2 = this._def.valueType, r2 = [...n2.data.entries()].map(([e16, t3], r3) => ({ key: o2._parse(new Oa(n2, e16, n2.path, [r3, "key"])), value: i2._parse(new Oa(n2, t3, n2.path, [r3, "value"])) }));
if (n2.common.async) {
const e16 = new Map;
return Promise.resolve().then(async () => {
for (const n3 of r2) {
const o3 = await n3.key, i3 = await n3.value;
if (o3.status === "aborted" || i3.status === "aborted")
return Ma;
o3.status !== "dirty" && i3.status !== "dirty" || t2.dirty(), e16.set(o3.value, i3.value);
}
return { status: t2.value, value: e16 };
});
}
{
const e16 = new Map;
for (const n3 of r2) {
const { key: o3, value: i3 } = n3;
if (o3.status === "aborted" || i3.status === "aborted")
return Ma;
o3.status !== "dirty" && i3.status !== "dirty" || t2.dirty(), e16.set(o3.value, i3.value);
}
return { status: t2.value, value: e16 };
}
}
};
Tc.create = (e15, t2, n2) => new Tc({ valueType: t2, keyType: e15, typeName: qc.ZodMap, ...Da(n2) });
var Rc = class e15 extends za {
_parse(e16) {
const { status: t2, ctx: n2 } = this._processInputParams(e16);
if (n2.parsedType !== da.set)
return Ia(n2, { code: pa.invalid_type, expected: da.set, received: n2.parsedType }), Ma;
const o2 = this._def;
o2.minSize !== null && n2.data.size < o2.minSize.value && (Ia(n2, { code: pa.too_small, minimum: o2.minSize.value, type: "set", inclusive: true, exact: false, message: o2.minSize.message }), t2.dirty()), o2.maxSize !== null && n2.data.size > o2.maxSize.value && (Ia(n2, { code: pa.too_big, maximum: o2.maxSize.value, type: "set", inclusive: true, exact: false, message: o2.maxSize.message }), t2.dirty());
const i2 = this._def.valueType;
function r2(e17) {
const n3 = new Set;
for (const o3 of e17) {
if (o3.status === "aborted")
return Ma;
o3.status === "dirty" && t2.dirty(), n3.add(o3.value);
}
return { status: t2.value, value: n3 };
}
const s2 = [...n2.data.values()].map((e17, t3) => i2._parse(new Oa(n2, e17, n2.path, t3)));
return n2.common.async ? Promise.all(s2).then((e17) => r2(e17)) : r2(s2);
}
min(t2, n2) {
return new e15({ ...this._def, minSize: { value: t2, message: Sa.toString(n2) } });
}
max(t2, n2) {
return new e15({ ...this._def, maxSize: { value: t2, message: Sa.toString(n2) } });
}
size(e16, t2) {
return this.min(e16, t2).max(e16, t2);
}
nonempty(e16) {
return this.min(1, e16);
}
};
Rc.create = (e16, t2) => new Rc({ valueType: e16, minSize: null, maxSize: null, typeName: qc.ZodSet, ...Da(t2) });
var Ec = class e16 extends za {
constructor() {
super(...arguments), this.validate = this.implement;
}
_parse(e17) {
const { ctx: t2 } = this._processInputParams(e17);
if (t2.parsedType !== da.function)
return Ia(t2, { code: pa.invalid_type, expected: da.function, received: t2.parsedType }), Ma;
function n2(e18, n3) {
return xa({ data: e18, path: t2.path, errorMaps: [t2.common.contextualErrorMap, t2.schemaErrorMap, ba(), fa].filter((e19) => !!e19), issueData: { code: pa.invalid_arguments, argumentsError: n3 } });
}
function o2(e18, n3) {
return xa({ data: e18, path: t2.path, errorMaps: [t2.common.contextualErrorMap, t2.schemaErrorMap, ba(), fa].filter((e19) => !!e19), issueData: { code: pa.invalid_return_type, returnTypeError: n3 } });
}
const i2 = { errorMap: t2.common.contextualErrorMap }, r2 = t2.data;
if (this._def.returns instanceof zc) {
const e18 = this;
return Na(async function(...t3) {
const s2 = new ga([]), a2 = await e18._def.args.parseAsync(t3, i2).catch((e19) => {
throw s2.addIssue(n2(t3, e19)), s2;
}), c2 = await Reflect.apply(r2, this, a2);
return await e18._def.returns._def.type.parseAsync(c2, i2).catch((e19) => {
throw s2.addIssue(o2(c2, e19)), s2;
});
});
}
{
const e18 = this;
return Na(function(...t3) {
const s2 = e18._def.args.safeParse(t3, i2);
if (!s2.success)
throw new ga([n2(t3, s2.error)]);
const a2 = Reflect.apply(r2, this, s2.data), c2 = e18._def.returns.safeParse(a2, i2);
if (!c2.success)
throw new ga([o2(a2, c2.error)]);
return c2.data;
});
}
}
parameters() {
return this._def.args;
}
returnType() {
return this._def.returns;
}
args(...t2) {
return new e16({ ...this._def, args: wc.create(t2).rest(fc.create()) });
}
returns(t2) {
return new e16({ ...this._def, returns: t2 });
}
implement(e17) {
return this.parse(e17);
}
strictImplement(e17) {
return this.parse(e17);
}
static create(t2, n2, o2) {
return new e16({ args: t2 || wc.create([]).rest(fc.create()), returns: n2 || fc.create(), typeName: qc.ZodFunction, ...Da(o2) });
}
};
var Ac = class extends za {
get schema() {
return this._def.getter();
}
_parse(e17) {
const { ctx: t2 } = this._processInputParams(e17);
return this._def.getter()._parse({ data: t2.data, path: t2.path, parent: t2 });
}
};
Ac.create = (e17, t2) => new Ac({ getter: e17, typeName: qc.ZodLazy, ...Da(t2) });
var Oc = class extends za {
_parse(e17) {
if (e17.data !== this._def.value) {
const t2 = this._getOrReturnCtx(e17);
return Ia(t2, { received: t2.data, code: pa.invalid_literal, expected: this._def.value }), Ma;
}
return { status: "valid", value: e17.data };
}
get value() {
return this._def.value;
}
};
function kc(e17, t2) {
return new Dc({ values: e17, typeName: qc.ZodEnum, ...Da(t2) });
}
Oc.create = (e17, t2) => new Oc({ value: e17, typeName: qc.ZodLiteral, ...Da(t2) });
var Dc = class e17 extends za {
_parse(e18) {
if (typeof e18.data != "string") {
const t2 = this._getOrReturnCtx(e18), n2 = this._def.values;
return Ia(t2, { expected: aa.joinValues(n2), received: t2.parsedType, code: pa.invalid_type }), Ma;
}
if (this._cache || (this._cache = new Set(this._def.values)), !this._cache.has(e18.data)) {
const t2 = this._getOrReturnCtx(e18), n2 = this._def.values;
return Ia(t2, { received: t2.data, code: pa.invalid_enum_value, options: n2 }), Ma;
}
return Na(e18.data);
}
get options() {
return this._def.values;
}
get enum() {
const e18 = {};
for (const t2 of this._def.values)
e18[t2] = t2;
return e18;
}
get Values() {
const e18 = {};
for (const t2 of this._def.values)
e18[t2] = t2;
return e18;
}
get Enum() {
const e18 = {};
for (const t2 of this._def.values)
e18[t2] = t2;
return e18;
}
extract(t2, n2 = this._def) {
return e17.create(t2, { ...this._def, ...n2 });
}
exclude(t2, n2 = this._def) {
return e17.create(this.options.filter((e18) => !t2.includes(e18)), { ...this._def, ...n2 });
}
};
Dc.create = kc;
var Lc = class extends za {
_parse(e18) {
const t2 = aa.getValidEnumValues(this._def.values), n2 = this._getOrReturnCtx(e18);
if (n2.parsedType !== da.string && n2.parsedType !== da.number) {
const e19 = aa.objectValues(t2);
return Ia(n2, { expected: aa.joinValues(e19), received: n2.parsedType, code: pa.invalid_type }), Ma;
}
if (this._cache || (this._cache = new Set(aa.getValidEnumValues(this._def.values))), !this._cache.has(e18.data)) {
const e19 = aa.objectValues(t2);
return Ia(n2, { received: n2.data, code: pa.invalid_enum_value, options: e19 }), Ma;
}
return Na(e18.data);
}
get enum() {
return this._def.values;
}
};
Lc.create = (e18, t2) => new Lc({ values: e18, typeName: qc.ZodNativeEnum, ...Da(t2) });
var zc = class extends za {
unwrap() {
return this._def.type;
}
_parse(e18) {
const { ctx: t2 } = this._processInputParams(e18);
if (t2.parsedType !== da.promise && t2.common.async === false)
return Ia(t2, { code: pa.invalid_type, expected: da.promise, received: t2.parsedType }), Ma;
const n2 = t2.parsedType === da.promise ? t2.data : Promise.resolve(t2.data);
return Na(n2.then((e19) => this._def.type.parseAsync(e19, { path: t2.path, errorMap: t2.common.contextualErrorMap })));
}
};
zc.create = (e18, t2) => new zc({ type: e18, typeName: qc.ZodPromise, ...Da(t2) });
var Bc = class extends za {
innerType() {
return this._def.schema;
}
sourceType() {
return this._def.schema._def.typeName === qc.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
}
_parse(e18) {
const { status: t2, ctx: n2 } = this._processInputParams(e18), o2 = this._def.effect || null, i2 = { addIssue: (e19) => {
Ia(n2, e19), e19.fatal ? t2.abort() : t2.dirty();
}, get path() {
return n2.path;
} };
if (i2.addIssue = i2.addIssue.bind(i2), o2.type === "preprocess") {
const e19 = o2.transform(n2.data, i2);
if (n2.common.async)
return Promise.resolve(e19).then(async (e20) => {
if (t2.value === "aborted")
return Ma;
const o3 = await this._def.schema._parseAsync({ data: e20, path: n2.path, parent: n2 });
return o3.status === "aborted" ? Ma : o3.status === "dirty" || t2.value === "dirty" ? wa(o3.value) : o3;
});
{
if (t2.value === "aborted")
return Ma;
const o3 = this._def.schema._parseSync({ data: e19, path: n2.path, parent: n2 });
return o3.status === "aborted" ? Ma : o3.status === "dirty" || t2.value === "dirty" ? wa(o3.value) : o3;
}
}
if (o2.type === "refinement") {
const e19 = (e20) => {
const t3 = o2.refinement(e20, i2);
if (n2.common.async)
return Promise.resolve(t3);
if (t3 instanceof Promise)
throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
return e20;
};
if (n2.common.async === false) {
const o3 = this._def.schema._parseSync({ data: n2.data, path: n2.path, parent: n2 });
return o3.status === "aborted" ? Ma : (o3.status === "dirty" && t2.dirty(), e19(o3.value), { status: t2.value, value: o3.value });
}
return this._def.schema._parseAsync({ data: n2.data, path: n2.path, parent: n2 }).then((n3) => n3.status === "aborted" ? Ma : (n3.status === "dirty" && t2.dirty(), e19(n3.value).then(() => ({ status: t2.value, value: n3.value }))));
}
if (o2.type === "transform") {
if (n2.common.async === false) {
const e19 = this._def.schema._parseSync({ data: n2.data, path: n2.path, parent: n2 });
if (!Ea(e19))
return Ma;
const r2 = o2.transform(e19.value, i2);
if (r2 instanceof Promise)
throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");
return { status: t2.value, value: r2 };
}
return this._def.schema._parseAsync({ data: n2.data, path: n2.path, parent: n2 }).then((e19) => Ea(e19) ? Promise.resolve(o2.transform(e19.value, i2)).then((e20) => ({ status: t2.value, value: e20 })) : Ma);
}
aa.assertNever(o2);
}
};
Bc.create = (e18, t2, n2) => new Bc({ schema: e18, typeName: qc.ZodEffects, effect: t2, ...Da(n2) }), Bc.createWithPreprocess = (e18, t2, n2) => new Bc({ schema: t2, effect: { type: "preprocess", transform: e18 }, typeName: qc.ZodEffects, ...Da(n2) });
var Fc = class extends za {
_parse(e18) {
return this._getType(e18) === da.undefined ? Na(undefined) : this._def.innerType._parse(e18);
}
unwrap() {
return this._def.innerType;
}
};
Fc.create = (e18, t2) => new Fc({ innerType: e18, typeName: qc.ZodOptional, ...Da(t2) });
var jc = class extends za {
_parse(e18) {
return this._getType(e18) === da.null ? Na(null) : this._def.innerType._parse(e18);
}
unwrap() {
return this._def.innerType;
}
};
jc.create = (e18, t2) => new jc({ innerType: e18, typeName: qc.ZodNullable, ...Da(t2) });
var $c = class extends za {
_parse(e18) {
const { ctx: t2 } = this._processInputParams(e18);
let n2 = t2.data;
return t2.parsedType === da.undefined && (n2 = this._def.defaultValue()), this._def.innerType._parse({ data: n2, path: t2.path, parent: t2 });
}
removeDefault() {
return this._def.innerType;
}
};
$c.create = (e18, t2) => new $c({ innerType: e18, typeName: qc.ZodDefault, defaultValue: typeof t2.default == "function" ? t2.default : () => t2.default, ...Da(t2) });
var Yc = class extends za {
_parse(e18) {
const { ctx: t2 } = this._processInputParams(e18), n2 = { ...t2, common: { ...t2.common, issues: [] } }, o2 = this._def.innerType._parse({ data: n2.data, path: n2.path, parent: { ...n2 } });
return Aa(o2) ? o2.then((e19) => ({ status: "valid", value: e19.status === "valid" ? e19.value : this._def.catchValue({ get error() {
return new ga(n2.common.issues);
}, input: n2.data }) })) : { status: "valid", value: o2.status === "valid" ? o2.value : this._def.catchValue({ get error() {
return new ga(n2.common.issues);
}, input: n2.data }) };
}
removeCatch() {
return this._def.innerType;
}
};
Yc.create = (e18, t2) => new Yc({ innerType: e18, typeName: qc.ZodCatch, catchValue: typeof t2.catch == "function" ? t2.catch : () => t2.catch, ...Da(t2) });
var Xc = class extends za {
_parse(e18) {
if (this._getType(e18) !== da.nan) {
const t2 = this._getOrReturnCtx(e18);
return Ia(t2, { code: pa.invalid_type, expected: da.nan, received: t2.parsedType }), Ma;
}
return { status: "valid", value: e18.data };
}
};
Xc.create = (e18) => new Xc({ typeName: qc.ZodNaN, ...Da(e18) });
var Wc = Symbol("zod_brand");
var Vc = class extends za {
_parse(e18) {
const { ctx: t2 } = this._processInputParams(e18), n2 = t2.data;
return this._def.type._parse({ data: n2, path: t2.path, parent: t2 });
}
unwrap() {
return this._def.type;
}
};
var Hc = class e18 extends za {
_parse(e19) {
const { status: t2, ctx: n2 } = this._processInputParams(e19);
if (n2.common.async) {
return (async () => {
const e20 = await this._def.in._parseAsync({ data: n2.data, path: n2.path, parent: n2 });
return e20.status === "aborted" ? Ma : e20.status === "dirty" ? (t2.dirty(), wa(e20.value)) : this._def.out._parseAsync({ data: e20.value, path: n2.path, parent: n2 });
})();
}
{
const e20 = this._def.in._parseSync({ data: n2.data, path: n2.path, parent: n2 });
return e20.status === "aborted" ? Ma : e20.status === "dirty" ? (t2.dirty(), { status: "dirty", value: e20.value }) : this._def.out._parseSync({ data: e20.value, path: n2.path, parent: n2 });
}
}
static create(t2, n2) {
return new e18({ in: t2, out: n2, typeName: qc.ZodPipeline });
}
};
var Gc = class extends za {
_parse(e19) {
const t2 = this._def.innerType._parse(e19), n2 = (e20) => (Ea(e20) && (e20.value = Object.freeze(e20.value)), e20);
return Aa(t2) ? t2.then((e20) => n2(e20)) : n2(t2);
}
unwrap() {
return this._def.innerType;
}
};
function Uc(e19, t2) {
const n2 = typeof e19 == "function" ? e19(t2) : typeof e19 == "string" ? { message: e19 } : e19;
return typeof n2 == "string" ? { message: n2 } : n2;
}
function Zc(e19, t2 = {}, n2) {
return e19 ? gc.create().superRefine((o2, i2) => {
const r2 = e19(o2);
if (r2 instanceof Promise)
return r2.then((e20) => {
if (!e20) {
const e21 = Uc(t2, o2), r3 = e21.fatal ?? n2 ?? true;
i2.addIssue({ code: "custom", ...e21, fatal: r3 });
}
});
if (!r2) {
const e20 = Uc(t2, o2), r3 = e20.fatal ?? n2 ?? true;
i2.addIssue({ code: "custom", ...e20, fatal: r3 });
}
}) : gc.create();
}
Gc.create = (e19, t2) => new Gc({ innerType: e19, typeName: qc.ZodReadonly, ...Da(t2) });
var qc;
var Jc;
var Qc = { object: vc.lazycreate };
(Jc = qc || (qc = {})).ZodString = "ZodString", Jc.ZodNumber = "ZodNumber", Jc.ZodNaN = "ZodNaN", Jc.ZodBigInt = "ZodBigInt", Jc.ZodBoolean = "ZodBoolean", Jc.ZodDate = "ZodDate", Jc.ZodSymbol = "ZodSymbol", Jc.ZodUndefined = "ZodUndefined", Jc.ZodNull = "ZodNull", Jc.ZodAny = "ZodAny", Jc.ZodUnknown = "ZodUnknown", Jc.ZodNever = "ZodNever", Jc.ZodVoid = "ZodVoid", Jc.ZodArray = "ZodArray", Jc.ZodObject = "ZodObject", Jc.ZodUnion = "ZodUnion", Jc.ZodDiscriminatedUnion = "ZodDiscriminatedUnion", Jc.ZodIntersection = "ZodIntersection", Jc.ZodTuple = "ZodTuple", Jc.ZodRecord = "ZodRecord", Jc.ZodMap = "ZodMap", Jc.ZodSet = "ZodSet", Jc.ZodFunction = "ZodFunction", Jc.ZodLazy = "ZodLazy", Jc.ZodLiteral = "ZodLiteral", Jc.ZodEnum = "ZodEnum", Jc.ZodEffects = "ZodEffects", Jc.ZodNativeEnum = "ZodNativeEnum", Jc.ZodOptional = "ZodOptional", Jc.ZodNullable = "ZodNullable", Jc.ZodDefault = "ZodDefault", Jc.ZodCatch = "ZodCatch", Jc.ZodPromise = "ZodPromise", Jc.ZodBranded = "ZodBranded", Jc.ZodPipeline = "ZodPipeline", Jc.ZodReadonly = "ZodReadonly";
var Kc = (e19, t2 = { message: `Input not instance of ${e19.name}` }) => Zc((t3) => t3 instanceof e19, t2);
var el = sc.create;
var tl = cc.create;
var nl = Xc.create;
var ol = lc.create;
var il = hc.create;
var rl = dc.create;
var sl = uc.create;
var al = pc.create;
var cl = mc.create;
var ll = gc.create;
var hl = fc.create;
var dl = _c.create;
var ul = yc.create;
var pl = bc.create;
var ml = vc.create;
var gl = vc.strictCreate;
var fl = Ic.create;
var _l = Cc.create;
var yl = Mc.create;
var bl = wc.create;
var xl = Nc.create;
var vl = Tc.create;
var Il = Rc.create;
var Sl = Ec.create;
var Cl = Ac.create;
var Pl = Oc.create;
var Ml = Dc.create;
var wl = Lc.create;
var Nl = zc.create;
var Tl = Bc.create;
var Rl = Fc.create;
var El = jc.create;
var Al = Bc.createWithPreprocess;
var Ol = Hc.create;
var kl = () => el().optional();
var Dl = () => tl().optional();
var Ll = () => il().optional();
var zl = { string: (e19) => sc.create({ ...e19, coerce: true }), number: (e19) => cc.create({ ...e19, coerce: true }), boolean: (e19) => hc.create({ ...e19, coerce: true }), bigint: (e19) => lc.create({ ...e19, coerce: true }), date: (e19) => dc.create({ ...e19, coerce: true }) };
var Bl = Ma;
var Fl = { Hz: { baseUnit: "Hz", variants: { MHz: 1e6, kHz: 1000, Hz: 1 } }, g: { baseUnit: "g", variants: { kg: 1000, g: 1 } }, "Ω": { baseUnit: "Ω", variants: { "mΩ": 0.001, "Ω": 1, "kΩ": 1000, "KΩ": 1000, kohm: 1000, "MΩ": 1e6, "GΩ": 1e9, "TΩ": 1000000000000 } }, V: { baseUnit: "V", variants: { mV: 0.001, V: 1, kV: 1000, KV: 1000, MV: 1e6, GV: 1e9, TV: 1000000000000 } }, A: { baseUnit: "A", variants: { "µA": 0.000001, mA: 0.001, ma: 0.001, A: 1, kA: 1000, MA: 1e6 } }, F: { baseUnit: "F", variants: { pF: 0.000000000001, nF: 0.000000001, "µF": 0.000001, uF: 0.000001, mF: 0.001, F: 1 } }, ml: { baseUnit: "ml", variants: { ml: 1, mL: 1, l: 1000, L: 1000 } }, deg: { baseUnit: "deg", variants: { rad: 180 / Math.PI } }, ms: { baseUnit: "ms", variants: { fs: 0.000000000001, ps: 0.000000001, ns: 0.000001, us: 0.001, "µs": 0.001, ms: 1, s: 1000 } }, mm: { baseUnit: "mm", variants: { nm: 0.000001, "µm": 0.001, um: 0.001, mm: 1, cm: 10, dm: 100, m: 1000, km: 1e6, in: 25.4, ft: 304.8, IN: 25.4, FT: 304.8, yd: 914.4, mi: 1609344, mil: 0.0254 } } };
var jl = new Set;
for (const [e19, t2] of Object.entries(Fl)) {
jl.add(e19);
for (const e20 of Object.keys(t2.variants))
jl.add(e20);
}
var $l = { tera: 1000000000000, T: 1000000000000, giga: 1e9, G: 1e9, mega: 1e6, M: 1e6, kilo: 1000, k: 1000, deci: 0.1, d: 0.1, centi: 0.01, c: 0.01, milli: 0.001, m: 0.001, micro: 0.000001, u: 0.000001, "µ": 0.000001, nano: 0.000000001, n: 0.000000001, pico: 0.000000000001, p: 0.000000000001 };
function Yl(e19) {
if (e19 == null)
return { parsedUnit: null, unitOfValue: null, value: null };
if (typeof e19 == "string" && e19.match(/^-?[\d\.]+$/))
return { value: Number.parseFloat(e19), parsedUnit: null, unitOfValue: null };
if (typeof e19 == "number")
return { value: e19, parsedUnit: null, unitOfValue: null };
if (typeof e19 == "object" && "x" in e19 && "y" in e19) {
const { parsedUnit: t3, unitOfValue: n3 } = Yl(e19.x), o3 = Yl(e19.x), i3 = Yl(e19.y);
return o3.value === null || i3.value === null ? { parsedUnit: null, unitOfValue: null, value: null } : { parsedUnit: t3, unitOfValue: n3, value: { x: o3.value, y: i3.value } };
}
const t2 = e19.toString().split("").reverse().join(""), n2 = t2.match(/[^\d\s]+/)?.[0];
if (!n2)
throw new Error(`Could not determine unit: "${e19}"`);
const o2 = n2.split("").reverse().join(""), i2 = e19.slice(0, -o2.length);
if (o2 in $l && !jl.has(o2)) {
const e20 = $l[o2];
return { parsedUnit: null, unitOfValue: null, value: Number.parseFloat(i2) * e20 };
}
const { baseUnit: r2, conversionFactor: s2 } = function(e20) {
for (const [t3, n3] of Object.entries(Fl))
if (e20 in n3.variants)
return { baseUnit: n3.baseUnit, conversionFactor: n3.variants[e20] };
return { baseUnit: e20, conversionFactor: 1 };
}(o2);
return { parsedUnit: o2, unitOfValue: r2, value: s2 * Number.parseFloat(i2) };
}
var Xl = ha.string().or(ha.number()).transform((e19) => Yl(e19).value);
var Wl = ha.string().or(ha.number()).transform((e19) => Yl(e19).value).transform((e19) => Number.parseFloat(e19.toPrecision(12)));
var Vl = ha.string().or(ha.number()).transform((e19) => Yl(e19).value);
var Hl = ha.string().or(ha.number()).transform((e19) => Yl(e19).value);
var Gl = ha.string().or(ha.number()).transform((e19) => Yl(e19).value);
var Ul = ha.string().or(ha.number()).transform((e19) => Yl(e19).value);
var Zl = Gl;
var ql = ha.string().or(ha.number()).transform((e19) => Yl(e19).value);
var Jl = ha.string().or(ha.number()).transform((e19) => Yl(e19).value);
var Ql = Jl;
var Kl = Jl;
var eh = ha.string().datetime();
var th = ha.string().or(ha.number()).transform((e19) => typeof e19 == "number" ? e19 : e19.endsWith("deg") ? Number.parseFloat(e19.split("deg")[0]) : e19.endsWith("rad") ? 180 * Number.parseFloat(e19.split("rad")[0]) / Math.PI : Number.parseFloat(e19));
var nh = ha.number().or(ha.string().endsWith("mAh")).transform((e19) => {
if (typeof e19 == "string") {
const t2 = e19.replace("mAh", ""), n2 = Number.parseFloat(t2);
if (Number.isNaN(n2))
throw new Error("Invalid capacity");
return n2;
}
return e19;
}).describe("Battery capacity in mAh");
var oh = ha.object({ x: Zl, y: Zl });
var ih = oh;
var rh = ha.object({ x: Zl, y: Zl, z: Zl });
var sh = rh;
var ah = ha.object({ width: ha.number(), height: ha.number() });
var ch = (e19) => ha.string().optional().default(() => `${e19}_${((e20) => {
const t2 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return Array.from({ length: e20 }, () => t2[Math.floor(62 * Math.random())]).join("");
})(10)}`);
var lh = ha.enum(["top_left", "top_center", "top_right", "center_left", "center", "center_right", "bottom_left", "bottom_center", "bottom_right"]);
var hh = ha.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"]);
var dh = ha.object({ project_relative_path: ha.string(), url: ha.string(), mimetype: ha.string() });
var uh = oh.extend({ rotation: th.optional() });
var ph = ha.object({ size: oh.optional(), thickness: Zl.optional() });
var mh = ha.object({ font: ph.optional() });
var gh = ha.object({ value: ha.string(), at: uh.optional(), layer: ha.string().optional(), uuid: ha.string().optional(), hide: ha.boolean().optional(), effects: mh.optional() });
var fh = ha.object({ Reference: gh.optional(), Value: gh.optional(), Datasheet: gh.optional(), Description: gh.optional() });
var _h = ha.object({ through_hole: ha.boolean().optional(), smd: ha.boolean().optional(), exclude_from_pos_files: ha.boolean().optional(), exclude_from_bom: ha.boolean().optional() });
var yh = ha.object({ name: ha.string(), type: ha.string(), shape: ha.string().optional(), at: uh.optional(), size: oh.optional(), drill: Zl.optional(), layers: ha.array(ha.string()).optional(), removeUnusedLayers: ha.boolean().optional(), uuid: ha.string().optional() });
var bh = ha.object({ path: ha.string(), offset: rh.optional(), scale: rh.optional(), rotate: rh.optional() });
var xh = ha.object({ footprintName: ha.string().optional(), version: ha.union([ha.number(), ha.string()]).optional(), generator: ha.string().optional(), generatorVersion: ha.union([ha.number(), ha.string()]).optional(), layer: ha.string().optional(), properties: fh.optional(), attributes: _h.optional(), pads: ha.array(yh).optional(), embeddedFonts: ha.boolean().optional(), model: bh.optional() });
var vh = ha.object({ hide: ha.boolean().optional() });
var Ih = ha.object({ offset: Zl.optional(), hide: ha.boolean().optional() });
var Sh = ha.object({ font: ph.optional(), justify: ha.union([ha.string(), ha.array(ha.string())]).optional(), hide: ha.boolean().optional() });
var Ch = ha.object({ value: ha.string(), id: ha.union([ha.number(), ha.string()]).optional(), at: uh.optional(), effects: Sh.optional() });
var Ph = ha.object({ Reference: Ch.optional(), Value: Ch.optional(), Footprint: Ch.optional(), Datasheet: Ch.optional(), Description: Ch.optional(), ki_keywords: Ch.optional(), ki_fp_filters: Ch.optional() });
var Mh = ha.object({ symbolName: ha.string().optional(), extends: ha.string().optional(), pinNumbers: vh.optional(), pinNames: Ih.optional(), excludeFromSim: ha.boolean().optional(), inBom: ha.boolean().optional(), onBoard: ha.boolean().optional(), properties: Ph.optional(), embeddedFonts: ha.boolean().optional() });
var wh = ha.object({ error_type: ha.string(), message: ha.string(), is_fatal: ha.boolean().optional() });
var Nh = ha.enum(["jlcpcb", "macrofab", "pcbway", "digikey", "mouser", "lcsc"]);
var Th = ha.object({ type: ha.literal("source_component"), ftype: ha.string().optional(), source_component_id: ha.string(), name: ha.string(), manufacturer_part_number: ha.string().optional(), supplier_part_numbers: ha.record(Nh, ha.array(ha.string())).optional(), display_value: ha.string().optional(), display_name: ha.string().optional(), are_pins_interchangeable: ha.boolean().optional(), internally_connected_source_port_ids: ha.array(ha.array(ha.string())).optional(), source_group_id: ha.string().optional(), subcircuit_id: ha.string().optional() });
var Rh = Th.extend({ ftype: ha.literal("simple_capacitor"), capacitance: Wl, max_voltage_rating: Hl.optional(), display_capacitance: ha.string().optional(), max_decoupling_trace_length: Zl.optional() });
var Eh = Th.extend({ ftype: ha.literal("simple_resistor"), resistance: Xl, display_resistance: ha.string().optional() });
var Ah = Th.extend({ ftype: ha.literal("simple_diode") });
var Oh = Th.extend({ ftype: ha.literal("simple_fiducial") });
var kh = Ah.extend({ ftype: ha.literal("simple_led"), color: ha.string().optional(), wavelength: ha.string().optional() });
var Dh = Th.extend({ ftype: ha.literal("simple_ground") });
var Lh = Th.extend({ ftype: ha.literal("simple_chip") });
var zh = Th.extend({ ftype: ha.literal("simple_power_source"), voltage: Hl });
var Bh = Th.extend({ ftype: ha.literal("simple_current_source"), current: ql, frequency: Ul.optional(), peak_to_peak_current: ql.optional(), wave_shape: ha.enum(["sine", "square", "triangle", "sawtooth", "dc"]).optional().default("dc"), phase: ha.number().optional(), duty_cycle: ha.number().min(0).max(1).optional() });
var Fh = ha.object({ must_be_connected: ha.boolean().optional(), provides_power: ha.boolean().optional(), requires_power: ha.boolean().optional(), provides_ground: ha.boolean().optional(), requires_ground: ha.boolean().optional(), provides_voltage: ha.union([ha.string(), ha.number()]).optional(), requires_voltage: ha.union([ha.string(), ha.number()]).optional(), do_not_connect: ha.boolean().optional(), include_in_board_pinout: ha.boolean().optional(), can_use_internal_pullup: ha.boolean().optional(), is_using_internal_pullup: ha.boolean().optional(), needs_external_pullup: ha.boolean().optional(), can_use_internal_pulldown: ha.boolean().optional(), is_using_internal_pulldown: ha.boolean().optional(), needs_external_pulldown: ha.boolean().optional(), can_use_open_drain: ha.boolean().optional(), is_using_open_drain: ha.boolean().optional(), can_use_push_pull: ha.boolean().optional(), is_using_push_pull: ha.boolean().optional(), should_have_decoupling_capacitor: ha.boolean().optional(), recommended_decoupling_capacitor_capacitance: ha.union([ha.string(), ha.number()]).optional(), is_configured_for_i2c_sda: ha.boolean().optional(), is_configured_for_i2c_scl: ha.boolean().optional(), is_configured_for_spi_mosi: ha.boolean().optional(), is_configured_for_spi_miso: ha.boolean().optional(), is_configured_for_spi_sck: ha.boolean().optional(), is_configured_for_spi_cs: ha.boolean().optional(), is_configured_for_uart_tx: ha.boolean().optional(), is_configured_for_uart_rx: ha.boolean().optional(), supports_i2c_sda: ha.boolean().optional(), supports_i2c_scl: ha.boolean().optional(), supports_spi_mosi: ha.boolean().optional(), supports_spi_miso: ha.boolean().optional(), supports_spi_sck: ha.boolean().optional(), supports_spi_cs: ha.boolean().optional(), supports_uart_tx: ha.boolean().optional(), supports_uart_rx: ha.boolean().optional() });
var jh = Th.extend({ ftype: ha.literal("simple_fuse"), current_rating_amps: ha.number().describe("Nominal current in amps the fuse is rated for"), voltage_rating_volts: ha.number().describe("Voltage rating in volts, e.g. ±5V would be 5") });
var $h = Th.extend({ ftype: ha.literal("simple_battery"), capacity: nh });
var Yh = Th.extend({ ftype: ha.literal("simple_inductor"), inductance: Vl, display_inductance: ha.string().optional(), max_current_rating: ha.number().optional() });
var Xh = Th.extend({ ftype: ha.literal("simple_push_button") });
var Wh = Th.extend({ ftype: ha.literal("simple_potentiometer"), max_resistance: Xl, display_max_resistance: ha.string().optional() });
var Vh = Th.extend({ ftype: ha.literal("simple_crystal"), frequency: ha.number().describe("Frequency in Hz"), load_capacitance: ha.number().optional().describe("Load capacitance in pF"), pin_variant: ha.enum(["two_pin", "four_pin"]).optional() });
var Hh = Th.extend({ ftype: ha.literal("simple_pin_header"), pin_count: ha.number(), gender: ha.enum(["male", "female"]).optional().default("male") });
var Gh = Th.extend({ ftype: ha.literal("simple_connector"), standard: ha.enum(["usb_c", "m2"]).optional() });
var Uh = Th.extend({ ftype: ha.literal("simple_pinout") });
var Zh = Th.extend({ ftype: ha.literal("simple_resonator"), load_capacitance: Wl, equivalent_series_resistance: Xl.optional(), frequency: Ul });
var qh = Th.extend({ ftype: ha.literal("simple_transistor"), transistor_type: ha.enum(["npn", "pnp"]) });
var Jh = Th.extend({ ftype: ha.literal("simple_test_point"), footprint_variant: ha.enum(["pad", "through_hole"]).optional(), pad_shape: ha.enum(["rect", "circle"]).optional(), pad_diameter: ha.union([ha.number(), ha.string()]).optional(), hole_diameter: ha.union([ha.number(), ha.string()]).optional(), width: ha.union([ha.number(), ha.string()]).optional(), height: ha.union([ha.number(), ha.string()]).optional() });
var Qh = Th.extend({ ftype: ha.literal("simple_mosfet"), channel_type: ha.enum(["n", "p"]), mosfet_mode: ha.enum(["enhancement", "depletion"]) });
var Kh = Th.extend({ ftype: ha.literal("simple_op_amp") });
var ed = Th.extend({ ftype: ha.literal("simple_switch") });
var td = ha.object({ type: ha.literal("source_project_metadata"), name: ha.string().optional(), software_used_string: ha.string().optional(), project_url: ha.string().optional(), created_at: eh.optional() });
var nd = wh.extend({ type: ha.literal("source_missing_property_error"), source_missing_property_error_id: ch("source_missing_property_error"), source_component_id: ha.string(), property_name: ha.string(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_missing_property_error").default("source_missing_property_error") }).describe("The source code is missing a property");
var od = wh.extend({ type: ha.literal("source_failed_to_create_component_error"), source_failed_to_create_component_error_id: ch("source_failed_to_create_component_error"), error_type: ha.literal("source_failed_to_create_component_error").default("source_failed_to_create_component_error"), component_name: ha.string().optional(), subcircuit_id: ha.string().optional(), parent_source_component_id: ha.string().optional(), pcb_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), schematic_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional() }).describe("Error emitted when a component fails to be constructed");
var id = wh.extend({ type: ha.literal("source_invalid_component_property_error"), source_invalid_component_property_error_id: ch("source_invalid_component_property_error"), source_component_id: ha.string(), property_name: ha.string(), property_value: ha.unknown().optional(), expected_format: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_invalid_component_property_error").default("source_invalid_component_property_error") }).describe("The source component property is invalid");
var rd = wh.extend({ type: ha.literal("source_trace_not_connected_error"), source_trace_not_connected_error_id: ch("source_trace_not_connected_error"), error_type: ha.literal("source_trace_not_connected_error").default("source_trace_not_connected_error"), subcircuit_id: ha.string().optional(), source_group_id: ha.string().optional(), source_trace_id: ha.string().optional(), connected_source_port_ids: ha.array(ha.string()).optional(), selectors_not_found: ha.array(ha.string()).optional() }).describe("Occurs when a source trace selector does not match any ports");
var sd = ha.object({ type: ha.literal("source_property_ignored_warning"), source_property_ignored_warning_id: ch("source_property_ignored_warning"), source_component_id: ha.string(), property_name: ha.string(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_property_ignored_warning").default("source_property_ignored_warning"), message: ha.string() }).describe("The source property was ignored");
var ad = ha.object({ type: ha.literal("source_pin_missing_trace_warning"), source_pin_missing_trace_warning_id: ch("source_pin_missing_trace_warning"), warning_type: ha.literal("source_pin_missing_trace_warning").default("source_pin_missing_trace_warning"), message: ha.string(), source_component_id: ha.string(), source_port_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a source component pin is missing a trace connection");
var cd = ha.object({ type: ha.literal("source_missing_manufacturer_part_number_warning"), source_missing_manufacturer_part_number_warning_id: ch("source_missing_manufacturer_part_number_warning"), warning_type: ha.literal("source_missing_manufacturer_part_number_warning").default("source_missing_manufacturer_part_number_warning"), message: ha.string(), source_component_id: ha.string(), standard: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a standard connector is missing manufacturer part number");
var ld = Th.extend({ ftype: ha.literal("simple_voltage_probe") });
var hd = Th.extend({ ftype: ha.literal("interconnect") });
var dd = wh.extend({ type: ha.literal("source_i2c_misconfigured_error"), source_i2c_misconfigured_error_id: ch("source_i2c_misconfigured_error"), error_type: ha.literal("source_i2c_misconfigured_error").default("source_i2c_misconfigured_error"), source_port_ids: ha.array(ha.string()) }).describe("Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net");
var ud = Th.extend({ ftype: ha.literal("simple_voltage_source"), voltage: Hl, frequency: Ul.optional(), peak_to_peak_voltage: Hl.optional(), wave_shape: ha.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(), phase: th.optional(), duty_cycle: ha.number().optional().describe("Duty cycle as a fraction (0 to 1)") });
var pd = ha.union([Eh, Rh, Ah, Oh, kh, Dh, Lh, zh, Bh, $h, Yh, Xh, Wh, Vh, Hh, Gh, Uh, Zh, ed, qh, Jh, Qh, Kh, jh, ld, hd, ud, td, nd, id, od, rd, sd, ad, cd, dd]);
var md = ha.object({ type: ha.literal("source_port"), pin_number: ha.number().optional(), port_hints: ha.array(ha.string()).optional(), name: ha.string(), source_port_id: ha.string(), source_component_id: ha.string().optional(), source_group_id: ha.string().optional(), most_frequently_referenced_by_name: ha.string().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() }).merge(Fh);
var gd = ha.object({ type: ha.literal("source_component_internal_connection"), source_component_internal_connection_id: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() });
var fd = ha.object({ type: ha.literal("source_trace"), source_trace_id: ha.string(), connected_source_port_ids: ha.array(ha.string()), connected_source_net_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), max_length: ha.number().optional(), min_trace_thickness: ha.number().optional(), display_name: ha.string().optional() });
var _d = ha.object({ type: ha.literal("source_group"), source_group_id: ha.string(), subcircuit_id: ha.string().optional(), parent_subcircuit_id: ha.string().optional(), parent_source_group_id: ha.string().optional(), is_subcircuit: ha.boolean().optional(), show_as_schematic_box: ha.boolean().optional(), name: ha.string().optional(), was_automatically_named: ha.boolean().optional() });
var yd = ha.object({ type: ha.literal("source_net"), source_net_id: ha.string(), name: ha.string(), member_source_group_ids: ha.array(ha.string()), is_power: ha.boolean().optional(), is_ground: ha.boolean().optional(), is_digital_signal: ha.boolean().optional(), is_analog_signal: ha.boolean().optional(), is_positive_voltage_source: ha.boolean().optional(), trace_width: ha.number().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() });
var bd = ha.object({ type: ha.literal("source_board"), source_board_id: ha.string(), source_group_id: ha.string(), title: ha.string().optional() }).describe("Defines a board in the source domain");
var xd = wh.extend({ type: ha.literal("source_ambiguous_port_reference"), source_ambiguous_port_reference_id: ch("source_ambiguous_port_reference"), error_type: ha.literal("source_ambiguous_port_reference").default("source_ambiguous_port_reference"), source_port_id: ha.string().optional(), source_component_id: ha.string().optional() }).describe("Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous");
var vd = ha.object({ type: ha.literal("source_pcb_ground_plane"), source_pcb_ground_plane_id: ha.string(), source_group_id: ha.string(), source_net_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Defines a ground plane in the source domain");
var Id = ["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"];
var Sd = ha.enum(Id);
var Cd = Sd.or(ha.object({ name: Sd })).transform((e19) => typeof e19 == "string" ? e19 : e19.name);
var Pd = ha.enum(["top", "bottom"]);
var Md = ha.object({ type: ha.literal("source_manually_placed_via"), source_manually_placed_via_id: ha.string(), source_group_id: ha.string(), source_net_id: ha.string(), subcircuit_id: ha.string().optional(), source_trace_id: ha.string().optional() }).describe("Defines a via that is manually placed in the source domain");
var wd = ha.object({ type: ha.literal("source_no_power_pin_defined_warning"), source_no_power_pin_defined_warning_id: ch("source_no_power_pin_defined_warning"), warning_type: ha.literal("source_no_power_pin_defined_warning").default("source_no_power_pin_defined_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a chip has no source ports with requires_power=true");
var Nd = ha.object({ type: ha.literal("source_no_ground_pin_defined_warning"), source_no_ground_pin_defined_warning_id: ch("source_no_ground_pin_defined_warning"), warning_type: ha.literal("source_no_ground_pin_defined_warning").default("source_no_ground_pin_defined_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a chip has no source ports marked as ground pins");
var Td = ha.object({ type: ha.literal("source_component_pins_underspecified_warning"), source_component_pins_underspecified_warning_id: ch("source_component_pins_underspecified_warning"), warning_type: ha.literal("source_component_pins_underspecified_warning").default("source_component_pins_underspecified_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when all ports on a source component are underspecified");
var Rd = wh.extend({ type: ha.literal("source_pin_must_be_connected_error"), source_pin_must_be_connected_error_id: ch("source_pin_must_be_connected_error"), error_type: ha.literal("source_pin_must_be_connected_error").default("source_pin_must_be_connected_error"), source_component_id: ha.string(), source_port_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a pin with mustBeConnected attribute is not connected to any trace");
var Ed = wh.extend({ type: ha.literal("unknown_error_finding_part"), unknown_error_finding_part_id: ch("unknown_error_finding_part"), error_type: ha.literal("unknown_error_finding_part").default("unknown_error_finding_part"), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when an unexpected error occurs while finding a part");
var Ad = ha.object({ type: ha.literal("schematic_box"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), width: Zl, height: Zl, is_dashed: ha.boolean().default(false), x: Zl, y: Zl, subcircuit_id: ha.string().optional() }).describe("Draws a box on the schematic");
var Od = ha.object({ type: ha.literal("schematic_path"), schematic_path_id: ch("schematic_path"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), fill_color: ha.string().optional(), is_filled: ha.boolean().optional(), stroke_width: Zl.nullable().optional(), stroke_color: ha.string().optional(), points: ha.array(oh), subcircuit_id: ha.string().optional() });
var kd = ha.record(ha.object({ left_margin: Gl.optional(), right_margin: Gl.optional(), top_margin: Gl.optional(), bottom_margin: Gl.optional() }));
var Dd = ha.object({ left_size: ha.number(), right_size: ha.number(), top_size: ha.number().optional(), bottom_size: ha.number().optional() });
var Ld = ha.object({ left_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["top-to-bottom", "bottom-to-top"]).optional() }).optional(), right_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["top-to-bottom", "bottom-to-top"]).optional() }).optional(), top_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["left-to-right", "right-to-left"]).optional() }).optional(), bottom_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["left-to-right", "right-to-left"]).optional() }).optional() });
var zd = ha.union([Dd, Ld]);
var Bd = ha.object({ type: ha.literal("schematic_component"), size: ah, center: oh, source_component_id: ha.string().optional(), schematic_component_id: ha.string(), schematic_symbol_id: ha.string().optional(), pin_spacing: Gl.optional(), pin_styles: kd.optional(), box_width: Gl.optional(), symbol_name: ha.string().optional(), port_arrangement: zd.optional(), port_labels: ha.record(ha.string()).optional(), symbol_display_value: ha.string().optional(), subcircuit_id: ha.string().optional(), schematic_group_id: ha.string().optional(), is_schematic_group: ha.boolean().optional(), source_group_id: ha.string().optional(), is_box_with_pins: ha.boolean().optional().default(true) });
var Fd = ha.object({ kicad_symbol: Mh.optional() }).catchall(ha.unknown());
var jd = ha.object({ type: ha.literal("schematic_symbol"), schematic_symbol_id: ha.string(), name: ha.string().optional(), metadata: Fd.optional() }).describe("Defines a named schematic symbol that can be referenced by components.");
var $d = ha.object({ type: ha.literal("schematic_line"), schematic_line_id: ch("schematic_line"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), x1: Zl, y1: Zl, x2: Zl, y2: Zl, stroke_width: Zl.nullable().optional(), color: ha.string().default("#000000"), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled line on the schematic");
var Yd = ha.object({ type: ha.literal("schematic_rect"), schematic_rect_id: ch("schematic_rect"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: oh, width: Zl, height: Zl, rotation: th.default(0), stroke_width: Zl.nullable().optional(), color: ha.string().default("#000000"), is_filled: ha.boolean().default(false), fill_color: ha.string().optional(), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled rectangle on the schematic");
var Xd = ha.object({ type: ha.literal("schematic_circle"), schematic_circle_id: ch("schematic_circle"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: oh, radius: Zl, stroke_width: Zl.nullable().optional(), color: ha.string().default("#000000"), is_filled: ha.boolean().default(false), fill_color: ha.string().optional(), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled circle on the schematic");
var Wd = ha.object({ type: ha.literal("schematic_arc"), schematic_arc_id: ch("schematic_arc"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: oh, radius: Zl, start_angle_degrees: th, end_angle_degrees: th, direction: ha.enum(["clockwise", "counterclockwise"]).default("counterclockwise"), stroke_width: Zl.nullable().optional(), color: ha.string().default("#000000"), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled arc on the schematic");
var Vd = ha.object({ type: ha.literal("schematic_trace"), schematic_trace_id: ha.string(), source_trace_id: ha.string().optional(), junctions: ha.array(ha.object({ x: ha.number(), y: ha.number() })), edges: ha.array(ha.object({ from: ha.object({ x: ha.number(), y: ha.number() }), to: ha.object({ x: ha.number(), y: ha.number() }), is_crossing: ha.boolean().optional(), from_schematic_port_id: ha.string().optional(), to_schematic_port_id: ha.string().optional() })), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() });
var Hd = ha.enum(["center", "left", "right", "top", "bottom"]);
var Gd = ha.object({ type: ha.literal("schematic_text"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), schematic_text_id: ha.string(), text: ha.string(), font_size: ha.number().default(0.18), position: ha.object({ x: Zl, y: Zl }), rotation: ha.number().default(0), anchor: ha.union([Hd.describe("legacy"), lh]).default("center"), color: ha.string().default("#000000"), subcircuit_id: ha.string().optional() });
var Ud = ha.object({ type: ha.literal("schematic_port"), schematic_port_id: ha.string(), source_port_id: ha.string(), schematic_component_id: ha.string().optional(), center: oh, facing_direction: ha.enum(["up", "down", "left", "right"]).optional(), distance_from_component_edge: ha.number().optional(), side_of_component: ha.enum(["top", "bottom", "left", "right"]).optional(), true_ccw_index: ha.number().optional(), pin_number: ha.number().optional(), display_pin_label: ha.string().optional(), subcircuit_id: ha.string().optional(), is_connected: ha.boolean().optional(), has_input_arrow: ha.boolean().optional(), has_output_arrow: ha.boolean().optional(), is_drawn_with_inversion_circle: ha.boolean().optional() }).describe("Defines a port on a schematic component");
var Zd = ha.object({ type: ha.literal("schematic_net_label"), schematic_net_label_id: ch("schematic_net_label"), schematic_trace_id: ha.string().optional(), source_trace_id: ha.string().optional(), source_net_id: ha.string(), center: oh, anchor_position: oh.optional(), anchor_side: ha.enum(["top", "bottom", "left", "right"]), text: ha.string(), symbol_name: ha.string().optional(), is_movable: ha.boolean().optional(), subcircuit_id: ha.string().optional() });
var qd = wh.extend({ type: ha.literal("schematic_error"), schematic_error_id: ha.string(), error_type: ha.literal("schematic_port_not_found").default("schematic_port_not_found"), subcircuit_id: ha.string().optional() }).describe("Defines a schematic error on the schematic");
var Jd = wh.extend({ type: ha.literal("schematic_layout_error"), schematic_layout_error_id: ch("schematic_layout_error"), error_type: ha.literal("schematic_layout_error").default("schematic_layout_error"), source_group_id: ha.string(), schematic_group_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Error emitted when schematic layout fails for a group");
var Qd = ha.object({ type: ha.literal("schematic_debug_object"), label: ha.string().optional(), subcircuit_id: ha.string().optional() });
var Kd = Qd.extend({ shape: ha.literal("rect"), center: oh, size: ah });
var eu = Qd.extend({ shape: ha.literal("line"), start: oh, end: oh });
var tu = Qd.extend({ shape: ha.literal("point"), center: oh });
var nu = ha.discriminatedUnion("shape", [Kd, eu, tu]);
var ou = ha.object({ type: ha.literal("schematic_voltage_probe"), schematic_voltage_probe_id: ha.string(), source_component_id: ha.string().optional(), name: ha.string().optional(), position: oh, schematic_trace_id: ha.string(), voltage: Hl.optional(), subcircuit_id: ha.string().optional(), color: ha.string().optional(), label_alignment: lh.optional() }).describe("Defines a voltage probe measurement point on a schematic trace");
var iu = ha.object({ type: ha.literal("schematic_manual_edit_conflict_warning"), schematic_manual_edit_conflict_warning_id: ch("schematic_manual_edit_conflict_warning"), warning_type: ha.literal("schematic_manual_edit_conflict_warning").default("schematic_manual_edit_conflict_warning"), message: ha.string(), schematic_component_id: ha.string(), schematic_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_component_id: ha.string() }).describe("Warning emitted when a component has both manual placement and explicit schX/schY coordinates");
var ru = ha.object({ type: ha.literal("schematic_group"), schematic_group_id: ch("schematic_group"), source_group_id: ha.string(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), width: Gl, height: Gl, center: oh, schematic_component_ids: ha.array(ha.string()), show_as_schematic_box: ha.boolean().optional(), name: ha.string().optional(), description: ha.string().optional() }).describe("Defines a group of components on the schematic");
var su = ha.object({ type: ha.literal("schematic_table"), schematic_table_id: ch("schematic_table"), anchor_position: oh, column_widths: ha.array(Zl), row_heights: ha.array(Zl), cell_padding: Zl.optional(), border_width: Zl.optional(), subcircuit_id: ha.string().optional(), schematic_component_id: ha.string().optional(), anchor: lh.optional() }).describe("Defines a table on the schematic");
var au = ha.object({ type: ha.literal("schematic_table_cell"), schematic_table_cell_id: ch("schematic_table_cell"), schematic_table_id: ha.string(), start_row_index: ha.number(), end_row_index: ha.number(), start_column_index: ha.number(), end_column_index: ha.number(), text: ha.string().optional(), center: oh, width: Zl, height: Zl, horizontal_align: ha.enum(["left", "center", "right"]).optional(), vertical_align: ha.enum(["top", "middle", "bottom"]).optional(), font_size: Zl.optional(), subcircuit_id: ha.string().optional() }).describe("Defines a cell within a schematic_table");
var cu = ha.object({ type: ha.literal("schematic_sheet"), schematic_sheet_id: ch("schematic_sheet"), name: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a schematic sheet or page that components can be placed on");
var lu = ha.object({ x: Zl, y: Zl, bulge: ha.number().optional() });
var hu = ha.object({ vertices: ha.array(lu) });
var du = ha.object({ outer_ring: hu, inner_rings: ha.array(hu).default([]) });
var uu = ha.object({ x: Zl, y: Zl, via: ha.boolean().optional(), via_to_layer: Cd.optional() });
var pu = ha.array(uu);
var mu = ha.object({ x: Zl, y: Zl, via: ha.boolean().optional(), to_layer: Cd.optional(), trace_width: Zl.optional() });
var gu = ha.object({ min_trace_width: Gl.optional(), min_board_edge_clearance: Gl.optional(), min_via_hole_edge_to_via_hole_edge_clearance: Gl.optional(), min_plated_hole_drill_edge_to_drill_edge_clearance: Gl.optional(), min_trace_to_pad_edge_clearance: Gl.optional(), min_pad_edge_to_pad_edge_clearance: Gl.optional(), min_same_net_trace_edge_to_trace_edge_clearance: Gl.optional(), min_different_net_trace_edge_to_trace_edge_clearance: Gl.optional(), min_via_hole_diameter: Gl.optional(), min_via_pad_diameter: Gl.optional() });
var fu = ha.object({ type: ha.literal("pcb_component"), pcb_component_id: ch("pcb_component"), source_component_id: ha.string(), center: oh, layer: Cd, rotation: th, display_offset_x: ha.string().optional().describe("How to display the x offset for this part, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this part, usually corresponding with how the user specified it"), width: Gl, height: Gl, do_not_place: ha.boolean().optional(), is_allowed_to_be_off_board: ha.boolean().optional(), subcircuit_id: ha.string().optional(), pcb_group_id: ha.string().optional(), position_mode: ha.enum(["packed", "relative_to_group_anchor", "relative_to_another_component", "none"]).optional(), anchor_position: oh.optional(), anchor_alignment: lh.optional(), positioned_relative_to_pcb_group_id: ha.string().optional(), positioned_relative_to_pcb_board_id: ha.string().optional(), cable_insertion_center: oh.optional(), insertion_direction: ha.enum(["from_above", "from_left", "from_right", "from_front", "from_back"]).optional(), metadata: ha.object({ kicad_footprint: xh.optional() }).optional(), obstructs_within_bounds: ha.boolean().default(true).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");
var _u = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: ch("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("circle"), hole_diameter: ha.number(), x: Zl, y: Zl, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var yu = _u.describe("Defines a circular hole on the PCB");
var bu = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: ch("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), x: Zl, y: Zl, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var xu = bu.describe("Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.");
var vu = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: ch("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.enum(["circle", "square"]), hole_diameter: ha.number(), x: Zl, y: Zl, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Iu = vu.describe("Defines a circular or square hole on the PCB");
var Su = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: ch("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("oval"), hole_width: ha.number(), hole_height: ha.number(), x: Zl, y: Zl, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Cu = Su.describe("Defines an oval hole on the PCB");
var Pu = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: ch("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("pill"), hole_width: ha.number(), hole_height: ha.number(), x: Zl, y: Zl, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Mu = Pu.describe("Defines a pill-shaped hole on the PCB");
var wu = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: ch("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("rotated_pill"), hole_width: ha.number(), hole_height: ha.number(), x: Zl, y: Zl, ccw_rotation: th, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Nu = wu.describe("Defines a rotated pill-shaped hole on the PCB");
var Tu = vu.or(Su).or(Pu).or(wu).or(_u).or(bu);
var Ru = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("circle"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), outer_diameter: ha.number(), hole_diameter: ha.number(), is_covered_with_solder_mask: ha.boolean().optional(), x: Zl, y: Zl, layers: ha.array(Cd), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: ch("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var Eu = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.enum(["oval", "pill"]), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), outer_width: ha.number(), outer_height: ha.number(), hole_width: ha.number(), hole_height: ha.number(), is_covered_with_solder_mask: ha.boolean().optional(), x: Zl, y: Zl, ccw_rotation: th, layers: ha.array(Cd), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: ch("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var Au = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("circular_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("circle"), pad_shape: ha.literal("rect"), hole_diameter: ha.number(), rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), hole_offset_x: Zl.default(0), hole_offset_y: Zl.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: Zl, y: Zl, layers: ha.array(Cd), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: ch("pcb_plated_hole"), soldermask_margin: ha.number().optional(), rect_ccw_rotation: th.optional() });
var Ou = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("pill_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("pill"), pad_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), hole_offset_x: Zl.default(0), hole_offset_y: Zl.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: Zl, y: Zl, layers: ha.array(Cd), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: ch("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var ku = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("rotated_pill_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("rotated_pill"), pad_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), hole_ccw_rotation: th, rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), rect_ccw_rotation: th, hole_offset_x: Zl.default(0), hole_offset_y: Zl.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: Zl, y: Zl, layers: ha.array(Cd), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: ch("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var Du = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("hole_with_polygon_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.enum(["circle", "oval", "pill", "rotated_pill"]), hole_diameter: ha.number().optional(), hole_width: ha.number().optional(), hole_height: ha.number().optional(), pad_outline: ha.array(ha.object({ x: Zl, y: Zl })).min(3), hole_offset_x: Zl.default(0), hole_offset_y: Zl.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: Zl, y: Zl, layers: ha.array(Cd), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: ch("pcb_plated_hole"), soldermask_margin: ha.number().optional(), ccw_rotation: th.optional() });
var Lu = ha.union([Ru, Eu, Au, Ou, ku, Du]);
var zu = ha.object({ type: ha.literal("pcb_port"), pcb_port_id: ch("pcb_port"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_port_id: ha.string(), pcb_component_id: ha.string().optional(), x: Zl, y: Zl, layers: ha.array(Cd), is_board_pinout: ha.boolean().optional() }).describe("Defines a port on the PCB");
var Bu = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("circle"), pcb_smtpad_id: ch("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, radius: ha.number(), layer: Cd, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Fu = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rect"), pcb_smtpad_id: ch("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), rect_border_radius: ha.number().optional(), corner_radius: ha.number().optional(), layer: Cd, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), soldermask_margin_left: ha.number().optional(), soldermask_margin_top: ha.number().optional(), soldermask_margin_right: ha.number().optional(), soldermask_margin_bottom: ha.number().optional() });
var ju = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rotated_rect"), pcb_smtpad_id: ch("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), rect_border_radius: ha.number().optional(), corner_radius: ha.number().optional(), ccw_rotation: th, layer: Cd, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), soldermask_margin_left: ha.number().optional(), soldermask_margin_top: ha.number().optional(), soldermask_margin_right: ha.number().optional(), soldermask_margin_bottom: ha.number().optional() });
var $u = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("pill"), pcb_smtpad_id: ch("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), radius: ha.number(), layer: Cd, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Yu = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rotated_pill"), pcb_smtpad_id: ch("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), radius: ha.number(), ccw_rotation: th, layer: Cd, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Xu = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("polygon"), pcb_smtpad_id: ch("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), points: ha.array(oh), layer: Cd, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var Wu = ha.discriminatedUnion("shape", [Bu, Fu, ju, Yu, $u, Xu]).describe("Defines an SMT pad on the PCB");
var Vu = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("circle"), pcb_solder_paste_id: ch("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, radius: ha.number(), layer: Cd, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Hu = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("rect"), pcb_solder_paste_id: ch("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), layer: Cd, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Gu = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("pill"), pcb_solder_paste_id: ch("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), radius: ha.number(), layer: Cd, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Uu = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("rotated_rect"), pcb_solder_paste_id: ch("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), ccw_rotation: Zl, layer: Cd, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Zu = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("oval"), pcb_solder_paste_id: ch("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: Zl, y: Zl, width: ha.number(), height: ha.number(), layer: Cd, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var qu = ha.union([Vu, Hu, Gu, Uu, Zu]).describe("Defines solderpaste on the PCB");
var Ju = ha.object({ type: ha.literal("pcb_text"), pcb_text_id: ch("pcb_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), text: ha.string(), center: oh, layer: Cd, width: Gl, height: Gl, lines: ha.number(), align: ha.enum(["bottom-left"]) }).describe("Defines text on the PCB");
var Qu = ha.object({ route_type: ha.literal("wire"), x: Zl, y: Zl, width: Zl, copper_pour_id: ha.string().optional(), is_inside_copper_pour: ha.boolean().optional(), start_pcb_port_id: ha.string().optional(), end_pcb_port_id: ha.string().optional(), layer: Cd });
var Ku = ha.object({ route_type: ha.literal("via"), x: Zl, y: Zl, copper_pour_id: ha.string().optional(), is_inside_copper_pour: ha.boolean().optional(), hole_diameter: Zl.optional(), outer_diameter: Zl.optional(), from_layer: Cd, to_layer: Cd });
var ep = ha.union([Qu, Ku]);
var tp = ha.object({ type: ha.literal("pcb_trace"), source_trace_id: ha.string().optional(), pcb_component_id: ha.string().optional(), pcb_trace_id: ch("pcb_trace"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), route_thickness_mode: ha.enum(["constant", "interpolated"]).default("constant").optional(), route_order_index: ha.number().optional(), should_round_corners: ha.boolean().optional(), trace_length: ha.number().optional(), highlight_color: ha.string().optional(), route: ha.array(ep) }).describe("Defines a trace on the PCB");
var np = ha.object({ type: ha.literal("pcb_trace_warning"), pcb_trace_warning_id: ch("pcb_trace_warning"), warning_type: ha.literal("pcb_trace_warning").default("pcb_trace_warning"), message: ha.string(), center: oh.optional(), pcb_trace_id: ha.string(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace warning on the PCB");
var op = wh.extend({ type: ha.literal("pcb_trace_error"), pcb_trace_error_id: ch("pcb_trace_error"), error_type: ha.literal("pcb_trace_error").default("pcb_trace_error"), center: oh.optional(), pcb_trace_id: ha.string(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace error on the PCB");
var ip = wh.extend({ type: ha.literal("pcb_trace_missing_error"), pcb_trace_missing_error_id: ch("pcb_trace_missing_error"), error_type: ha.literal("pcb_trace_missing_error").default("pcb_trace_missing_error"), center: oh.optional(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines an error when a source trace has no corresponding PCB trace");
var rp = wh.extend({ type: ha.literal("pcb_port_not_matched_error"), pcb_error_id: ch("pcb_error"), error_type: ha.literal("pcb_port_not_matched_error").default("pcb_port_not_matched_error"), pcb_component_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace error on the PCB where a port is not matched");
var sp = wh.extend({ type: ha.literal("pcb_port_not_connected_error"), pcb_port_not_connected_error_id: ch("pcb_port_not_connected_error"), error_type: ha.literal("pcb_port_not_connected_error").default("pcb_port_not_connected_error"), pcb_port_ids: ha.array(ha.string()), pcb_component_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines an error when a pcb port is not connected to any trace");
var ap = ha.object({ type: ha.literal("pcb_net"), pcb_net_id: ch("pcb_net"), source_net_id: ha.string().optional(), highlight_color: ha.string().optional() }).describe("Defines a net on the PCB");
var cp = ha.object({ type: ha.literal("pcb_via"), pcb_via_id: ch("pcb_via"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), x: Zl, y: Zl, outer_diameter: Zl.default("0.6mm"), hole_diameter: Zl.default("0.25mm"), from_layer: Cd.optional(), to_layer: Cd.optional(), layers: ha.array(Cd), pcb_trace_id: ha.string().optional(), net_is_assignable: ha.boolean().optional(), net_assigned: ha.boolean().optional(), is_tented: ha.boolean().optional() }).describe("Defines a via on the PCB");
var lp = ha.object({ type: ha.literal("pcb_board"), pcb_board_id: ch("pcb_board"), pcb_panel_id: ha.string().optional(), carrier_pcb_board_id: ha.string().optional(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), is_mounted_to_carrier_board: ha.boolean().optional(), width: Gl.optional(), height: Gl.optional(), center: oh, display_offset_x: ha.string().optional().describe("How to display the x offset for this board, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this board, usually corresponding with how the user specified it"), thickness: Gl.optional().default(1.4), num_layers: ha.number().optional().default(4), outline: ha.array(oh).optional(), shape: ha.enum(["rect", "polygon"]).optional(), material: ha.enum(["fr4", "fr1"]).default("fr4"), anchor_position: oh.optional(), anchor_alignment: lh.optional(), position_mode: ha.enum(["relative_to_panel_anchor", "none"]).optional() }).merge(gu).describe("Defines the board outline of the PCB");
var hp = ha.object({ type: ha.literal("pcb_panel"), pcb_panel_id: ch("pcb_panel"), width: Gl, height: Gl, center: oh, thickness: Gl.optional().default(1.4), covered_with_solder_mask: ha.boolean().optional().default(true) }).describe("Defines a PCB panel that can contain multiple boards");
var dp = wh.extend({ type: ha.literal("pcb_placement_error"), pcb_placement_error_id: ch("pcb_placement_error"), error_type: ha.literal("pcb_placement_error").default("pcb_placement_error"), subcircuit_id: ha.string().optional() }).describe("Defines a placement error on the PCB");
var up = wh.extend({ type: ha.literal("pcb_panelization_placement_error"), pcb_panelization_placement_error_id: ch("pcb_panelization_placement_error"), error_type: ha.literal("pcb_panelization_placement_error").default("pcb_panelization_placement_error"), pcb_panel_id: ha.string().optional(), pcb_board_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a panelization placement error on the PCB");
var pp = ha.object({ type: ha.literal("pcb_trace_hint"), pcb_trace_hint_id: ch("pcb_trace_hint"), pcb_port_id: ha.string(), pcb_component_id: ha.string(), route: ha.array(mu), subcircuit_id: ha.string().optional() }).describe("A hint that can be used during generation of a PCB trace");
var mp = ha.object({ type: ha.literal("pcb_silkscreen_line"), pcb_silkscreen_line_id: ch("pcb_silkscreen_line"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), stroke_width: Zl.default("0.1mm"), x1: Zl, y1: Zl, x2: Zl, y2: Zl, layer: Pd }).describe("Defines a silkscreen line on the PCB");
var gp = ha.object({ type: ha.literal("pcb_silkscreen_path"), pcb_silkscreen_path_id: ch("pcb_silkscreen_path"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Pd, route: ha.array(oh), stroke_width: Gl }).describe("Defines a silkscreen path on the PCB");
var fp = ha.object({ type: ha.literal("pcb_silkscreen_text"), pcb_silkscreen_text_id: ch("pcb_silkscreen_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: Zl.default("0.2mm"), pcb_component_id: ha.string(), text: ha.string(), is_knockout: ha.boolean().default(false).optional(), knockout_padding: ha.object({ left: Gl, top: Gl, bottom: Gl, right: Gl }).default({ left: "0.2mm", top: "0.2mm", bottom: "0.2mm", right: "0.2mm" }).optional(), ccw_rotation: ha.number().optional(), layer: Cd, is_mirrored: ha.boolean().default(false).optional(), anchor_position: oh.default({ x: 0, y: 0 }), anchor_alignment: lh.default("center") }).describe("Defines silkscreen text on the PCB");
var _p = ha.object({ type: ha.literal("pcb_copper_text"), pcb_copper_text_id: ch("pcb_copper_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: Zl.default("0.2mm"), pcb_component_id: ha.string(), text: ha.string(), is_knockout: ha.boolean().default(false).optional(), knockout_padding: ha.object({ left: Gl, top: Gl, bottom: Gl, right: Gl }).default({ left: "0.2mm", top: "0.2mm", bottom: "0.2mm", right: "0.2mm" }).optional(), ccw_rotation: ha.number().optional(), layer: Cd, is_mirrored: ha.boolean().default(false).optional(), anchor_position: oh.default({ x: 0, y: 0 }), anchor_alignment: lh.default("center") }).describe("Defines copper text on the PCB");
var yp = ha.object({ type: ha.literal("pcb_silkscreen_rect"), pcb_silkscreen_rect_id: ch("pcb_silkscreen_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, width: Gl, height: Gl, layer: Cd, stroke_width: Gl.default("1mm"), corner_radius: Gl.optional(), is_filled: ha.boolean().default(true).optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), ccw_rotation: ha.number().optional() }).describe("Defines a silkscreen rect on the PCB");
var bp = ha.object({ type: ha.literal("pcb_silkscreen_circle"), pcb_silkscreen_circle_id: ch("pcb_silkscreen_circle"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, radius: Gl, layer: Pd, stroke_width: Gl.default("1mm"), is_filled: ha.boolean().optional() }).describe("Defines a silkscreen circle on the PCB");
var xp = ha.object({ type: ha.literal("pcb_silkscreen_oval"), pcb_silkscreen_oval_id: ch("pcb_silkscreen_oval"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, radius_x: Zl, radius_y: Zl, layer: Pd, ccw_rotation: th.optional() }).describe("Defines a silkscreen oval on the PCB");
var vp = ha.object({ type: ha.literal("pcb_silkscreen_pill"), pcb_silkscreen_pill_id: ch("pcb_silkscreen_pill"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, width: Gl, height: Gl, layer: Cd, ccw_rotation: ha.number().optional() }).describe("Defines a silkscreen pill on the PCB");
var Ip = ha.object({ type: ha.literal("pcb_fabrication_note_text"), pcb_fabrication_note_text_id: ch("pcb_fabrication_note_text"), subcircuit_id: ha.string().optional(), pcb_group_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: Zl.default("1mm"), pcb_component_id: ha.string(), text: ha.string(), layer: Pd, anchor_position: oh.default({ x: 0, y: 0 }), anchor_alignment: ha.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center"), color: ha.string().optional() }).describe("Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators");
var Sp = ha.object({ type: ha.literal("pcb_fabrication_note_path"), pcb_fabrication_note_path_id: ch("pcb_fabrication_note_path"), pcb_component_id: ha.string(), subcircuit_id: ha.string().optional(), layer: Cd, route: ha.array(oh), stroke_width: Gl, color: ha.string().optional() }).describe("Defines a fabrication path on the PCB for fabricators or assemblers");
var Cp = ha.object({ type: ha.literal("pcb_fabrication_note_rect"), pcb_fabrication_note_rect_id: ch("pcb_fabrication_note_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, width: Gl, height: Gl, layer: Pd, stroke_width: Gl.default("0.1mm"), corner_radius: Gl.optional(), is_filled: ha.boolean().optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a fabrication note rectangle on the PCB");
var Pp = ha.object({ type: ha.literal("pcb_fabrication_note_dimension"), pcb_fabrication_note_dimension_id: ch("pcb_fabrication_note_dimension"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Pd, from: oh, to: oh, text: ha.string().optional(), text_ccw_rotation: ha.number().optional(), offset: Gl.optional(), offset_distance: Gl.optional(), offset_direction: ha.object({ x: ha.number(), y: ha.number() }).optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: Gl.default("1mm"), color: ha.string().optional(), arrow_size: Gl.default("1mm") }).describe("Defines a measurement annotation within PCB fabrication notes");
var Mp = ha.object({ type: ha.literal("pcb_note_text"), pcb_note_text_id: ch("pcb_note_text"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: Zl.default("1mm"), text: ha.string().optional(), anchor_position: oh.default({ x: 0, y: 0 }), anchor_alignment: ha.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center"), layer: Pd.default("top"), is_mirrored_from_top_view: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a documentation note in text on the PCB");
var wp = ha.object({ type: ha.literal("pcb_note_rect"), pcb_note_rect_id: ch("pcb_note_rect"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), center: oh, width: Gl, height: Gl, layer: Pd.default("top"), stroke_width: Gl.default("0.1mm"), corner_radius: Gl.optional(), is_filled: ha.boolean().optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a rectangular documentation note on the PCB");
var Np = ha.object({ type: ha.literal("pcb_note_path"), pcb_note_path_id: ch("pcb_note_path"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), route: ha.array(oh), layer: Pd.default("top"), stroke_width: Gl.default("0.1mm"), color: ha.string().optional() }).describe("Defines a polyline documentation note on the PCB");
var Tp = ha.object({ type: ha.literal("pcb_note_line"), pcb_note_line_id: ch("pcb_note_line"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), x1: Zl, y1: Zl, x2: Zl, y2: Zl, layer: Pd.default("top"), stroke_width: Zl.default("0.1mm"), color: ha.string().optional(), is_dashed: ha.boolean().optional() }).describe("Defines a straight documentation note line on the PCB");
var Rp = ha.object({ type: ha.literal("pcb_note_dimension"), pcb_note_dimension_id: ch("pcb_note_dimension"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), from: oh, to: oh, text: ha.string().optional(), text_ccw_rotation: ha.number().optional(), offset_distance: Gl.optional(), offset_direction: ha.object({ x: ha.number(), y: ha.number() }).optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: Gl.default("1mm"), layer: Pd.default("top"), color: ha.string().optional(), arrow_size: Gl.default("1mm") }).describe("Defines a measurement annotation within PCB documentation notes");
var Ep = wh.extend({ type: ha.literal("pcb_footprint_overlap_error"), pcb_error_id: ch("pcb_error"), error_type: ha.literal("pcb_footprint_overlap_error").default("pcb_footprint_overlap_error"), pcb_smtpad_ids: ha.array(ha.string()).optional(), pcb_plated_hole_ids: ha.array(ha.string()).optional(), pcb_hole_ids: ha.array(ha.string()).optional(), pcb_keepout_ids: ha.array(ha.string()).optional() }).describe("Error emitted when a pcb footprint overlaps with another element");
var Ap = wh.extend({ type: ha.literal("pcb_courtyard_overlap_error"), pcb_error_id: ch("pcb_error"), error_type: ha.literal("pcb_courtyard_overlap_error").default("pcb_courtyard_overlap_error"), pcb_component_ids: ha.tuple([ha.string(), ha.string()]) }).describe("Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another");
var Op = ha.object({ type: ha.literal("pcb_keepout"), shape: ha.literal("rect"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, width: Zl, height: Zl, pcb_keepout_id: ha.string(), layers: ha.array(ha.string()), description: ha.string().optional() }).or(ha.object({ type: ha.literal("pcb_keepout"), shape: ha.literal("circle"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, radius: Zl, pcb_keepout_id: ha.string(), layers: ha.array(ha.string()), description: ha.string().optional() }));
var kp = ha.object({ type: ha.literal("pcb_cutout"), pcb_cutout_id: ch("pcb_cutout"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_board_id: ha.string().optional(), pcb_panel_id: ha.string().optional() });
var Dp = kp.extend({ shape: ha.literal("rect"), center: oh, width: Gl, height: Gl, rotation: th.optional(), corner_radius: Gl.optional() });
var Lp = kp.extend({ shape: ha.literal("circle"), center: oh, radius: Gl });
var zp = kp.extend({ shape: ha.literal("polygon"), points: ha.array(oh) });
var Bp = kp.extend({ shape: ha.literal("path"), route: ha.array(oh), slot_width: Gl, slot_length: Gl.optional(), space_between_slots: Gl.optional(), slot_corner_radius: Gl.optional() });
var Fp = ha.discriminatedUnion("shape", [Dp, Lp, zp, Bp]).describe("Defines a cutout on the PCB, removing board material.");
var jp = wh.extend({ type: ha.literal("pcb_missing_footprint_error"), pcb_missing_footprint_error_id: ch("pcb_missing_footprint_error"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("pcb_missing_footprint_error").default("pcb_missing_footprint_error"), source_component_id: ha.string() }).describe("Defines a missing footprint error on the PCB");
var $p = wh.extend({ type: ha.literal("external_footprint_load_error"), external_footprint_load_error_id: ch("external_footprint_load_error"), pcb_component_id: ha.string(), source_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), footprinter_string: ha.string().optional(), error_type: ha.literal("external_footprint_load_error").default("external_footprint_load_error") }).describe("Defines an error when an external footprint fails to load");
var Yp = wh.extend({ type: ha.literal("circuit_json_footprint_load_error"), circuit_json_footprint_load_error_id: ch("circuit_json_footprint_load_error"), pcb_component_id: ha.string(), source_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("circuit_json_footprint_load_error").default("circuit_json_footprint_load_error"), circuit_json: ha.array(ha.any()).optional() }).describe("Defines an error when a circuit JSON footprint fails to load");
var Xp = ha.object({ type: ha.literal("pcb_group"), pcb_group_id: ch("pcb_group"), source_group_id: ha.string(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), width: Gl.optional(), height: Gl.optional(), center: oh, display_offset_x: ha.string().optional().describe("How to display the x offset for this group, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this group, usually corresponding with how the user specified it"), outline: ha.array(oh).optional(), anchor_position: oh.optional(), anchor_alignment: lh.default("center"), position_mode: ha.enum(["packed", "relative_to_group_anchor", "none"]).optional(), positioned_relative_to_pcb_group_id: ha.string().optional(), positioned_relative_to_pcb_board_id: ha.string().optional(), pcb_component_ids: ha.array(ha.string()), child_layout_mode: ha.enum(["packed", "none"]).optional(), name: ha.string().optional(), description: ha.string().optional(), layout_mode: ha.string().optional(), autorouter_configuration: ha.object({ trace_clearance: Gl }).optional(), autorouter_used_string: ha.string().optional() }).describe("Defines a group of components on the PCB");
var Wp = wh.extend({ type: ha.literal("pcb_autorouting_error"), pcb_error_id: ch("pcb_autorouting_error"), error_type: ha.literal("pcb_autorouting_error").default("pcb_autorouting_error"), subcircuit_id: ha.string().optional() }).describe("The autorouting has failed to route a portion of the board");
var Vp = ha.object({ type: ha.literal("pcb_manual_edit_conflict_warning"), pcb_manual_edit_conflict_warning_id: ch("pcb_manual_edit_conflict_warning"), warning_type: ha.literal("pcb_manual_edit_conflict_warning").default("pcb_manual_edit_conflict_warning"), message: ha.string(), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_component_id: ha.string() }).describe("Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates");
var Hp = ha.enum(["x-", "x+", "y+", "y-"]);
var Gp = ha.object({ type: ha.literal("pcb_connector_not_in_accessible_orientation_warning"), pcb_connector_not_in_accessible_orientation_warning_id: ch("pcb_connector_not_in_accessible_orientation_warning"), warning_type: ha.literal("pcb_connector_not_in_accessible_orientation_warning").default("pcb_connector_not_in_accessible_orientation_warning"), message: ha.string(), pcb_component_id: ha.string(), source_component_id: ha.string().optional(), pcb_board_id: ha.string().optional(), facing_direction: Hp, recommended_facing_direction: Hp, subcircuit_id: ha.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");
var Up = ha.object({ type: ha.literal("supplier_footprint_mismatch_warning"), supplier_footprint_mismatch_warning_id: ch("supplier_footprint_mismatch_warning"), warning_type: ha.literal("supplier_footprint_mismatch_warning").default("supplier_footprint_mismatch_warning"), message: ha.string(), source_component_id: ha.string(), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), supplier_name: Nh.optional(), supplier_part_number: ha.string().optional(), supplier_footprint_url: ha.string().optional(), footprint_copper_intersection_over_union: ha.number() }).describe("Warning emitted when a supplier part footprint does not match the expected footprint");
var Zp = ha.object({ type: ha.literal("pcb_breakout_point"), pcb_breakout_point_id: ch("pcb_breakout_point"), pcb_group_id: ha.string(), subcircuit_id: ha.string().optional(), source_trace_id: ha.string().optional(), source_port_id: ha.string().optional(), source_net_id: ha.string().optional(), x: Zl, y: Zl }).describe("Defines a routing target within a pcb_group for a source_trace or source_net");
var qp = ha.object({ type: ha.literal("pcb_ground_plane"), pcb_ground_plane_id: ch("pcb_ground_plane"), source_pcb_ground_plane_id: ha.string(), source_net_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a ground plane on the PCB");
var Jp = ha.object({ type: ha.literal("pcb_ground_plane_region"), pcb_ground_plane_region_id: ch("pcb_ground_plane_region"), pcb_ground_plane_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Cd, points: ha.array(oh) }).describe("Defines a polygon region of a ground plane");
var Qp = ha.object({ type: ha.literal("pcb_thermal_spoke"), pcb_thermal_spoke_id: ch("pcb_thermal_spoke"), pcb_ground_plane_id: ha.string(), shape: ha.string(), spoke_count: ha.number(), spoke_thickness: Zl, spoke_inner_diameter: Zl, spoke_outer_diameter: Zl, pcb_plated_hole_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Pattern for connecting a ground plane to a plated hole");
var Kp = ha.object({ type: ha.literal("pcb_copper_pour"), pcb_copper_pour_id: ch("pcb_copper_pour"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Cd, source_net_id: ha.string().optional(), covered_with_solder_mask: ha.boolean().optional().default(true) });
var em = Kp.extend({ shape: ha.literal("rect"), center: oh, width: Gl, height: Gl, rotation: th.optional() });
var tm = Kp.extend({ shape: ha.literal("brep"), brep_shape: du });
var nm = Kp.extend({ shape: ha.literal("polygon"), points: ha.array(oh) });
var om = ha.discriminatedUnion("shape", [em, tm, nm]).describe("Defines a copper pour on the PCB.");
var im = wh.extend({ type: ha.literal("pcb_component_outside_board_error"), pcb_component_outside_board_error_id: ch("pcb_component_outside_board_error"), error_type: ha.literal("pcb_component_outside_board_error").default("pcb_component_outside_board_error"), pcb_component_id: ha.string(), pcb_board_id: ha.string(), component_center: oh, component_bounds: ha.object({ min_x: ha.number(), max_x: ha.number(), min_y: ha.number(), max_y: ha.number() }), subcircuit_id: ha.string().optional(), source_component_id: ha.string().optional() }).describe("Error emitted when a PCB component is placed outside the board boundaries");
var rm = wh.extend({ type: ha.literal("pcb_component_not_on_board_edge_error"), pcb_component_not_on_board_edge_error_id: ch("pcb_component_not_on_board_edge_error"), error_type: ha.literal("pcb_component_not_on_board_edge_error").default("pcb_component_not_on_board_edge_error"), pcb_component_id: ha.string(), pcb_board_id: ha.string(), component_center: oh, pad_to_nearest_board_edge_distance: ha.number(), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a component that must be placed on the board edge is centered away from the edge");
var sm = wh.extend({ type: ha.literal("pcb_component_invalid_layer_error"), pcb_component_invalid_layer_error_id: ch("pcb_component_invalid_layer_error"), error_type: ha.literal("pcb_component_invalid_layer_error").default("pcb_component_invalid_layer_error"), pcb_component_id: ha.string().optional(), source_component_id: ha.string(), layer: Cd, subcircuit_id: ha.string().optional() }).describe("Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)");
var am = wh.extend({ type: ha.literal("pcb_via_clearance_error"), pcb_error_id: ch("pcb_error"), error_type: ha.literal("pcb_via_clearance_error").default("pcb_via_clearance_error"), pcb_via_ids: ha.array(ha.string()).min(2), minimum_clearance: Zl.optional(), actual_clearance: Zl.optional(), pcb_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when vias are closer than the allowed clearance");
var cm = wh.extend({ type: ha.literal("pcb_via_trace_clearance_error"), pcb_via_trace_clearance_error_id: ch("pcb_via_trace_clearance_error"), error_type: ha.literal("pcb_via_trace_clearance_error").default("pcb_via_trace_clearance_error"), pcb_via_id: ha.string(), pcb_trace_id: ha.string(), minimum_clearance: Zl.optional(), actual_clearance: Zl.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a via and trace are closer than the allowed clearance");
var lm = wh.extend({ type: ha.literal("pcb_pad_pad_clearance_error"), pcb_pad_pad_clearance_error_id: ch("pcb_pad_pad_clearance_error"), error_type: ha.literal("pcb_pad_pad_clearance_error").default("pcb_pad_pad_clearance_error"), pcb_pad_ids: ha.array(ha.string()).min(2), minimum_clearance: Zl.optional(), actual_clearance: Zl.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when pads are closer than the allowed clearance");
var hm = wh.extend({ type: ha.literal("pcb_pad_trace_clearance_error"), pcb_pad_trace_clearance_error_id: ch("pcb_pad_trace_clearance_error"), error_type: ha.literal("pcb_pad_trace_clearance_error").default("pcb_pad_trace_clearance_error"), pcb_pad_id: ha.string(), pcb_trace_id: ha.string(), minimum_clearance: Zl.optional(), actual_clearance: Zl.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a pad and trace are closer than allowed clearance");
var dm = ha.object({ type: ha.literal("pcb_courtyard_rect"), pcb_courtyard_rect_id: ch("pcb_courtyard_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, width: Gl, height: Gl, layer: Pd, ccw_rotation: th.optional(), color: ha.string().optional() }).describe("Defines a courtyard rectangle on the PCB");
var um = ha.object({ type: ha.literal("pcb_courtyard_outline"), pcb_courtyard_outline_id: ch("pcb_courtyard_outline"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Pd, outline: ha.array(oh).min(2) }).describe("Defines a courtyard outline on the PCB");
var pm = ha.object({ type: ha.literal("pcb_courtyard_polygon"), pcb_courtyard_polygon_id: ch("pcb_courtyard_polygon"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Pd, points: ha.array(oh).min(3), color: ha.string().optional() }).describe("Defines a courtyard polygon on the PCB");
var mm = ha.object({ type: ha.literal("pcb_courtyard_circle"), pcb_courtyard_circle_id: ch("pcb_courtyard_circle"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: oh, radius: Gl, layer: Pd, color: ha.string().optional() }).describe("Defines a courtyard circle on the PCB");
var gm = ["obj", "stl", "3mf", "gltf", "glb", "step", "wrl"];
var fm = ["x+", "x-", "y+", "y-", "z+", "z-"];
var _m = { obj: "z+", stl: "z+", "3mf": "z+", gltf: "y+", glb: "y+", step: "z+", wrl: "y+" };
var ym = ha.object({ type: ha.literal("cad_component"), cad_component_id: ha.string(), pcb_component_id: ha.string(), source_component_id: ha.string(), position: rh, rotation: rh.optional(), size: rh.optional(), layer: Cd.optional(), subcircuit_id: ha.string().optional(), footprinter_string: ha.string().optional(), model_obj_url: ha.string().optional(), model_stl_url: ha.string().optional(), model_3mf_url: ha.string().optional(), model_gltf_url: ha.string().optional(), model_glb_url: ha.string().optional(), model_step_url: ha.string().optional(), model_wrl_url: ha.string().optional(), model_asset: dh.optional(), model_unit_to_mm_scale_factor: ha.number().optional(), model_board_normal_direction: ha.enum(fm).optional().describe(`The direction in the model's coordinate space that is considered "up" or "coming out of the board surface"`), model_origin_position: rh.optional(), model_origin_alignment: ha.enum(["unknown", "center", "center_of_component_on_board_surface", "bottom_center_of_component"]).optional(), model_object_fit: ha.enum(["contain_within_bounds", "fill_bounds"]).optional().default("contain_within_bounds"), model_jscad: ha.any().optional(), show_as_translucent_model: ha.boolean().optional(), anchor_alignment: ha.enum(["center", "center_of_component_on_board_surface"]).optional().default("center") }).describe("Defines a component on the PCB");
var bm = ha.enum(["sinewave", "square", "triangle", "sawtooth"]);
var xm = ha.union([ha.string(), ha.number()]).transform((e19) => typeof e19 == "string" ? e19.endsWith("%") ? parseFloat(e19.slice(0, -1)) / 100 : parseFloat(e19) : e19).pipe(ha.number().min(0, "Duty cycle must be non-negative").max(1, "Duty cycle cannot be greater than 100%"));
var vm = ha.object({ type: ha.literal("simulation_voltage_source"), simulation_voltage_source_id: ch("simulation_voltage_source"), is_dc_source: ha.literal(true).optional().default(true), positive_source_port_id: ha.string().optional(), negative_source_port_id: ha.string().optional(), positive_source_net_id: ha.string().optional(), negative_source_net_id: ha.string().optional(), voltage: Hl }).describe("Defines a DC voltage source for simulation");
var Im = ha.object({ type: ha.literal("simulation_voltage_source"), simulation_voltage_source_id: ch("simulation_voltage_source"), is_dc_source: ha.literal(false), terminal1_source_port_id: ha.string().optional(), terminal2_source_port_id: ha.string().optional(), terminal1_source_net_id: ha.string().optional(), terminal2_source_net_id: ha.string().optional(), voltage: Hl.optional(), frequency: Ul.optional(), peak_to_peak_voltage: Hl.optional(), wave_shape: bm.optional(), phase: th.optional(), duty_cycle: xm.optional() }).describe("Defines an AC voltage source for simulation");
var Sm = ha.union([vm, Im]).describe("Defines a voltage source for simulation");
var Cm = ha.union([ha.string(), ha.number()]).transform((e19) => typeof e19 == "string" ? e19.endsWith("%") ? parseFloat(e19.slice(0, -1)) / 100 : parseFloat(e19) : e19).pipe(ha.number().min(0, "Duty cycle must be non-negative").max(1, "Duty cycle cannot be greater than 100%"));
var Pm = ha.object({ type: ha.literal("simulation_current_source"), simulation_current_source_id: ch("simulation_current_source"), is_dc_source: ha.literal(true).optional().default(true), positive_source_port_id: ha.string().optional(), negative_source_port_id: ha.string().optional(), positive_source_net_id: ha.string().optional(), negative_source_net_id: ha.string().optional(), current: ql }).describe("Defines a DC current source for simulation");
var Mm = ha.object({ type: ha.literal("simulation_current_source"), simulation_current_source_id: ch("simulation_current_source"), is_dc_source: ha.literal(false), terminal1_source_port_id: ha.string().optional(), terminal2_source_port_id: ha.string().optional(), terminal1_source_net_id: ha.string().optional(), terminal2_source_net_id: ha.string().optional(), current: ql.optional(), frequency: Ul.optional(), peak_to_peak_current: ql.optional(), wave_shape: bm.optional(), phase: th.optional(), duty_cycle: Cm.optional() }).describe("Defines an AC current source for simulation");
var wm = ha.union([Pm, Mm]).describe("Defines a current source for simulation");
var Nm = ha.union([ha.literal("spice_dc_sweep"), ha.literal("spice_dc_operating_point"), ha.literal("spice_transient_analysis"), ha.literal("spice_ac_analysis")]);
var Tm = ha.object({ type: ha.literal("simulation_experiment"), simulation_experiment_id: ch("simulation_experiment"), name: ha.string(), experiment_type: Nm, time_per_step: Jl.optional(), start_time_ms: Kl.optional(), end_time_ms: Kl.optional() }).describe("Defines a simulation experiment configuration");
var Rm = ha.object({ type: ha.literal("simulation_transient_voltage_graph"), simulation_transient_voltage_graph_id: ch("simulation_transient_voltage_graph"), simulation_experiment_id: ha.string(), timestamps_ms: ha.array(ha.number()).optional(), voltage_levels: ha.array(ha.number()), source_component_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), time_per_step: Jl, start_time_ms: Kl, end_time_ms: Kl, name: ha.string().optional(), color: ha.string().optional() }).describe("Stores voltage measurements over time for a simulation");
var Em = ha.object({ type: ha.literal("simulation_switch"), simulation_switch_id: ch("simulation_switch"), source_component_id: ha.string().optional(), closes_at: Kl.optional(), opens_at: Kl.optional(), starts_closed: ha.boolean().optional(), switching_frequency: Ul.optional() }).describe("Defines a switch for simulation timing control");
var Am = ha.object({ type: ha.literal("simulation_voltage_probe"), simulation_voltage_probe_id: ch("simulation_voltage_probe"), source_component_id: ha.string().optional(), name: ha.string().optional(), signal_input_source_port_id: ha.string().optional(), signal_input_source_net_id: ha.string().optional(), reference_input_source_port_id: ha.string().optional(), reference_input_source_net_id: ha.string().optional(), subcircuit_id: ha.string().optional(), color: ha.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((e19, t2) => {
if (e19.reference_input_source_port_id || e19.reference_input_source_net_id) {
const n2 = !!e19.signal_input_source_port_id || !!e19.reference_input_source_port_id, o2 = !!e19.signal_input_source_net_id || !!e19.reference_input_source_net_id;
n2 && o2 ? t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Cannot mix port and net connections in a differential probe." }) : n2 ? e19.signal_input_source_port_id && e19.reference_input_source_port_id || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id." }) : o2 && (e19.signal_input_source_net_id && e19.reference_input_source_net_id || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id." }));
} else
!!e19.signal_input_source_port_id == !!e19.signal_input_source_net_id && t2.addIssue({ code: ha.ZodIssueCode.custom, message: "A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id." });
});
var Om = wh.extend({ type: ha.literal("simulation_unknown_experiment_error"), simulation_unknown_experiment_error_id: ch("simulation_unknown_experiment_error"), error_type: ha.literal("simulation_unknown_experiment_error").default("simulation_unknown_experiment_error"), simulation_experiment_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("An unknown error occurred during the simulation experiment.");
var km = ha.object({ type: ha.literal("simulation_op_amp"), simulation_op_amp_id: ch("simulation_op_amp"), source_component_id: ha.string().optional(), inverting_input_source_port_id: ha.string(), non_inverting_input_source_port_id: ha.string(), output_source_port_id: ha.string(), positive_supply_source_port_id: ha.string(), negative_supply_source_port_id: ha.string() }).describe("Defines a simple ideal operational amplifier for simulation");
var Dm = ha.union([fd, md, gd, pd, yd, _d, Lh, Rh, Ah, kh, Eh, zh, $h, Yh, Hh, Uh, Zh, ed, qh, Jh, Qh, Kh, Wh, Xh, vd, Md, bd, td, id, rd, ad, cd, wd, Nd, Td, Rd, Ed, dd, xd, fu, Tu, jp, $p, Yp, Vp, Gp, Up, Lu, Op, zu, ap, Ju, tp, np, cp, Wu, qu, lp, hp, Xp, pp, mp, gp, fp, vp, _p, yp, bp, xp, op, ip, dp, up, rp, sp, am, cm, lm, hm, Sp, Ip, Cp, Pp, Mp, wp, Np, Tp, Rp, Wp, Ep, Ap, Zp, Fp, qp, Jp, Qp, om, im, rm, sm, dm, um, pm, mm, Ad, Gd, $d, Yd, Xd, Wd, Bd, jd, Ud, Vd, Od, qd, Jd, Zd, nu, ou, iu, ru, cu, su, au, ym, Sm, wm, Tm, Rm, Em, Am, Om, km]);
var Lm = Dm;
function zm(e19, t2, n2) {
if (!t2 || !n2)
return;
let o2 = e19.get(t2);
o2 || (o2 = new Set, e19.set(t2, o2)), o2.add(n2);
let i2 = e19.get(n2);
i2 || (i2 = new Set, e19.set(n2, i2)), i2.add(t2);
}
var Bm = (e19, t2 = {}) => {
const n2 = e19;
let o2 = n2._internal_store;
if (!o2) {
o2 = { counts: {}, editCount: 0 }, n2._internal_store = o2;
for (const e20 of n2) {
const t3 = e20.type, n3 = e20[`${t3}_id`];
if (!n3)
continue;
const i3 = Number.parseInt(n3.split("_").pop());
Number.isNaN(i3) || (o2.counts[t3] = Math.max(o2.counts[t3] ?? 0, i3));
}
}
const i2 = new Proxy({}, { get: (e20, r2) => {
if (r2 === "toArray")
return () => (n2.editCount = o2.editCount, n2);
if (r2 === "editCount")
return o2.editCount;
if (r2 === "subtree")
return (e21) => Bm(function(e22, t3) {
if (!t3.subcircuit_id && !t3.source_group_id)
return [...e22];
let n3 = t3;
if (t3.subcircuit_id) {
const o4 = new Set([t3.subcircuit_id]), i4 = new Map, r4 = new Map;
for (const t4 of e22)
if (t4.type === "source_group") {
const { source_group_id: e23, subcircuit_id: n4 } = t4;
n4 && r4.set(e23, n4);
const o5 = t4.parent_source_group_id;
o5 && (i4.has(o5) || i4.set(o5, []), i4.get(o5).push(e23));
}
let s4;
for (const [e23, n4] of r4)
if (n4 === t3.subcircuit_id) {
s4 = e23;
break;
}
if (s4) {
const e23 = (t4) => {
const n4 = i4.get(t4) || [];
for (const t5 of n4) {
const n5 = r4.get(t5);
n5 && o4.add(n5), e23(t5);
}
};
e23(s4), n3 = { ...t3, subcircuit_ids: Array.from(o4) };
}
}
const o3 = new Map;
for (const t4 of e22) {
const e23 = t4[`${t4.type}_id`];
typeof e23 == "string" && o3.set(e23, t4);
}
const i3 = new Map;
for (const t4 of e22) {
const e23 = Object.entries(t4);
for (const [n4, r4] of e23)
if (n4 !== "parent_source_group_id") {
if (n4.endsWith("_id") && typeof r4 == "string")
zm(i3, t4, o3.get(r4));
else if (n4.endsWith("_ids") && Array.isArray(r4))
for (const e24 of r4)
typeof e24 == "string" && zm(i3, t4, o3.get(e24));
}
}
const r3 = [], s3 = new Set;
for (const t4 of e22) {
let e23 = false;
(n3.subcircuit_id && ("subcircuit_id" in t4) && t4.subcircuit_id === n3.subcircuit_id || n3.subcircuit_ids && ("subcircuit_id" in t4) && t4.subcircuit_id && n3.subcircuit_ids.includes(t4.subcircuit_id) || n3.source_group_id && ("source_group_id" in t4) && t4.source_group_id === n3.source_group_id || n3.source_group_id && ("member_source_group_ids" in t4) && Array.isArray(t4.member_source_group_ids) && t4.member_source_group_ids.includes(n3.source_group_id)) && (e23 = true), e23 && (r3.push(t4), s3.add(t4));
}
for (;r3.length > 0; ) {
const e23 = r3.shift(), t4 = i3.get(e23);
if (t4)
for (const e24 of t4)
s3.has(e24) || (s3.add(e24), r3.push(e24));
}
return e22.filter((e23) => s3.has(e23));
}(n2, e21), t2);
if (r2 === "insert")
return (e21) => {
const i3 = e21.type;
if (!i3)
throw new Error("insert requires an element with a type");
o2.counts[i3] ??= -1, o2.counts[i3]++;
const r3 = o2.counts[i3], s3 = { ...e21, type: i3, [`${i3}_id`]: `${i3}_${r3}` };
if (t2.validateInserts) {
(sa[i3] ?? Lm).parse(s3);
}
return n2.push(s3), o2.editCount++, s3;
};
if (r2 === "insertAll")
return (e21) => e21.map((e22) => i2.insert(e22));
const s2 = r2;
return { get: (e21) => n2.find((t3) => t3.type === s2 && t3[`${s2}_id`] === e21), getUsing: (e21) => {
const t3 = Object.keys(e21);
if (t3.length !== 1)
throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");
const o3 = t3[0], i3 = o3.replace("_id", ""), r3 = n2.find((t4) => t4.type === i3 && t4[o3] === e21[o3]);
return r3 ? n2.find((e22) => e22.type === s2 && e22[`${s2}_id`] === r3[`${s2}_id`]) : null;
}, getWhere: (e21) => {
const t3 = Object.keys(e21);
return n2.find((n3) => n3.type === s2 && t3.every((t4) => n3[t4] === e21[t4]));
}, list: (e21) => {
const t3 = e21 ? Object.keys(e21) : [];
return n2.filter((n3) => n3.type === s2 && t3.every((t4) => n3[t4] === e21[t4]));
}, insert: (e21) => {
o2.counts[s2] ??= -1, o2.counts[s2]++;
const i3 = o2.counts[s2], r3 = { type: s2, [`${s2}_id`]: `${s2}_${i3}`, ...e21 };
if (t2.validateInserts) {
(sa[s2] ?? Lm).parse(r3);
}
return n2.push(r3), o2.editCount++, r3;
}, delete: (e21) => {
const t3 = n2.find((t4) => t4[`${s2}_id`] === e21);
t3 && (n2.splice(n2.indexOf(t3), 1), o2.editCount++);
}, update: (e21, t3) => {
const i3 = n2.find((t4) => t4.type === s2 && t4[`${s2}_id`] === e21);
return i3 ? (Object.assign(i3, t3), o2.editCount++, i3) : null;
}, select: (e21) => {
if (s2 === "source_component")
return n2.find((t3) => t3.type === "source_component" && t3.name === e21.replace(/\./g, ""));
if (s2 === "pcb_port" || s2 === "source_port" || s2 === "schematic_port") {
const [t3, o3] = e21.replace(/\./g, "").split(/[\s\>]+/), i3 = n2.find((e22) => e22.type === "source_component" && e22.name === t3);
if (!i3)
return null;
const r3 = n2.find((e22) => e22.type === "source_port" && e22.source_component_id === i3.source_component_id && (e22.name === o3 || (e22.port_hints ?? []).includes(o3)));
if (!r3)
return null;
if (s2 === "source_port")
return r3;
if (s2 === "pcb_port")
return n2.find((e22) => e22.type === "pcb_port" && e22.source_port_id === r3.source_port_id);
if (s2 === "schematic_port")
return n2.find((e22) => e22.type === "schematic_port" && e22.source_port_id === r3.source_port_id);
}
} };
} });
return i2;
};
function Fm(e19) {
const t2 = e19.type;
return `${t2}:${e19[`${t2}_id`]}`;
}
Bm.unparsed = Bm;
var jm = (e19, t2 = {}) => {
let n2 = e19._internal_store_indexed;
if (!n2) {
n2 = { counts: {}, editCount: 0, indexes: {} };
for (const t3 of e19) {
const e20 = t3.type, o3 = t3[`${e20}_id`];
if (!o3)
continue;
const i3 = Number.parseInt(o3.split("_").pop() || "");
Number.isNaN(i3) || (n2.counts[e20] = Math.max(n2.counts[e20] ?? 0, i3));
}
const o2 = t2.indexConfig || {}, i2 = n2.indexes;
if (o2.byId && (i2.byId = new Map), o2.byType && (i2.byType = new Map), o2.byRelation && (i2.byRelation = new Map), o2.bySubcircuit && (i2.bySubcircuit = new Map), o2.byCustomField && o2.byCustomField.length > 0) {
i2.byCustomField = new Map;
for (const e20 of o2.byCustomField)
i2.byCustomField.set(e20, new Map);
}
for (const t3 of e19) {
if (o2.byId) {
const e20 = Fm(t3);
i2.byId.set(e20, t3);
}
if (o2.byType) {
const e20 = i2.byType.get(t3.type) || [];
e20.push(t3), i2.byType.set(t3.type, e20);
}
if (o2.byRelation) {
const e20 = Object.entries(t3);
for (const [n3, o3] of e20)
if (n3.endsWith("_id") && n3 !== `${t3.type}_id` && typeof o3 == "string") {
const e21 = i2.byRelation.get(n3) || new Map, r2 = e21.get(o3) || [];
r2.push(t3), e21.set(o3, r2), i2.byRelation.set(n3, e21);
}
}
if (o2.bySubcircuit && "subcircuit_id" in t3) {
const e20 = t3.subcircuit_id;
if (e20 && typeof e20 == "string") {
const n3 = i2.bySubcircuit.get(e20) || [];
n3.push(t3), i2.bySubcircuit.set(e20, n3);
}
}
if (o2.byCustomField && i2.byCustomField) {
for (const e20 of o2.byCustomField)
if (e20 in t3) {
const n3 = t3[e20];
if (n3 !== undefined && (typeof n3 == "string" || typeof n3 == "number")) {
const o3 = String(n3), r2 = i2.byCustomField.get(e20), s2 = r2.get(o3) || [];
s2.push(t3), r2.set(o3, s2);
}
}
}
}
e19._internal_store_indexed = n2;
}
return new Proxy({}, { get: (o2, i2) => {
if (i2 === "toArray")
return () => (e19.editCount = n2.editCount, e19);
if (i2 === "editCount")
return n2.editCount;
const r2 = i2;
return { get: (o3) => {
const i3 = t2.indexConfig || {};
if (i3.byId && n2.indexes.byId)
return n2.indexes.byId.get(`${r2}:${o3}`) || null;
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e20) => e20[`${r2}_id`] === o3) || null;
}
return e19.find((e20) => e20.type === r2 && e20[`${r2}_id`] === o3) || null;
}, getUsing: (o3) => {
const i3 = t2.indexConfig || {}, s2 = Object.keys(o3);
if (s2.length !== 1)
throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");
const a2 = s2[0], c2 = a2.replace("_id", "");
if (i3.byRelation && n2.indexes.byRelation) {
const t3 = n2.indexes.byRelation.get(a2);
if (t3) {
const s3 = (t3.get(o3[a2]) || []).find((e20) => e20.type === c2);
if (!s3)
return null;
const l3 = s3[`${r2}_id`];
if (i3.byId && n2.indexes.byId)
return n2.indexes.byId.get(`${r2}:${l3}`) || null;
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e20) => e20[`${r2}_id`] === l3) || null;
}
return e19.find((e20) => e20.type === r2 && e20[`${r2}_id`] === l3) || null;
}
}
const l2 = e19.find((e20) => e20.type === c2 && e20[a2] === o3[a2]);
return l2 && e19.find((e20) => e20.type === r2 && e20[`${r2}_id`] === l2[`${r2}_id`]) || null;
}, getWhere: (o3) => {
const i3 = t2.indexConfig || {}, s2 = Object.keys(o3);
if (s2.length === 1 && i3.byCustomField && n2.indexes.byCustomField) {
const e20 = s2[0], t3 = n2.indexes.byCustomField.get(e20);
if (t3) {
const n3 = String(o3[e20]);
return (t3.get(n3) || []).find((e21) => e21.type === r2) || null;
}
}
if ("subcircuit_id" in o3 && i3.bySubcircuit && n2.indexes.bySubcircuit) {
const e20 = o3.subcircuit_id;
return (n2.indexes.bySubcircuit.get(e20) || []).find((e21) => e21.type === r2 && s2.every((t3) => e21[t3] === o3[t3])) || null;
}
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e20) => s2.every((t3) => e20[t3] === o3[t3])) || null;
}
return e19.find((e20) => e20.type === r2 && s2.every((t3) => e20[t3] === o3[t3])) || null;
}, list: (o3) => {
const i3 = t2.indexConfig || {}, s2 = o3 ? Object.keys(o3) : [];
if (s2.length === 0 && i3.byType && n2.indexes.byType)
return n2.indexes.byType.get(r2) || [];
if (s2.length === 1 && s2[0] === "subcircuit_id" && i3.bySubcircuit && n2.indexes.bySubcircuit) {
const e20 = o3.subcircuit_id;
return (n2.indexes.bySubcircuit.get(e20) || []).filter((e21) => e21.type === r2);
}
let a2;
return a2 = i3.byType && n2.indexes.byType ? n2.indexes.byType.get(r2) || [] : e19.filter((e20) => e20.type === r2), s2.length > 0 ? a2.filter((e20) => s2.every((t3) => e20[t3] === o3[t3])) : a2;
}, insert: (o3) => {
n2.counts[r2] ??= -1, n2.counts[r2]++;
const i3 = n2.counts[r2], s2 = { type: r2, [`${r2}_id`]: `${r2}_${i3}`, ...o3 };
if (t2.validateInserts) {
(sa[r2] ?? Lm).parse(s2);
}
e19.push(s2), n2.editCount++;
const a2 = t2.indexConfig || {};
if (a2.byId && n2.indexes.byId) {
const e20 = Fm(s2);
n2.indexes.byId.set(e20, s2);
}
if (a2.byType && n2.indexes.byType) {
const e20 = n2.indexes.byType.get(r2) || [];
e20.push(s2), n2.indexes.byType.set(r2, e20);
}
if (a2.byRelation && n2.indexes.byRelation) {
const e20 = Object.entries(s2);
for (const [t3, o4] of e20)
if (t3.endsWith("_id") && t3 !== `${s2.type}_id` && typeof o4 == "string") {
const e21 = n2.indexes.byRelation.get(t3) || new Map, i4 = e21.get(o4) || [];
i4.push(s2), e21.set(o4, i4), n2.indexes.byRelation.set(t3, e21);
}
}
if (a2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in s2) {
const e20 = s2.subcircuit_id;
if (e20 && typeof e20 == "string") {
const t3 = n2.indexes.bySubcircuit.get(e20) || [];
t3.push(s2), n2.indexes.bySubcircuit.set(e20, t3);
}
}
if (a2.byCustomField && n2.indexes.byCustomField) {
for (const e20 of a2.byCustomField)
if (e20 in s2) {
const t3 = s2[e20];
if (t3 !== undefined && (typeof t3 == "string" || typeof t3 == "number")) {
const o4 = String(t3), i4 = n2.indexes.byCustomField.get(e20), r3 = i4.get(o4) || [];
r3.push(s2), i4.set(o4, r3);
}
}
}
return s2;
}, delete: (o3) => {
const i3 = t2.indexConfig || {};
let s2;
if (i3.byId && n2.indexes.byId)
s2 = n2.indexes.byId.get(`${r2}:${o3}`);
else if (i3.byType && n2.indexes.byType) {
const e20 = n2.indexes.byType.get(r2) || [];
s2 = e20.find((e21) => e21[`${r2}_id`] === o3);
} else
s2 = e19.find((e20) => e20[`${r2}_id`] === o3);
if (!s2)
return;
const a2 = e19.indexOf(s2);
if (a2 >= 0 && (e19.splice(a2, 1), n2.editCount++), i3.byId && n2.indexes.byId) {
const e20 = Fm(s2);
n2.indexes.byId.delete(e20);
}
if (i3.byType && n2.indexes.byType) {
const e20 = (n2.indexes.byType.get(r2) || []).filter((e21) => e21[`${r2}_id`] !== o3);
n2.indexes.byType.set(r2, e20);
}
if (i3.byRelation && n2.indexes.byRelation)
for (const [e20, t3] of n2.indexes.byRelation.entries())
for (const [e21, n3] of t3.entries()) {
const o4 = n3.filter((e22) => e22 !== s2);
o4.length === 0 ? t3.delete(e21) : t3.set(e21, o4);
}
if (i3.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in s2) {
const e20 = s2.subcircuit_id;
if (e20) {
const t3 = (n2.indexes.bySubcircuit.get(e20) || []).filter((e21) => e21 !== s2);
t3.length === 0 ? n2.indexes.bySubcircuit.delete(e20) : n2.indexes.bySubcircuit.set(e20, t3);
}
}
if (i3.byCustomField && n2.indexes.byCustomField)
for (const e20 of n2.indexes.byCustomField.values())
for (const [t3, n3] of e20.entries()) {
const o4 = n3.filter((e21) => e21 !== s2);
o4.length === 0 ? e20.delete(t3) : e20.set(t3, o4);
}
}, update: (o3, i3) => {
const s2 = t2.indexConfig || {};
let a2;
if (s2.byId && n2.indexes.byId)
a2 = n2.indexes.byId.get(`${r2}:${o3}`);
else if (s2.byType && n2.indexes.byType) {
const e20 = n2.indexes.byType.get(r2) || [];
a2 = e20.find((e21) => e21[`${r2}_id`] === o3);
} else
a2 = e19.find((e20) => e20.type === r2 && e20[`${r2}_id`] === o3);
if (!a2)
return null;
if (s2.byRelation && n2.indexes.byRelation) {
const e20 = Object.entries(a2);
for (const [t3, o4] of e20)
if (t3.endsWith("_id") && t3 !== `${a2.type}_id` && typeof o4 == "string" && t3 in i3 && i3[t3] !== o4) {
const e21 = n2.indexes.byRelation.get(t3);
if (e21) {
const t4 = (e21.get(o4) || []).filter((e22) => e22 !== a2);
t4.length === 0 ? e21.delete(o4) : e21.set(o4, t4);
}
}
}
if (s2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in a2 && "subcircuit_id" in i3) {
const e20 = a2.subcircuit_id;
if (e20 !== i3.subcircuit_id) {
const t3 = (n2.indexes.bySubcircuit.get(e20) || []).filter((e21) => e21 !== a2);
t3.length === 0 ? n2.indexes.bySubcircuit.delete(e20) : n2.indexes.bySubcircuit.set(e20, t3);
}
}
if (s2.byCustomField && n2.indexes.byCustomField) {
for (const e20 of s2.byCustomField)
if (e20 in a2 && e20 in i3 && a2[e20] !== i3[e20]) {
const t3 = n2.indexes.byCustomField.get(e20);
if (t3) {
const n3 = String(a2[e20]), o4 = (t3.get(n3) || []).filter((e21) => e21 !== a2);
o4.length === 0 ? t3.delete(n3) : t3.set(n3, o4);
}
}
}
if (Object.assign(a2, i3), n2.editCount++, s2.byRelation && n2.indexes.byRelation) {
const e20 = Object.entries(a2);
for (const [t3, o4] of e20)
if (t3.endsWith("_id") && t3 !== `${a2.type}_id` && typeof o4 == "string" && t3 in i3) {
const e21 = n2.indexes.byRelation.get(t3) || new Map, i4 = e21.get(o4) || [];
i4.includes(a2) || (i4.push(a2), e21.set(o4, i4), n2.indexes.byRelation.set(t3, e21));
}
}
if (s2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in a2 && "subcircuit_id" in i3) {
const e20 = a2.subcircuit_id;
if (e20 && typeof e20 == "string") {
const t3 = n2.indexes.bySubcircuit.get(e20) || [];
t3.includes(a2) || (t3.push(a2), n2.indexes.bySubcircuit.set(e20, t3));
}
}
if (s2.byCustomField && n2.indexes.byCustomField) {
for (const e20 of s2.byCustomField)
if (e20 in a2 && e20 in i3) {
const t3 = a2[e20];
if (t3 !== undefined && (typeof t3 == "string" || typeof t3 == "number")) {
const o4 = String(t3), i4 = n2.indexes.byCustomField.get(e20), r3 = i4.get(o4) || [];
r3.includes(a2) || (r3.push(a2), i4.set(o4, r3));
}
}
}
return a2;
}, select: (t3) => {
if (r2 === "source_component")
return e19.find((e20) => e20.type === "source_component" && e20.name === t3.replace(/\./g, "")) || null;
if (r2 === "pcb_port" || r2 === "source_port" || r2 === "schematic_port") {
const [n3, o3] = t3.replace(/\./g, "").split(/[\s\>]+/), i3 = e19.find((e20) => e20.type === "source_component" && e20.name === n3);
if (!i3)
return null;
const s2 = e19.find((e20) => e20.type === "source_port" && e20.source_component_id === i3.source_component_id && (e20.name === o3 || (e20.port_hints ?? []).includes(o3)));
if (!s2)
return null;
if (r2 === "source_port")
return s2;
if (r2 === "pcb_port")
return e19.find((e20) => e20.type === "pcb_port" && e20.source_port_id === s2.source_port_id) || null;
if (r2 === "schematic_port")
return e19.find((e20) => e20.type === "schematic_port" && e20.source_port_id === s2.source_port_id) || null;
}
return null;
} };
} });
};
jm.unparsed = jm;
var $m = true;
var Ym = { CCW: -1, CW: 1, NOT_ORIENTABLE: 0 };
var Xm = 2 * Math.PI;
var Wm = Object.freeze({ __proto__: null, BOUNDARY: 2, CCW: $m, CONTAINS: 3, CW: false, END_VERTEX: 2, INSIDE: 1, INTERLACE: 4, NOT_VERTEX: 0, ORIENTATION: Ym, OUTSIDE: 0, OVERLAP_OPPOSITE: 2, OVERLAP_SAME: 1, PIx2: Xm, START_VERTEX: 1 });
var Vm = 0.000001;
function Hm(e19) {
Vm = e19;
}
function Gm() {
return Vm;
}
function Um(e19) {
return e19 < Vm && e19 > -Vm;
}
function Zm(e19, t2) {
return e19 - t2 < Vm && e19 - t2 > -Vm;
}
function qm(e19, t2) {
return e19 - t2 > Vm;
}
function Jm(e19, t2) {
return e19 - t2 < -Vm;
}
var Qm = { Utils: Object.freeze({ __proto__: null, DECIMALS: 3, EQ: Zm, EQ_0: Um, GE: function(e19, t2) {
return e19 - t2 > -Vm;
}, GT: qm, LE: function(e19, t2) {
return e19 - t2 < Vm;
}, LT: Jm, getTolerance: Gm, setTolerance: Hm }), Errors: undefined, Matrix: undefined, Planar_set: undefined, Point: undefined, Vector: undefined, Line: undefined, Circle: undefined, Segment: undefined, Arc: undefined, Box: undefined, Edge: undefined, Face: undefined, Ray: undefined, Ray_shooting: undefined, Multiline: undefined, Polygon: undefined, Distance: undefined, Inversion: undefined };
for (let e19 in Wm)
Qm[e19] = Wm[e19];
Object.defineProperty(Qm, "DP_TOL", { get: function() {
return Gm();
}, set: function(e19) {
Hm(e19);
} });
var Km = 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");
}
};
Qm.Errors = Km;
var eg = class {
constructor(e19, t2) {
this.first = e19, this.last = t2 || this.first;
}
[Symbol.iterator]() {
let e19;
return { next: () => (e19 = e19 ? e19.next : this.first, { value: e19, done: e19 === undefined }) };
}
get size() {
let e19 = 0;
for (let t2 of this)
e19++;
return e19;
}
toArray(e19 = undefined, t2 = undefined) {
let n2 = [], o2 = e19 || this.first, i2 = t2 || this.last, r2 = o2;
if (r2 === undefined)
return n2;
do {
n2.push(r2), r2 = r2.next;
} while (r2 !== i2.next);
return n2;
}
append(e19) {
return this.isEmpty() ? this.first = e19 : (e19.prev = this.last, this.last.next = e19), this.last = e19, this.last.next = undefined, this.first.prev = undefined, this;
}
insert(e19, t2) {
if (this.isEmpty())
this.first = e19, this.last = e19;
else if (t2 == null)
e19.next = this.first, this.first.prev = e19, this.first = e19;
else {
let n2 = t2.next;
t2.next = e19, n2 && (n2.prev = e19), e19.prev = t2, e19.next = n2, this.last === t2 && (this.last = e19);
}
return this.last.next = undefined, this.first.prev = undefined, this;
}
remove(e19) {
return e19 === this.first && e19 === this.last ? (this.first = undefined, this.last = undefined) : (e19.prev && (e19.prev.next = e19.next), e19.next && (e19.next.prev = e19.prev), e19 === this.first && (this.first = e19.next), e19 === this.last && (this.last = e19.prev)), this;
}
isEmpty() {
return this.first === undefined;
}
static testInfiniteLoop(e19) {
let t2 = e19, n2 = e19;
do {
if (t2 != e19 && t2 === n2)
throw Km.INFINITE_LOOP;
t2 = t2.next, n2 = n2.next.next;
} while (t2 != e19);
}
};
var tg = { stroke: "black" };
var ng = class {
constructor(e19 = tg) {
for (const t2 in e19)
this[t2] = e19[t2];
this.stroke = e19.stroke ?? tg.stroke;
}
toAttributesString() {
return Object.keys(this).reduce((e19, t2) => e19 + (this[t2] !== undefined ? this.toAttrString(t2, this[t2]) : ""), "");
}
toAttrString(e19, t2) {
const n2 = e19 === "className" ? "class" : this.convertCamelToKebabCase(e19);
return t2 === null ? `${n2} ` : `${n2}="${t2.toString()}" `;
}
convertCamelToKebabCase(e19) {
return e19.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 og(e19) {
return new ng(e19).toAttributesString();
}
function ig(e19, t2) {
let n2 = [], [o2, i2, r2] = e19.standard, [s2, a2, c2] = t2.standard, l2 = o2 * a2 - i2 * s2, h2 = r2 * a2 - i2 * c2, d2 = o2 * c2 - r2 * s2;
if (!Qm.Utils.EQ_0(l2)) {
let e20, t3;
i2 === 0 ? (e20 = r2 / o2, t3 = d2 / l2) : a2 === 0 ? (e20 = c2 / s2, t3 = d2 / l2) : o2 === 0 ? (e20 = h2 / l2, t3 = r2 / i2) : s2 === 0 ? (e20 = h2 / l2, t3 = c2 / a2) : (e20 = h2 / l2, t3 = d2 / l2), n2.push(new Qm.Point(e20, t3));
}
return n2;
}
function rg(e19, t2) {
let n2 = [], o2 = t2.pc.projectionOn(e19), i2 = t2.pc.distanceTo(o2)[0];
if (Qm.Utils.EQ(i2, t2.r))
n2.push(o2);
else if (Qm.Utils.LT(i2, t2.r)) {
let r2, s2, a2 = Math.sqrt(t2.r * t2.r - i2 * i2);
r2 = e19.norm.rotate90CCW().multiply(a2), s2 = o2.translate(r2), n2.push(s2), r2 = e19.norm.rotate90CW().multiply(a2), s2 = o2.translate(r2), n2.push(s2);
}
return n2;
}
function sg(e19, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = cg(o2, e19);
for (let e20 of t3)
wg(e20, n2) || n2.push(e20);
}
return n2;
}
function ag(e19, t2) {
let n2 = [];
if (sg(e19, t2.box).length === 0)
return n2;
let o2 = rg(e19, new Qm.Circle(t2.pc, t2.r));
for (let e20 of o2)
e20.on(t2) && n2.push(e20);
return n2;
}
function cg(e19, t2) {
let n2 = [];
return e19.ps.on(t2) && n2.push(e19.ps), e19.pe.on(t2) && !e19.isZeroLength() && n2.push(e19.pe), n2.length > 0 || e19.isZeroLength() || e19.ps.leftTo(t2) && e19.pe.leftTo(t2) || !e19.ps.leftTo(t2) && !e19.pe.leftTo(t2) ? n2 : ig(new Qm.Line(e19.ps, e19.pe), t2);
}
function lg(e19, t2) {
let n2 = [];
if (e19.isZeroLength())
return e19.ps.on(t2) && n2.push(e19.ps), n2;
if (t2.isZeroLength())
return t2.ps.on(e19) && n2.push(t2.ps), n2;
let o2 = new Qm.Line(e19.ps, e19.pe), i2 = new Qm.Line(t2.ps, t2.pe);
if (o2.incidentTo(i2))
e19.ps.on(t2) && n2.push(e19.ps), e19.pe.on(t2) && n2.push(e19.pe), !t2.ps.on(e19) || t2.ps.equalTo(e19.ps) || t2.ps.equalTo(e19.pe) || n2.push(t2.ps), !t2.pe.on(e19) || t2.pe.equalTo(e19.ps) || t2.pe.equalTo(e19.pe) || n2.push(t2.pe);
else if (o2.parallelTo(i2)) {
const o3 = new Qm.Vector(e19.ps, e19.pe), i3 = new Qm.Vector(t2.ps, t2.pe), r2 = new Qm.Vector(e19.ps, t2.ps), s2 = o3.cross(i3);
if (!Qm.Utils.EQ_0(s2)) {
const a2 = r2.cross(i3) / s2, c2 = r2.cross(o3) / s2;
Qm.Utils.GE(a2, 0) && Qm.Utils.LE(a2, 1) && Qm.Utils.GE(c2, 0) && Qm.Utils.LE(c2, 1) && n2.push(hg(e19.ps.translate(o3.multiply(a2)), e19, t2));
}
} else {
let r2 = ig(o2, i2);
r2.length > 0 && dg(r2[0], e19) && dg(r2[0], t2) && n2.push(hg(r2[0], e19, t2));
}
return n2;
}
function hg(e19, t2, n2) {
for (const o2 of [t2.ps, t2.pe, n2.ps, n2.pe])
if (e19.equalTo(o2))
return o2;
return e19;
}
function dg(e19, t2) {
const n2 = t2.box;
return Qm.Utils.LE(e19.x, n2.xmax) && Qm.Utils.GE(e19.x, n2.xmin) && Qm.Utils.LE(e19.y, n2.ymax) && Qm.Utils.GE(e19.y, n2.ymin);
}
function ug(e19, t2) {
let n2 = [];
if (e19.isZeroLength()) {
let [o3, i2] = e19.ps.distanceTo(t2.pc);
return Qm.Utils.EQ(o3, t2.r) && n2.push(e19.ps), n2;
}
let o2 = rg(new Qm.Line(e19.ps, e19.pe), t2);
for (let t3 of o2)
t3.on(e19) && n2.push(t3);
return n2;
}
function pg(e19, t2) {
let n2 = [];
if (e19.isZeroLength())
return e19.ps.on(t2) && n2.push(e19.ps), n2;
let o2 = rg(new Qm.Line(e19.ps, e19.pe), new Qm.Circle(t2.pc, t2.r));
for (let i2 of o2)
i2.on(e19) && i2.on(t2) && n2.push(i2);
return n2;
}
function mg(e19, t2) {
let n2 = [], o2 = new Qm.Vector(e19.pc, t2.pc), i2 = e19.r, r2 = t2.r;
if (Qm.Utils.EQ_0(i2) || Qm.Utils.EQ_0(r2))
return n2;
if (Qm.Utils.EQ_0(o2.x) && Qm.Utils.EQ_0(o2.y) && Qm.Utils.EQ(i2, r2))
return n2.push(e19.pc.translate(-i2, 0)), n2;
let s2, a2 = e19.pc.distanceTo(t2.pc)[0];
if (Qm.Utils.GT(a2, i2 + r2))
return n2;
if (Qm.Utils.LT(a2, Math.abs(i2 - r2)))
return n2;
if (o2.x /= a2, o2.y /= a2, Qm.Utils.EQ(a2, i2 + r2) || Qm.Utils.EQ(a2, Math.abs(i2 - r2)))
return s2 = e19.pc.translate(i2 * o2.x, i2 * o2.y), n2.push(s2), n2;
let c2 = i2 * i2 / (2 * a2) - r2 * r2 / (2 * a2) + a2 / 2, l2 = e19.pc.translate(c2 * o2.x, c2 * o2.y), h2 = Math.sqrt(i2 * i2 - c2 * c2);
return s2 = l2.translate(o2.rotate90CCW().multiply(h2)), n2.push(s2), s2 = l2.translate(o2.rotate90CW().multiply(h2)), n2.push(s2), n2;
}
function gg(e19, t2) {
let n2 = [];
if (e19.pc.equalTo(t2.pc) && Qm.Utils.EQ(e19.r, t2.r)) {
let o3;
return o3 = e19.start, o3.on(t2) && n2.push(o3), o3 = e19.end, o3.on(t2) && n2.push(o3), o3 = t2.start, o3.on(e19) && n2.push(o3), o3 = t2.end, o3.on(e19) && n2.push(o3), n2;
}
let o2 = new Qm.Circle(e19.pc, e19.r), i2 = new Qm.Circle(t2.pc, t2.r), r2 = o2.intersect(i2);
for (let o3 of r2)
o3.on(e19) && o3.on(t2) && n2.push(o3);
return n2;
}
function fg(e19, t2) {
let n2 = [];
if (t2.pc.equalTo(e19.pc) && Qm.Utils.EQ(t2.r, e19.r))
return n2.push(e19.start), n2.push(e19.end), n2;
let o2 = mg(t2, new Qm.Circle(e19.pc, e19.r));
for (let t3 of o2)
t3.on(e19) && n2.push(t3);
return n2;
}
function _g(e19, t2) {
return e19.isSegment ? lg(e19.shape, t2) : pg(t2, e19.shape);
}
function yg(e19, t2) {
return e19.isSegment ? pg(e19.shape, t2) : gg(e19.shape, t2);
}
function bg(e19, t2) {
return e19.isSegment ? cg(e19.shape, t2) : ag(t2, e19.shape);
}
function xg(e19, t2) {
return e19.isSegment ? ug(e19.shape, t2) : fg(e19.shape, t2);
}
function vg(e19, t2) {
let n2 = [];
for (let o2 of t2.edges)
for (let t3 of _g(o2, e19))
n2.push(t3);
return n2;
}
function Ig(e19, t2) {
let n2 = [];
for (let o2 of t2.edges)
for (let t3 of yg(o2, e19))
n2.push(t3);
return n2;
}
function Sg(e19, t2) {
let n2 = [];
if (t2.isEmpty())
return n2;
for (let o2 of t2.edges)
for (let t3 of bg(o2, e19))
wg(t3, n2) || n2.push(t3);
return e19.sortPoints(n2);
}
function Cg(e19, t2) {
let n2 = [];
if (t2.isEmpty())
return n2;
for (let o2 of t2.edges)
for (let t3 of xg(o2, e19))
n2.push(t3);
return n2;
}
function Pg(e19, t2) {
return e19.isSegment ? _g(t2, e19.shape) : e19.isArc ? yg(t2, e19.shape) : e19.isLine ? bg(t2, e19.shape) : e19.isRay ? (n2 = t2, o2 = e19.shape, n2.isSegment ? Tg(o2, n2.shape) : Rg(o2, n2.shape)) : [];
var n2, o2;
}
function Mg(e19, t2) {
let n2 = [];
if (t2.isEmpty() || e19.shape.box.not_intersect(t2.box))
return n2;
let o2 = t2.edges.search(e19.shape.box);
for (let t3 of o2)
n2 = [...n2, ...Pg(e19, t3)];
return n2;
}
function wg(e19, t2) {
return t2.some((t3) => t3.equalTo(e19));
}
function Ng(e19) {
return new Qm.Line(e19.start, e19.norm);
}
function Tg(e19, t2) {
return cg(t2, Ng(e19)).filter((t3) => e19.contains(t3));
}
function Rg(e19, t2) {
return ag(Ng(e19), t2).filter((t3) => e19.contains(t3));
}
function Eg(e19, t2) {
return rg(Ng(e19), t2).filter((t3) => e19.contains(t3));
}
function Ag(e19, t2) {
return ig(Ng(e19), t2).filter((t3) => e19.contains(t3));
}
function Og(e19, t2) {
return Sg(Ng(e19), t2).filter((t3) => e19.contains(t3));
}
function kg(e19, t2) {
if (e19.intersect && e19.intersect instanceof Function)
return e19.intersect(t2);
throw Km.UNSUPPORTED_SHAPE_TYPE;
}
function Dg(e19, t2) {
let n2 = [];
for (let o2 of t2)
n2 = [...n2, ...kg(e19, o2.shape)];
return n2;
}
var Lg = class e19 extends eg {
constructor(...e20) {
if (super(), this.isInfinite = false, e20.length === 1 && e20[0] instanceof Array && e20[0].length > 0) {
const t2 = e20[0], n2 = t2.length, o2 = (e21) => e21 instanceof Qm.Segment || e21 instanceof Qm.Arc || e21 instanceof Qm.Ray, i2 = (e21) => e21 instanceof Qm.Segment || e21 instanceof Qm.Arc;
if (!(n2 === 1 && ((e21) => e21 instanceof Qm.Segment || e21 instanceof Qm.Arc || e21 instanceof Qm.Ray || e21 instanceof Qm.Line)(t2[0]) || n2 > 1 && o2(t2[0]) && o2(t2[n2 - 1]) && t2.slice(1, n2 - 1).every(i2)))
throw Qm.Errors.ILLEGAL_PARAMETERS;
this.isInfinite = t2.some((e21) => e21 instanceof Qm.Ray || e21 instanceof Qm.Line);
for (let e21 of t2) {
let t3 = new Qm.Edge(e21);
this.append(t3);
}
this.setArcLength();
}
}
get edges() {
return [...this];
}
get box() {
return this.edges.reduce((e20, t2) => e20.merge(t2.box), new Qm.Box);
}
get vertices() {
let e20 = this.edges.map((e21) => e21.start);
return e20.push(this.last.end), e20;
}
get length() {
if (this.isEmpty())
return 0;
if (this.isInfinite)
return Number.POSITIVE_INFINITY;
let e20 = 0;
for (let t2 of this)
e20 += t2.length;
return e20;
}
clone() {
return new e19(this.toShapes());
}
setArcLength() {
for (let e20 of this)
this.setOneEdgeArcLength(e20);
}
setOneEdgeArcLength(e20) {
e20 === this.first ? e20.arc_length = 0 : e20.arc_length = e20.prev.arc_length + e20.prev.length;
}
pointAtLength(e20) {
if (e20 > this.length || e20 < 0)
return null;
if (this.isInfinite)
return null;
let t2 = null;
for (let n2 of this)
if (e20 >= n2.arc_length && (n2 === this.last || e20 < n2.next.arc_length)) {
t2 = n2.pointAtLength(e20 - n2.arc_length);
break;
}
return t2;
}
addVertex(e20, t2) {
let n2 = t2.shape.split(e20);
if (n2[0] === null)
return t2.prev;
if (n2[1] === null)
return t2;
let o2 = new Qm.Edge(n2[0]), i2 = t2.prev;
return this.insert(o2, i2), t2.shape = n2[1], o2;
}
getChain(e20, t2) {
let n2 = [];
for (let o2 = e20;o2 !== t2.next; o2 = o2.next)
n2.push(o2);
return n2;
}
split(e20) {
for (let t2 of e20) {
let e21 = this.findEdgeByPoint(t2);
this.addVertex(t2, e21);
}
return this;
}
findEdgeByPoint(e20) {
let t2;
for (let n2 of this)
if (n2.shape.contains(e20)) {
t2 = n2;
break;
}
return t2;
}
distanceTo(e20) {
if (e20 instanceof Qm.Point) {
const [t2, n2] = Qm.Distance.shape2multiline(e20, this);
return [t2, n2.reverse()];
}
if (e20 instanceof Qm.Line) {
const [t2, n2] = Qm.Distance.shape2multiline(e20, this);
return [t2, n2.reverse()];
}
if (e20 instanceof Qm.Circle) {
const [t2, n2] = Qm.Distance.shape2multiline(e20, this);
return [t2, n2.reverse()];
}
if (e20 instanceof Qm.Segment) {
const [t2, n2] = Qm.Distance.shape2multiline(e20, this);
return [t2, n2.reverse()];
}
if (e20 instanceof Qm.Arc) {
const [t2, n2] = Qm.Distance.shape2multiline(e20, this);
return [t2, n2.reverse()];
}
if (e20 instanceof Qm.Box) {
const [t2, n2] = Qm.Distance.shape2multiline(new Qm.Polygon(e20), this);
return [t2, n2.reverse()];
}
if (e20 instanceof Qm.Multiline)
return Qm.Distance.multiline2multiline(this, e20);
throw Qm.Errors.UNSUPPORTED_SHAPE_TYPE;
}
intersect(e20) {
return e20 instanceof Qm.Multiline ? function(e21, t2) {
let n2 = [];
for (let o2 of e21)
for (let e22 of t2)
n2 = [...n2, ...kg(o2.shape, e22.shape)];
return n2;
}(this, e20) : Dg(e20, this);
}
contains(e20) {
if (e20 instanceof Qm.Point)
return this.edges.some((t2) => t2.shape.contains(e20));
throw Qm.Errors.UNSUPPORTED_SHAPE_TYPE;
}
translate(t2) {
return new e19(this.edges.map((e20) => e20.shape.translate(t2)));
}
rotate(t2 = 0, n2 = new Qm.Point) {
return new e19(this.edges.map((e20) => e20.shape.rotate(t2, n2)));
}
transform(t2 = new Qm.Matrix) {
return new e19(this.edges.map((e20) => e20.shape.transform(t2)));
}
toShapes() {
return this.edges.map((e20) => e20.shape.clone());
}
toJSON() {
return this.edges.map((e20) => e20.toJSON());
}
svgPoints() {
return this.vertices.map((e20) => `${e20.x},${e20.y}`).join(" ");
}
dpath() {
let e20 = `M${this.first.start.x},${this.first.start.y}`;
for (let t2 of this)
e20 += t2.svg();
return e20;
}
svg(e20 = {}) {
let t2 = `
<path ${og({ fill: "none", ...e20 })} d="`;
t2 += `
M${this.first.start.x},${this.first.start.y}`;
for (let e21 of this)
t2 += e21.svg();
return t2 += `" >
</path>`, t2;
}
};
Qm.Multiline = Lg;
function zg(e20, t2, n2) {
let o2 = n2.length, i2 = e20.shape.split(t2);
if (i2.length === 0)
return;
let r2 = 0;
r2 = i2[0] === null ? 0 : i2[1] === null ? e20.shape.length : i2[0].length;
let s2, a2 = 0;
Zm(r2, 0) && (a2 |= 1), Zm(r2, e20.shape.length) && (a2 |= 2), s2 = r2 === 1 / 0 ? i2[0].coord(t2) : 2 & a2 && e20.next && e20.next.arc_length === 0 ? 0 : e20.arc_length + r2, n2.push({ id: o2, pt: t2, arc_length: s2, edge_before: e20, edge_after: undefined, face: e20.face, is_vertex: a2 });
}
function Bg(e20) {
e20.int_points1_sorted = Fg(e20.int_points1), e20.int_points2_sorted = Fg(e20.int_points2);
}
function Fg(e20) {
let t2 = new Map, n2 = 0;
for (let o2 of e20)
t2.has(o2.face) || (t2.set(o2.face, n2), n2++);
for (let n3 of e20)
n3.faceId = t2.get(n3.face);
return e20.slice().sort(jg);
}
function jg(e20, t2) {
return e20.faceId < t2.faceId ? -1 : e20.faceId > t2.faceId ? 1 : e20.arc_length < t2.arc_length ? -1 : e20.arc_length > t2.arc_length ? 1 : 0;
}
function $g(e20) {
if (e20.int_points1.length < 2)
return;
let t2, n2, o2, i2, r2 = false;
for (let s2 = 0;s2 < e20.int_points1_sorted.length; s2++)
if (e20.int_points1_sorted[s2].id !== -1) {
t2 = e20.int_points1_sorted[s2], n2 = e20.int_points2[t2.id];
for (let a2 = s2 + 1;a2 < e20.int_points1_sorted.length && (o2 = e20.int_points1_sorted[a2], Zm(o2.arc_length, t2.arc_length)); a2++)
o2.id !== -1 && (i2 = e20.int_points2[o2.id], i2.id !== -1 && o2.edge_before === t2.edge_before && o2.edge_after === t2.edge_after && i2.edge_before === n2.edge_before && i2.edge_after === n2.edge_after && (o2.id = -1, i2.id = -1, r2 = true));
}
n2 = e20.int_points2_sorted[0], t2 = e20.int_points1[n2.id];
for (let o3 = 1;o3 < e20.int_points2_sorted.length; o3++) {
let i3 = e20.int_points2_sorted[o3];
if (i3.id === -1)
continue;
if (n2.id === -1 || !Zm(i3.arc_length, n2.arc_length)) {
n2 = i3, t2 = e20.int_points1[n2.id];
continue;
}
let s2 = e20.int_points1[i3.id];
s2.edge_before === t2.edge_before && s2.edge_after === t2.edge_after && i3.edge_before === n2.edge_before && i3.edge_after === n2.edge_after && (s2.id = -1, i3.id = -1, r2 = true);
}
r2 && (e20.int_points1 = e20.int_points1.filter((e21) => e21.id >= 0), e20.int_points2 = e20.int_points2.filter((e21) => e21.id >= 0), e20.int_points1.forEach((e21, t3) => e21.id = t3), e20.int_points2.forEach((e21, t3) => e21.id = t3));
}
function Yg(e20) {
for (let t2 of e20)
t2.edge_before && (t2.edge_before.bvStart = undefined, t2.edge_before.bvEnd = undefined, t2.edge_before.bv = undefined, t2.edge_before.overlap = undefined), t2.edge_after && (t2.edge_after.bvStart = undefined, t2.edge_after.bvEnd = undefined, t2.edge_after.bv = undefined, t2.edge_after.overlap = undefined);
for (let t2 of e20)
t2.edge_before && (t2.edge_before.bvEnd = 2), t2.edge_after && (t2.edge_after.bvStart = 2);
}
function Xg(e20, t2) {
for (let n2 of e20)
n2.edge_before && n2.edge_before.setInclusion(t2), n2.edge_after && n2.edge_after.setInclusion(t2);
}
function Wg(e20, t2, n2) {
let o2, i2, r2 = 1;
if (e20.length === 1)
return 1;
o2 = e20[t2];
for (let s2 = t2 + 1;s2 < e20.length && o2.face === n2 && (i2 = e20[s2], i2.pt.equalTo(o2.pt) && i2.edge_before === o2.edge_before && i2.edge_after === o2.edge_after); s2++)
r2++;
return r2;
}
function Vg(e20, t2) {
if (t2) {
for (let n2 of t2) {
let t3 = n2.edge_before;
if (n2.is_vertex = 0, t3.shape.start && t3.shape.start.equalTo(n2.pt) && (n2.is_vertex |= 1), t3.shape.end && t3.shape.end.equalTo(n2.pt) && (n2.is_vertex |= 2), 1 & n2.is_vertex) {
n2.edge_before = t3.prev, t3.prev && (n2.is_vertex = 2);
continue;
}
if (2 & n2.is_vertex)
continue;
let o2 = e20.addVertex(n2.pt, t3);
n2.edge_before = o2;
}
for (let n2 of t2)
n2.edge_before ? n2.edge_after = n2.edge_before.next : e20 instanceof Lg && 1 & n2.is_vertex && (n2.edge_after = e20.first);
}
}
function Hg(e20, t2, n2) {
const o2 = e20.edge_before, i2 = t2.edge_after, r2 = n2.length;
o2.next = n2[0], n2[0].prev = o2, n2[r2 - 1].next = i2, i2.prev = n2[r2 - 1];
}
Qm.multiline = (...e20) => new Qm.Multiline(...e20);
var { INSIDE: Gg, OUTSIDE: Ug, BOUNDARY: Zg, OVERLAP_SAME: qg, OVERLAP_OPPOSITE: Jg } = Wm;
var { NOT_VERTEX: Qg, START_VERTEX: Kg, END_VERTEX: ef } = Wm;
function tf(e20, t2) {
let n2 = t2.clone().reverse(), [o2] = cf(e20, n2, 3, true);
return o2;
}
function nf(e20, t2) {
let [n2] = cf(e20, t2, 2, true);
return n2;
}
function of(e20, t2) {
let [n2, o2] = cf(e20, t2, 2, false), i2 = [];
for (let e21 of n2.faces)
i2 = [...i2, ...[...e21.edges].map((e22) => e22.shape)];
let r2 = [];
for (let e21 of o2.faces)
r2 = [...r2, ...[...e21.edges].map((e22) => e22.shape)];
return [i2, r2];
}
function rf(e20, t2) {
let [n2] = cf(e20, t2, 3, false), i2 = [];
for (let e21 of n2.faces)
i2 = [...i2, ...[...e21.edges].map((e22) => e22.shape)];
return i2;
}
function sf(e20, t2) {
let n2 = e20.clone(), o2 = t2.clone(), i2 = lf(n2, o2);
return Bg(i2), Vg(n2, i2.int_points1_sorted), Vg(o2, i2.int_points2_sorted), $g(i2), Bg(i2), [i2.int_points1_sorted.map((e21) => e21.pt), i2.int_points2_sorted.map((e21) => e21.pt)];
}
function af(e20, t2, n2, o2) {
let i2 = hf(e20, n2.int_points1), r2 = hf(t2, n2.int_points2);
for (df(i2, t2), df(r2, e20), Yg(n2.int_points1), Yg(n2.int_points2), Xg(n2.int_points1, t2), Xg(n2.int_points2, e20);uf(e20, t2, n2.int_points1, n2.int_points1_sorted, n2.int_points2, n2); )
;
((function(e21) {
let t3, n3, o3, i3 = e21.int_points1.length;
for (let r3 = 0;r3 < i3; r3++) {
let s2 = e21.int_points1_sorted[r3];
s2.face !== t3 && (n3 = r3, t3 = s2.face);
let a2, c2 = r3, l2 = Wg(e21.int_points1_sorted, r3, t3);
a2 = c2 + l2 < i3 && e21.int_points1_sorted[c2 + l2].face === t3 ? c2 + l2 : n3;
let h2 = Wg(e21.int_points1_sorted, a2, t3);
o3 = null;
for (let n4 = a2;n4 < a2 + h2; n4++) {
let i4 = e21.int_points1_sorted[n4];
if (i4.face === t3 && e21.int_points2[i4.id].face === e21.int_points2[s2.id].face) {
o3 = i4;
break;
}
}
if (o3 === null)
continue;
let d2 = s2.edge_after, u2 = o3.edge_before;
if (d2.bv !== 2 || u2.bv !== 2)
continue;
if (d2 !== u2)
continue;
let p2 = e21.int_points2[s2.id], m2 = e21.int_points2[o3.id], g2 = p2.edge_after, f2 = m2.edge_before;
g2.bv === 2 && f2.bv === 2 && g2 === f2 || (p2 = e21.int_points2[o3.id], m2 = e21.int_points2[s2.id], g2 = p2.edge_after, f2 = m2.edge_before), g2.bv === 2 && f2.bv === 2 && g2 === f2 && d2.setOverlap(g2);
}
}))(n2), pf(e20, o2, n2.int_points1_sorted, true), pf(t2, o2, n2.int_points2_sorted, false), ff(e20, i2, o2, true), ff(t2, r2, o2, false);
}
function cf(e20, t2, n2, o2) {
let i2 = e20.clone(), r2 = t2.clone(), s2 = lf(i2, r2);
return Bg(s2), Vg(i2, s2.int_points1_sorted), Vg(r2, s2.int_points2_sorted), $g(s2), Bg(s2), af(i2, r2, s2, n2), o2 && function(e21, t3, n3) {
((function(e22, t4, n4, o3) {
for (let n5 of t4.faces) {
for (let t5 of n5)
e22.edges.add(t5);
o3.find((e23) => e23.face === n5) === undefined && e22.addFace(n5.first, n5.last);
}
}))(e21, t3, 0, n3.int_points2), function(e22, t4, n4) {
if (n4.int_points1.length !== 0)
for (let e23 = 0;e23 < n4.int_points1.length; e23++) {
let t5 = n4.int_points1[e23], o3 = n4.int_points2[e23];
if (t5.edge_before !== undefined && t5.edge_after === undefined && o3.edge_before === undefined && o3.edge_after !== undefined && (t5.edge_before.next = o3.edge_after, o3.edge_after.prev = t5.edge_before, t5.edge_after = o3.edge_after, o3.edge_before = t5.edge_before), o3.edge_before !== undefined && o3.edge_after === undefined && t5.edge_before === undefined && t5.edge_after !== undefined && (o3.edge_before.next = t5.edge_after, t5.edge_after.prev = o3.edge_before, o3.edge_after = t5.edge_after, t5.edge_before = o3.edge_before), t5.edge_before !== undefined && t5.edge_after === undefined)
for (let e24 of n4.int_points1_sorted)
e24 !== t5 && e24.edge_before === undefined && e24.edge_after !== undefined && e24.pt.equalTo(t5.pt) && (t5.edge_before.next = e24.edge_after, e24.edge_after.prev = t5.edge_before, t5.edge_after = e24.edge_after, e24.edge_before = t5.edge_before);
if (o3.edge_before !== undefined && o3.edge_after === undefined)
for (let e24 of n4.int_points2_sorted)
e24 !== o3 && e24.edge_before === undefined && e24.edge_after !== undefined && e24.pt.equalTo(o3.pt) && (o3.edge_before.next = e24.edge_after, e24.edge_after.prev = o3.edge_before, o3.edge_after = e24.edge_after, e24.edge_before = o3.edge_before);
}
}(0, 0, n3), mf(e21, n3.int_points1), mf(t3, n3.int_points2), gf(e21, n3.int_points1, n3.int_points2), gf(e21, n3.int_points2, n3.int_points1), _f(e21), _f(t3);
}(i2, r2, s2), [i2, r2];
}
function lf(e20, t2) {
let n2 = { int_points1: [], int_points2: [] };
for (let o2 of e20.edges) {
let e21 = t2.edges.search(o2.box);
for (let t3 of e21) {
let e22 = o2.shape.intersect(t3.shape);
for (let i2 of e22)
zg(o2, i2, n2.int_points1), zg(t3, i2, n2.int_points2);
}
}
return n2;
}
function hf(e20, t2) {
let n2 = [];
for (let o2 of e20.faces)
t2.find((e21) => e21.face === o2) || n2.push(o2);
return n2;
}
function df(e20, t2) {
for (let n2 of e20)
n2.first.bv = n2.first.bvStart = n2.first.bvEnd = undefined, n2.first.setInclusion(t2);
}
function uf(e20, t2, n2, o2, i2, r2) {
let s2, a2, c2, l2 = o2.length, h2 = false;
for (let d2 = 0;d2 < l2; d2++) {
let u2 = o2[d2];
u2.face !== s2 && (a2 = d2, s2 = u2.face);
let p2, m2 = d2, g2 = Wg(o2, d2, s2);
p2 = m2 + g2 < l2 && o2[m2 + g2].face === s2 ? m2 + g2 : a2;
let f2 = Wg(o2, p2, s2);
c2 = null;
for (let e21 = p2;e21 < p2 + f2; e21++) {
let t3 = o2[e21];
if (t3.face === s2 && i2[t3.id].face === i2[u2.id].face) {
c2 = t3;
break;
}
}
if (c2 === null)
continue;
let _2 = u2.edge_after, y2 = c2.edge_before;
if (_2.bv !== Zg || y2.bv == Zg)
if (_2.bv == Zg || y2.bv !== Zg) {
if (_2.bv === Zg && y2.bv === Zg && _2 != y2 || _2.bv === Gg && y2.bv === Ug || _2.bv === Ug && y2.bv === Gg) {
let e21 = _2.next;
for (;e21 != y2; )
e21.bvStart = undefined, e21.bvEnd = undefined, e21.bv = undefined, e21.setInclusion(t2), e21 = e21.next;
}
if (_2.bv === Zg && y2.bv === Zg && _2 != y2) {
let e21, t3 = _2.next;
for (;t3 != y2; ) {
if (t3.bv != Zg) {
if (e21 === undefined)
e21 = t3.bv;
else if (t3.bv != e21)
throw Km.UNRESOLVED_BOUNDARY_CONFLICT;
}
t3 = t3.next;
}
e21 != null && (_2.bv = e21, y2.bv = e21);
continue;
}
if (_2.bv === Gg && y2.bv === Ug || _2.bv === Ug && y2.bv === Gg) {
let o3 = _2;
for (;o3 != y2; ) {
if (o3.bvStart === _2.bv && o3.bvEnd === y2.bv) {
let [s3, a3] = o3.shape.distanceTo(t2);
if (s3 < 10 * Qm.DP_TOL) {
zg(o3, a3.ps, n2);
let s4 = n2[n2.length - 1];
if (s4.is_vertex & Kg)
s4.edge_after = o3, s4.edge_before = o3.prev, o3.bvStart = Zg, o3.bv = undefined, o3.setInclusion(t2);
else if (s4.is_vertex & ef)
s4.edge_after = o3.next, o3.bvEnd = Zg, o3.bv = undefined, o3.setInclusion(t2);
else {
let e21 = t2.addVertex(s4.pt, o3);
s4.edge_before = e21, s4.edge_after = e21.next, e21.setInclusion(t2), e21.next.bvStart = Zg, e21.next.bvEnd = undefined, e21.next.bv = undefined, e21.next.setInclusion(t2);
}
let c3 = t2.findEdgeByPoint(a3.pe);
zg(c3, a3.pe, i2);
let l3 = i2[i2.length - 1];
if (l3.is_vertex & Kg)
l3.edge_after = c3, l3.edge_before = c3.prev;
else if (l3.is_vertex & ef)
l3.edge_after = c3.next;
else {
let n3 = i2.find((e21) => e21.edge_after === c3), o4 = t2.addVertex(l3.pt, c3);
l3.edge_before = o4, l3.edge_after = o4.next, n3 && (n3.edge_after = o4), o4.bvStart = undefined, o4.bvEnd = Zg, o4.bv = undefined, o4.setInclusion(e20), o4.next.bvStart = Zg, o4.next.bvEnd = undefined, o4.next.bv = undefined, o4.next.setInclusion(e20);
}
Bg(r2), h2 = true;
break;
}
}
o3 = o3.next;
}
if (h2)
break;
throw Km.UNRESOLVED_BOUNDARY_CONFLICT;
}
} else
y2.bv = _2.bv;
else
_2.bv = y2.bv;
}
return h2;
}
function pf(e20, t2, n2, o2) {
if (!n2)
return;
let i2, r2, s2, a2;
for (let c2 = 0;c2 < n2.length; c2++) {
if (s2 = n2[c2], s2.face !== i2 && (r2 = c2, i2 = s2.face), i2.isEmpty())
continue;
let l2, h2 = c2, d2 = Wg(n2, c2, i2);
l2 = h2 + d2 < n2.length && n2[h2 + d2].face === s2.face ? h2 + d2 : r2, a2 = n2[l2];
let u2 = l2, p2 = Wg(n2, u2, i2), m2 = s2.edge_after, g2 = a2.edge_before;
if (m2.bv === Gg && g2.bv === Gg && t2 === 1 || m2.bv === Ug && g2.bv === Ug && t2 === 2 || (m2.bv === Ug || g2.bv === Ug) && t2 === 3 && !o2 || (m2.bv === Gg || g2.bv === Gg) && t2 === 3 && o2 || m2.bv === Zg && g2.bv === Zg && m2.overlap & qg && o2 || m2.bv === Zg && g2.bv === Zg && m2.overlap & Jg) {
e20.removeChain(i2, m2, g2);
for (let e21 = h2;e21 < h2 + d2; e21++)
n2[e21].edge_after = undefined;
for (let e21 = u2;e21 < u2 + p2; e21++)
n2[e21].edge_before = undefined;
}
c2 += d2 - 1;
}
}
function mf(e20, t2) {
for (let n2 of t2)
e20.faces.delete(n2.face), n2.face = undefined, n2.edge_before && (n2.edge_before.face = undefined), n2.edge_after && (n2.edge_after.face = undefined);
}
function gf(e20, t2, n2) {
for (let o2 of t2) {
if (o2.edge_before === undefined || o2.edge_after === undefined)
continue;
if (o2.face)
continue;
if (o2.edge_after.face || o2.edge_before.face)
continue;
let { edge_after: i2, edge_before: r2 } = o2;
try {
eg.testInfiniteLoop(i2);
} catch (e21) {
throw Km.CANNOT_COMPLETE_BOOLEAN_OPERATION;
}
let s2 = e20.addFace(i2, r2);
for (let e21 of t2)
e21.edge_before && e21.edge_after && e21.edge_before.face === s2 && e21.edge_after.face === s2 && (e21.face = s2);
for (let e21 of n2)
e21.edge_before && e21.edge_after && e21.edge_before.face === s2 && e21.edge_after.face === s2 && (e21.face = s2);
}
}
function ff(e20, t2, n2, o2) {
for (let i2 of t2) {
let t3 = i2.first.bv;
(n2 === 1 && t3 === Gg || n2 === 3 && t3 === Gg && o2 || n2 === 3 && t3 === Ug && !o2 || n2 === 2 && t3 === Ug) && e20.deleteFace(i2);
}
}
function _f(e20) {
const t2 = [];
for (const n2 of e20.edges)
n2.face && e20.faces.has(n2.face) || t2.push(n2);
for (const n2 of t2)
e20.edges.delete(n2);
}
var yf = Object.freeze({ __proto__: null, BOOLEAN_INTERSECT: 2, BOOLEAN_SUBTRACT: 3, BOOLEAN_UNION: 1, calculateIntersections: sf, innerClip: of, intersect: nf, outerClip: rf, removeNotRelevantChains: pf, removeOldFaces: mf, restoreFaces: gf, subtract: tf, unify: function(e20, t2) {
let [n2] = cf(e20, t2, 1, true);
return n2;
} });
var bf = RegExp("T.F..FFF.|T.F...F..");
var xf = RegExp("T........|.T.......|...T.....|....T....");
var vf = RegExp("FT.......|F..T.....|F...T....");
var If = RegExp("T.F..F...");
var Sf = RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF...");
var Cf = class {
constructor() {
this.m = new Array(9).fill(undefined);
}
get I2I() {
return this.m[0];
}
set I2I(e20) {
this.m[0] = e20;
}
get I2B() {
return this.m[1];
}
set I2B(e20) {
this.m[1] = e20;
}
get I2E() {
return this.m[2];
}
set I2E(e20) {
this.m[2] = e20;
}
get B2I() {
return this.m[3];
}
set B2I(e20) {
this.m[3] = e20;
}
get B2B() {
return this.m[4];
}
set B2B(e20) {
this.m[4] = e20;
}
get B2E() {
return this.m[5];
}
set B2E(e20) {
this.m[5] = e20;
}
get E2I() {
return this.m[6];
}
set E2I(e20) {
this.m[6] = e20;
}
get E2B() {
return this.m[7];
}
set E2B(e20) {
this.m[7] = e20;
}
get E2E() {
return this.m[8];
}
set E2E(e20) {
this.m[8] = e20;
}
toString() {
return this.m.map((e20) => e20 instanceof Array && e20.length > 0 ? "T" : e20 instanceof Array && e20.length === 0 ? "F" : "*").join("");
}
equal() {
return bf.test(this.toString());
}
intersect() {
return xf.test(this.toString());
}
touch() {
return vf.test(this.toString());
}
inside() {
return If.test(this.toString());
}
covered() {
return Sf.test(this.toString());
}
};
function Pf(e20, t2) {
let n2, o2 = new Qm.Ray(t2), i2 = new Qm.Line(o2.pt, o2.norm);
const r2 = new Qm.Box(o2.box.xmin - Qm.DP_TOL, o2.box.ymin - Qm.DP_TOL, o2.box.xmax + Qm.DP_TOL, o2.box.ymax + Qm.DP_TOL);
if (e20.box.not_intersect(r2))
return Qm.OUTSIDE;
let s2 = e20.edges.search(r2);
if (s2.length === 0)
return Qm.OUTSIDE;
for (let e21 of s2)
if (e21.shape.contains(t2))
return Qm.BOUNDARY;
let a2 = [...e20.faces], c2 = [];
for (let e21 of s2)
for (let n3 of o2.intersect(e21.shape)) {
if (n3.equalTo(t2))
return Qm.BOUNDARY;
c2.push({ pt: n3, edge: e21, face_index: a2.indexOf(e21.face) });
}
c2.sort((e21, t3) => Jm(e21.pt.x, t3.pt.x) ? -1 : qm(e21.pt.x, t3.pt.x) ? 1 : e21.face_index < t3.face_index ? -1 : e21.face_index > t3.face_index ? 1 : e21.edge.arc_length < t3.edge.arc_length ? -1 : e21.edge.arc_length > t3.edge.arc_length ? 1 : 0);
let l2 = 0;
for (let e21 = 0;e21 < c2.length; e21++) {
let t3 = c2[e21];
if (t3.pt.equalTo(t3.edge.shape.start)) {
if (e21 > 0 && t3.pt.equalTo(c2[e21 - 1].pt) && t3.face_index === c2[e21 - 1].face_index && t3.edge.prev === c2[e21 - 1].edge)
continue;
let n3 = t3.edge.prev;
for (;Um(n3.length); )
n3 = n3.prev;
let o3 = n3.shape.tangentInEnd(), r3 = t3.pt.translate(o3), s3 = t3.edge.shape.tangentInStart(), a3 = t3.pt.translate(s3), h2 = r3.leftTo(i2), d2 = a3.leftTo(i2);
(h2 && !d2 || !h2 && d2) && l2++;
} else if (t3.pt.equalTo(t3.edge.shape.end)) {
if (e21 > 0 && t3.pt.equalTo(c2[e21 - 1].pt) && t3.face_index === c2[e21 - 1].face_index && t3.edge.next === c2[e21 - 1].edge)
continue;
let n3 = t3.edge.next;
for (;Um(n3.length); )
n3 = n3.next;
let o3 = n3.shape.tangentInStart(), r3 = t3.pt.translate(o3), s3 = t3.edge.shape.tangentInEnd(), a3 = t3.pt.translate(s3), h2 = r3.leftTo(i2), d2 = a3.leftTo(i2);
(h2 && !d2 || !h2 && d2) && l2++;
} else if (t3.edge.shape instanceof Qm.Segment)
l2++;
else {
let e22 = t3.edge.shape.box;
Zm(t3.pt.y, e22.ymin) || Zm(t3.pt.y, e22.ymax) || l2++;
}
}
return n2 = l2 % 2 == 1 ? 1 : 0, n2;
}
function Mf(e20, t2) {
return Rf(e20, t2).intersect();
}
function wf(e20, t2) {
return Rf(e20, t2).inside();
}
function Nf(e20, t2) {
return Rf(e20, t2).covered();
}
function Tf(e20, t2) {
return Nf(t2, e20);
}
function Rf(e20, t2) {
return e20 instanceof Qm.Line && t2 instanceof Qm.Line ? function(e21, t3) {
let n2 = new Cf, o2 = ig(e21, t3);
o2.length === 0 ? e21.contains(t3.pt) && t3.contains(e21.pt) ? (n2.I2I = [e21], n2.I2E = [], n2.E2I = []) : (n2.I2I = [], n2.I2E = [e21], n2.E2I = [t3]) : (n2.I2I = o2, n2.I2E = e21.split(o2), n2.E2I = t3.split(o2));
return n2;
}(e20, t2) : e20 instanceof Qm.Line && t2 instanceof Qm.Circle ? function(e21, t3) {
let n2 = new Cf, o2 = rg(e21, t3);
if (o2.length === 0)
n2.I2I = [], n2.I2B = [], n2.I2E = [e21], n2.E2I = [t3];
else if (o2.length === 1)
n2.I2I = [], n2.I2B = o2, n2.I2E = e21.split(o2), n2.E2I = [t3];
else {
let i2 = new Lg([e21]), r2 = e21.sortPoints(o2);
i2.split(r2);
let s2 = i2.toShapes();
n2.I2I = [s2[1]], n2.I2B = r2, n2.I2E = [s2[0], s2[2]], n2.E2I = new Qm.Polygon([t3.toArc()]).cutWithLine(e21);
}
return n2;
}(e20, t2) : e20 instanceof Qm.Line && t2 instanceof Qm.Box ? function(e21, t3) {
let n2 = new Cf, o2 = sg(e21, t3);
if (o2.length === 0)
n2.I2I = [], n2.I2B = [], n2.I2E = [e21], n2.E2I = [t3];
else if (o2.length === 1)
n2.I2I = [], n2.I2B = o2, n2.I2E = e21.split(o2), n2.E2I = [t3];
else {
let i2 = new Lg([e21]), r2 = e21.sortPoints(o2);
i2.split(r2);
let s2 = i2.toShapes();
t3.toSegments().some((e22) => e22.contains(o2[0]) && e22.contains(o2[1])) ? (n2.I2I = [], n2.I2B = [s2[1]], n2.I2E = [s2[0], s2[2]], n2.E2I = [t3]) : (n2.I2I = [s2[1]], n2.I2B = r2, n2.I2E = [s2[0], s2[2]], n2.E2I = new Qm.Polygon(t3.toSegments()).cutWithLine(e21));
}
return n2;
}(e20, t2) : e20 instanceof Qm.Line && t2 instanceof Qm.Polygon ? function(e21, t3) {
let n2 = new Cf, o2 = Sg(e21, t3), i2 = new Lg([e21]), r2 = o2.length > 0 ? o2.slice() : e21.sortPoints(o2);
return i2.split(r2), [...i2].forEach((e22) => e22.setInclusion(t3)), n2.I2I = [...i2].filter((e22) => e22.bv === Qm.INSIDE).map((e22) => e22.shape), n2.I2B = [...i2].slice(1).map((e22) => e22.bv === Qm.BOUNDARY ? e22.shape : e22.shape.start), n2.I2E = [...i2].filter((e22) => e22.bv === Qm.OUTSIDE).map((e22) => e22.shape), n2.E2I = t3.cutWithLine(e21), n2;
}(e20, t2) : (e20 instanceof Qm.Segment || e20 instanceof Qm.Arc) && t2 instanceof Qm.Polygon ? Ef(e20, t2) : (e20 instanceof Qm.Segment || e20 instanceof Qm.Arc) && (t2 instanceof Qm.Circle || t2 instanceof Qm.Box) ? Ef(e20, new Qm.Polygon(t2)) : e20 instanceof Qm.Polygon && t2 instanceof Qm.Polygon ? Af(e20, t2) : (e20 instanceof Qm.Circle || e20 instanceof Qm.Box) && (t2 instanceof Qm.Circle || t2 instanceof Qm.Box) ? Af(new Qm.Polygon(e20), new Qm.Polygon(t2)) : (e20 instanceof Qm.Circle || e20 instanceof Qm.Box) && t2 instanceof Qm.Polygon ? Af(new Qm.Polygon(e20), t2) : e20 instanceof Qm.Polygon && (t2 instanceof Qm.Circle || t2 instanceof Qm.Box) ? Af(e20, new Qm.Polygon(t2)) : undefined;
}
function Ef(e20, t2) {
let n2 = new Cf, o2 = function(e21, t3) {
return e21 instanceof Qm.Line ? Sg(e21, t3) : e21 instanceof Qm.Segment ? vg(e21, t3) : e21 instanceof Qm.Arc ? Ig(e21, t3) : [];
}(e20, t2), i2 = o2.length > 0 ? o2.slice() : e20.sortPoints(o2), r2 = new Lg([e20]);
r2.split(i2), [...r2].forEach((e21) => e21.setInclusion(t2)), n2.I2I = [...r2].filter((e21) => e21.bv === Qm.INSIDE).map((e21) => e21.shape), n2.I2B = [...r2].slice(1).map((e21) => e21.bv === Qm.BOUNDARY ? e21.shape : e21.shape.start), n2.I2E = [...r2].filter((e21) => e21.bv === Qm.OUTSIDE).map((e21) => e21.shape), n2.B2I = [], n2.B2B = [], n2.B2E = [];
for (let o3 of [e20.start, e20.end])
switch (Pf(t2, o3)) {
case Qm.INSIDE:
n2.B2I.push(o3);
break;
case Qm.BOUNDARY:
n2.B2B.push(o3);
break;
case Qm.OUTSIDE:
n2.B2E.push(o3);
}
return n2;
}
function Af(e20, t2) {
let n2 = new Cf, [o2, i2] = sf(e20, t2), r2 = nf(e20, t2), s2 = tf(e20, t2), a2 = tf(t2, e20), [c2, l2] = of(e20, t2), h2 = rf(e20, t2), d2 = rf(t2, e20);
return n2.I2I = r2.isEmpty() ? [] : [r2], n2.I2B = l2, n2.I2E = s2.isEmpty() ? [] : [s2], n2.B2I = c2, n2.B2B = o2, n2.B2E = h2, n2.E2I = a2.isEmpty() ? [] : [a2], n2.E2B = d2, n2;
}
var Of = Object.freeze({ __proto__: null, contain: function(e20, t2) {
return wf(t2, e20);
}, cover: Tf, covered: Nf, disjoint: function(e20, t2) {
return !Mf(e20, t2);
}, equal: function(e20, t2) {
return Rf(e20, t2).equal();
}, inside: wf, intersect: Mf, relate: Rf, touch: function(e20, t2) {
return Rf(e20, t2).touch();
} });
var kf = class e20 {
constructor(e21 = 1, t2 = 0, n2 = 0, o2 = 1, i2 = 0, r2 = 0) {
this.a = e21, this.b = t2, this.c = n2, this.d = o2, this.tx = i2, this.ty = r2;
}
fromMatrix3x3(t2) {
const [n2, o2, i2] = t2[0], [r2, s2, a2] = t2[1];
return new e20(n2, r2, o2, s2, i2, a2);
}
toMatrix3x3() {
return [[this.a, this.c, this.tx], [this.b, this.d, this.ty], [0, 0, 1]];
}
clone() {
return new e20(this.a, this.b, this.c, this.d, this.tx, this.ty);
}
transform(e21) {
return [e21[0] * this.a + e21[1] * this.c + this.tx, e21[0] * this.b + e21[1] * this.d + this.ty];
}
multiply(t2) {
return new e20(this.a * t2.a + this.c * t2.b, this.b * t2.a + this.d * t2.b, this.a * t2.c + this.c * t2.d, this.b * t2.c + this.d * t2.d, this.a * t2.tx + this.c * t2.ty + this.tx, this.b * t2.tx + this.d * t2.ty + this.ty);
}
translate(...t2) {
let n2, o2;
if (t2.length != 1 || isNaN(t2[0].x) || isNaN(t2[0].y)) {
if (t2.length !== 2 || typeof t2[0] != "number" || typeof t2[1] != "number")
throw Km.ILLEGAL_PARAMETERS;
n2 = t2[0], o2 = t2[1];
} else
n2 = t2[0].x, o2 = t2[0].y;
return this.multiply(new e20(1, 0, 0, 1, n2, o2));
}
rotate(t2, n2 = 0, o2 = 0) {
let i2 = Math.cos(t2), r2 = Math.sin(t2);
return this.translate(n2, o2).multiply(new e20(i2, r2, -r2, i2, 0, 0)).translate(-n2, -o2);
}
scale(t2, n2) {
return this.multiply(new e20(t2, 0, 0, n2, 0, 0));
}
equalTo(e21) {
return !!Qm.Utils.EQ(this.tx, e21.tx) && (!!Qm.Utils.EQ(this.ty, e21.ty) && (!!Qm.Utils.EQ(this.a, e21.a) && (!!Qm.Utils.EQ(this.b, e21.b) && (!!Qm.Utils.EQ(this.c, e21.c) && !!Qm.Utils.EQ(this.d, e21.d)))));
}
};
Qm.Matrix = kf;
Qm.matrix = (...e21) => new Qm.Matrix(...e21);
var Df = class {
constructor(e21, t2) {
this.low = e21, this.high = t2;
}
get max() {
return this.clone();
}
less_than(e21) {
return this.low < e21.low || this.low === e21.low && this.high < e21.high;
}
equal_to(e21) {
return this.low === e21.low && this.high === e21.high;
}
intersect(e21) {
return !this.not_intersect(e21);
}
not_intersect(e21) {
return this.high < e21.low || e21.high < this.low;
}
merge(e21) {
const t2 = this.low === undefined ? e21.low : this.low < e21.low ? this.low : e21.low, n2 = this.high === undefined ? e21.high : this.high > e21.high ? this.high : e21.high, o2 = this.clone();
return o2.low = t2, o2.high = n2, o2;
}
output() {
return [this.low, this.high];
}
comparable_less_than(e21, t2) {
return e21 < t2;
}
};
var Lf = class e21 extends Df {
clone() {
return new e21(this.low, this.high);
}
};
var zf = class {
constructor(e22, t2, n2 = null, o2 = null, i2 = null, r2 = 0) {
if (this.left = n2, this.right = o2, this.parent = i2, this.color = r2, this.item = { key: undefined, values: [] }, t2 !== undefined && this.item.values.push(t2), e22 !== undefined)
if (Array.isArray(e22)) {
const [t3, n3] = e22;
if (!Number.isNaN(t3) && !Number.isNaN(n3)) {
let e23 = t3, o3 = n3;
e23 > o3 && ([e23, o3] = [o3, e23]), this.item.key = new Lf(e23, o3);
}
} else
this.item.key = e22;
this.max = this.item.key ? this.item.key.max : undefined;
}
isNil() {
return this.item.key === undefined && this.item.values.length === 0 && this.left === null && this.right === null && this.color === 0;
}
requireKey() {
if (!this.item.key)
throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");
return this.item.key;
}
less_than(e22) {
const t2 = this.requireKey(), n2 = e22.requireKey();
return t2.less_than(n2);
}
_value_equal(e22) {
const t2 = this.item.values[0], n2 = e22.item.values[0];
return t2 && n2 && t2.equal_to ? t2.equal_to(n2) : t2 === n2;
}
equal_to(e22) {
const t2 = this.requireKey(), n2 = e22.requireKey();
return t2.equal_to(n2);
}
intersect(e22) {
const t2 = this.requireKey(), n2 = e22.requireKey();
return t2.intersect(n2);
}
copy_data(e22) {
this.item.key = e22.item.key, this.item.values = e22.item.values.slice();
}
update_max() {
this.max = this.item.key ? this.item.key.max : undefined, 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(e22) {
if (!this.left)
return true;
const t2 = this.left.max ? this.left.max.high : this.left.item.key.high, n2 = this.requireKey(), o2 = e22.requireKey();
return n2.comparable_less_than(t2, o2.low);
}
not_intersect_right_subtree(e22) {
if (!this.right)
return true;
const t2 = this.right.max ? this.right.max.low : this.right.item.key.low, n2 = this.requireKey(), o2 = e22.requireKey();
return n2.comparable_less_than(o2.high, t2);
}
};
var Bf = class e22 {
constructor() {
this.root = null, this.nil_node = new zf;
}
get size() {
let e23 = 0;
return this.tree_walk(this.root, (t2) => e23 += t2.item.values.length), e23;
}
get keys() {
const e23 = [];
return this.tree_walk(this.root, (t2) => e23.push(t2.item.key.output())), e23;
}
get values() {
const e23 = [];
return this.tree_walk(this.root, (t2) => {
for (const n2 of t2.item.values)
e23.push(n2);
}), e23;
}
get items() {
const e23 = [];
return this.tree_walk(this.root, (t2) => {
const n2 = t2.item.key.output();
for (const o2 of t2.item.values)
e23.push({ key: n2, value: o2 });
}), e23;
}
isEmpty() {
return this.root == null || this.root === this.nil_node;
}
clear() {
this.root = null;
}
insert(e23, t2 = e23) {
if (e23 === undefined)
return;
const n2 = this.tree_search(this.root, new zf(e23));
if (n2)
return n2.item.values.push(t2), n2;
const o2 = new zf(e23, t2, this.nil_node, this.nil_node, null, 1);
return this.tree_insert(o2), this.recalc_max(o2), o2;
}
exist(e23, t2 = e23) {
const n2 = this.tree_search(this.root, new zf(e23));
return !!n2 && (arguments.length < 2 || t2 === e23 || n2.item.values.some((e24) => e24 && e24.equal_to ? e24.equal_to(t2) : e24 === t2));
}
remove(e23, t2 = e23) {
const n2 = this.tree_search(this.root, new zf(e23));
if (!n2)
return;
if (arguments.length < 2)
return this.tree_delete(n2), n2;
const o2 = n2.item.values.findIndex((e24) => e24 && e24.equal_to ? e24.equal_to(t2) : e24 === t2);
return o2 >= 0 ? (n2.item.values.splice(o2, 1), n2.item.values.length === 0 && this.tree_delete(n2), n2) : undefined;
}
search(e23, t2 = (e24, t3) => e24 === t3 ? t3.output() : e24) {
const n2 = new zf(e23), o2 = [];
this.tree_search_interval(this.root, n2, o2);
const i2 = [];
for (const e24 of o2)
for (const n3 of e24.item.values)
i2.push(t2(n3, e24.item.key));
return i2;
}
intersect_any(e23) {
const t2 = new zf(e23);
return this.tree_find_any_interval(this.root, t2);
}
forEach(e23) {
this.tree_walk(this.root, (t2) => {
for (const n2 of t2.item.values)
e23(t2.item.key, n2);
});
}
map(t2) {
const n2 = new e22;
return this.tree_walk(this.root, (e23) => {
for (const o2 of e23.item.values)
n2.insert(e23.item.key, t2(o2, e23.item.key));
}), n2;
}
*iterate(e23, t2 = (e24, t3) => e24 === t3 ? t3.output() : e24) {
let n2 = null;
for (e23 ? n2 = this.tree_search_nearest_forward(this.root, new zf(e23)) : this.root && (n2 = this.local_minimum(this.root));n2; ) {
for (const e24 of n2.item.values)
yield t2(e24, n2.item.key);
n2 = this.tree_successor(n2);
}
}
recalc_max(e23) {
let t2 = e23;
for (;t2.parent != null; )
t2.parent.update_max(), t2 = t2.parent;
}
tree_insert(e23) {
let t2 = this.root, n2 = null;
if (this.root == null || this.root === this.nil_node)
this.root = e23;
else {
for (;t2 !== this.nil_node; )
n2 = t2, t2 = e23.less_than(t2) ? t2.left : t2.right;
e23.parent = n2, e23.less_than(n2) ? n2.left = e23 : n2.right = e23;
}
this.insert_fixup(e23);
}
insert_fixup(e23) {
let t2, n2;
for (t2 = e23;t2 !== this.root && t2.parent.color === 1; )
t2.parent === t2.parent.parent.left ? (n2 = t2.parent.parent.right, n2.color === 1 ? (t2.parent.color = 0, n2.color = 0, t2.parent.parent.color = 1, t2 = t2.parent.parent) : (t2 === t2.parent.right && (t2 = t2.parent, this.rotate_left(t2)), t2.parent.color = 0, t2.parent.parent.color = 1, this.rotate_right(t2.parent.parent))) : (n2 = t2.parent.parent.left, n2.color === 1 ? (t2.parent.color = 0, n2.color = 0, t2.parent.parent.color = 1, t2 = t2.parent.parent) : (t2 === t2.parent.left && (t2 = t2.parent, this.rotate_right(t2)), t2.parent.color = 0, t2.parent.parent.color = 1, this.rotate_left(t2.parent.parent)));
this.root.color = 0;
}
tree_delete(e23) {
let t2, n2;
t2 = e23.left === this.nil_node || e23.right === this.nil_node ? e23 : this.tree_successor(e23), n2 = t2.left !== this.nil_node ? t2.left : t2.right, n2.parent = t2.parent, t2 === this.root ? this.root = n2 : (t2 === t2.parent.left ? t2.parent.left = n2 : t2.parent.right = n2, t2.parent.update_max()), this.recalc_max(n2), t2 !== e23 && (e23.copy_data(t2), e23.update_max(), this.recalc_max(e23)), t2.color === 0 && this.delete_fixup(n2);
}
delete_fixup(e23) {
let t2, n2 = e23;
for (;n2 !== this.root && n2.parent != null && n2.color === 0; )
n2 === n2.parent.left ? (t2 = n2.parent.right, t2.color === 1 && (t2.color = 0, n2.parent.color = 1, this.rotate_left(n2.parent), t2 = n2.parent.right), t2.left.color === 0 && t2.right.color === 0 ? (t2.color = 1, n2 = n2.parent) : (t2.right.color === 0 && (t2.color = 1, t2.left.color = 0, this.rotate_right(t2), t2 = n2.parent.right), t2.color = n2.parent.color, n2.parent.color = 0, t2.right.color = 0, this.rotate_left(n2.parent), n2 = this.root)) : (t2 = n2.parent.left, t2.color === 1 && (t2.color = 0, n2.parent.color = 1, this.rotate_right(n2.parent), t2 = n2.parent.left), t2.left.color === 0 && t2.right.color === 0 ? (t2.color = 1, n2 = n2.parent) : (t2.left.color === 0 && (t2.color = 1, t2.right.color = 0, this.rotate_left(t2), t2 = n2.parent.left), t2.color = n2.parent.color, n2.parent.color = 0, t2.left.color = 0, this.rotate_right(n2.parent), n2 = this.root));
n2.color = 0;
}
tree_search(e23, t2) {
if (e23 != null && e23 !== this.nil_node)
return t2.equal_to(e23) ? e23 : t2.less_than(e23) ? this.tree_search(e23.left, t2) : this.tree_search(e23.right, t2);
}
tree_search_nearest_forward(e23, t2) {
let n2 = null, o2 = e23;
for (;o2 && o2 !== this.nil_node; )
o2.less_than(t2) ? o2.intersect(t2) ? (n2 = o2, o2 = o2.left) : o2 = o2.right : (n2 && !o2.less_than(n2) || (n2 = o2), o2 = o2.left);
return n2 || null;
}
tree_search_interval(e23, t2, n2) {
e23 != null && e23 !== this.nil_node && (e23.left === this.nil_node || e23.not_intersect_left_subtree(t2) || this.tree_search_interval(e23.left, t2, n2), e23.intersect(t2) && n2.push(e23), e23.right === this.nil_node || e23.not_intersect_right_subtree(t2) || this.tree_search_interval(e23.right, t2, n2));
}
tree_find_any_interval(e23, t2) {
let n2 = false;
return e23 != null && e23 !== this.nil_node && (e23.left === this.nil_node || e23.not_intersect_left_subtree(t2) || (n2 = this.tree_find_any_interval(e23.left, t2)), n2 || (n2 = e23.intersect(t2)), n2 || e23.right === this.nil_node || e23.not_intersect_right_subtree(t2) || (n2 = this.tree_find_any_interval(e23.right, t2))), n2;
}
local_minimum(e23) {
let t2 = e23;
for (;t2.left != null && t2.left !== this.nil_node; )
t2 = t2.left;
return t2;
}
local_maximum(e23) {
let t2 = e23;
for (;t2.right != null && t2.right !== this.nil_node; )
t2 = t2.right;
return t2;
}
tree_successor(e23) {
let t2, n2, o2;
if (e23.right !== this.nil_node)
t2 = this.local_minimum(e23.right);
else {
for (n2 = e23, o2 = e23.parent;o2 != null && o2.right === n2; )
n2 = o2, o2 = o2.parent;
t2 = o2;
}
return t2;
}
rotate_left(e23) {
const t2 = e23.right;
e23.right = t2.left, t2.left !== this.nil_node && (t2.left.parent = e23), t2.parent = e23.parent, e23 === this.root ? this.root = t2 : e23 === e23.parent.left ? e23.parent.left = t2 : e23.parent.right = t2, t2.left = e23, e23.parent = t2, e23 !== null && e23 !== this.nil_node && e23.update_max(), t2 != null && t2 !== this.nil_node && t2.update_max();
}
rotate_right(e23) {
const t2 = e23.left;
e23.left = t2.right, t2.right !== this.nil_node && (t2.right.parent = e23), t2.parent = e23.parent, e23 === this.root ? this.root = t2 : e23 === e23.parent.left ? e23.parent.left = t2 : e23.parent.right = t2, t2.right = e23, e23.parent = t2, e23 !== null && e23 !== this.nil_node && e23.update_max(), t2 != null && t2 !== this.nil_node && t2.update_max();
}
tree_walk(e23, t2) {
e23 != null && e23 !== this.nil_node && (this.tree_walk(e23.left, t2), t2(e23), this.tree_walk(e23.right, t2));
}
testRedBlackProperty() {
let e23 = true;
return this.tree_walk(this.root, function(t2) {
t2.color === 1 && (t2.left.color === 0 && t2.right.color === 0 || (e23 = false));
}), e23;
}
testBlackHeightProperty(e23) {
let t2 = 0, n2 = 0, o2 = 0;
if (e23.color === 0 && t2++, n2 = e23.left !== this.nil_node ? this.testBlackHeightProperty(e23.left) : 1, o2 = e23.right !== this.nil_node ? this.testBlackHeightProperty(e23.right) : 1, n2 !== o2)
throw new Error("Red-black height property violated");
return t2 += n2, t2;
}
};
var Ff = class extends Set {
constructor(e23) {
super(e23), this.index = new Bf, this.forEach((e24) => this.index.insert(e24));
}
add(e23) {
let t2 = this.size;
const { key: n2, value: o2 } = e23, i2 = n2 || e23.box, r2 = o2 || e23;
return super.add(r2), this.size > t2 && this.index.insert(i2, r2), this;
}
delete(e23) {
const { key: t2, value: n2 } = e23, o2 = t2 || e23.box, i2 = n2 || e23;
let r2 = super.delete(i2);
return r2 && this.index.remove(o2, i2), r2;
}
clear() {
super.clear(), this.index = new Bf;
}
search(e23) {
return this.index.search(e23);
}
hit(e23) {
let t2 = new Qm.Box(e23.x - 1, e23.y - 1, e23.x + 1, e23.y + 1);
return this.index.search(t2).filter((t3) => e23.on(t3));
}
svg() {
return [...this].reduce((e23, t2) => e23 + t2.svg(), "");
}
};
Qm.PlanarSet = Ff;
var jf = class {
get name() {
throw Km.CANNOT_INVOKE_ABSTRACT_METHOD;
}
get box() {
throw Km.CANNOT_INVOKE_ABSTRACT_METHOD;
}
clone() {
throw Km.CANNOT_INVOKE_ABSTRACT_METHOD;
}
translate(...e23) {
return this.transform(new kf().translate(...e23));
}
rotate(e23, t2 = new Qm.Point) {
return this.transform(new kf().rotate(e23, t2.x, t2.y));
}
scale(e23, t2) {
return this.transform(new kf().scale(e23, t2));
}
transform(...e23) {
throw Km.CANNOT_INVOKE_ABSTRACT_METHOD;
}
toJSON() {
return Object.assign({}, this, { name: this.name });
}
svg(e23 = {}) {
throw Km.CANNOT_INVOKE_ABSTRACT_METHOD;
}
};
var $f = class e23 extends jf {
constructor(...e24) {
if (super(), this.x = 0, this.y = 0, e24.length !== 0) {
if (e24.length === 1 && e24[0] instanceof Array && e24[0].length === 2) {
let t2 = e24[0];
if (typeof t2[0] == "number" && typeof t2[1] == "number")
return this.x = t2[0], void (this.y = t2[1]);
}
if (e24.length === 1 && e24[0] instanceof Object && e24[0].name === "point") {
let { x: t2, y: n2 } = e24[0];
return this.x = t2, void (this.y = n2);
}
if (e24.length === 2 && typeof e24[0] == "number" && typeof e24[1] == "number")
return this.x = e24[0], void (this.y = e24[1]);
throw Km.ILLEGAL_PARAMETERS;
}
}
get box() {
return new Qm.Box(this.x, this.y, this.x, this.y);
}
clone() {
return new Qm.Point(this.x, this.y);
}
get vertices() {
return [this.clone()];
}
equalTo(e24) {
return Qm.Utils.EQ(this.x, e24.x) && Qm.Utils.EQ(this.y, e24.y);
}
lessThan(e24) {
return !!Qm.Utils.LT(this.y, e24.y) || !(!Qm.Utils.EQ(this.y, e24.y) || !Qm.Utils.LT(this.x, e24.x));
}
transform(e24) {
return new Qm.Point(e24.transform([this.x, this.y]));
}
projectionOn(e24) {
if (this.equalTo(e24.pt))
return this.clone();
let t2 = new Qm.Vector(this, e24.pt);
if (Qm.Utils.EQ_0(t2.cross(e24.norm)))
return e24.pt.clone();
let n2 = t2.dot(e24.norm), o2 = e24.norm.multiply(n2);
return this.translate(o2);
}
leftTo(e24) {
let t2 = new Qm.Vector(e24.pt, this);
return Qm.Utils.GT(t2.dot(e24.norm), 0);
}
distanceTo(t2) {
if (t2 instanceof e23) {
let e24 = t2.x - this.x, n2 = t2.y - this.y;
return [Math.sqrt(e24 * e24 + n2 * n2), new Qm.Segment(this, t2)];
}
return t2 instanceof Qm.Line ? Qm.Distance.point2line(this, t2) : t2 instanceof Qm.Circle ? Qm.Distance.point2circle(this, t2) : t2 instanceof Qm.Segment ? Qm.Distance.point2segment(this, t2) : t2 instanceof Qm.Arc ? Qm.Distance.point2arc(this, t2) : t2 instanceof Qm.Box ? Qm.Distance.point2polygon(this, new Qm.Polygon(t2)) : t2 instanceof Qm.Polygon ? Qm.Distance.point2polygon(this, t2) : t2 instanceof Qm.PlanarSet ? Qm.Distance.shape2planarSet(this, t2) : t2 instanceof Qm.Multiline ? Qm.Distance.shape2multiline(this, t2) : undefined;
}
on(e24) {
if (e24 instanceof Qm.Point)
return this.equalTo(e24);
if (e24.contains && e24.contains instanceof Function)
return e24.contains(this);
throw Qm.Errors.UNSUPPORTED_SHAPE_TYPE;
}
get name() {
return "point";
}
svg(e24 = {}) {
const t2 = e24.r ?? 3;
return `
<circle cx="${this.x}" cy="${this.y}" r="${t2}"
${og({ fill: "red", ...e24 })} />`;
}
};
Qm.Point = $f;
var Yf = (...e24) => new Qm.Point(...e24);
Qm.point = Yf;
var Xf = class extends jf {
constructor(...e24) {
if (super(), this.x = 0, this.y = 0, e24.length !== 0) {
if (e24.length === 1 && e24[0] instanceof Array && e24[0].length === 2) {
let t2 = e24[0];
if (typeof t2[0] == "number" && typeof t2[1] == "number")
return this.x = t2[0], void (this.y = t2[1]);
}
if (e24.length === 1 && e24[0] instanceof Object && e24[0].name === "vector") {
let { x: t2, y: n2 } = e24[0];
return this.x = t2, void (this.y = n2);
}
if (e24.length === 1 && e24[0] instanceof Object && e24[0].name === "segment") {
let { start: t2, end: n2 } = e24[0];
return this.x = n2.x - t2.x, void (this.y = n2.y - t2.y);
}
if (e24.length === 2) {
let t2 = e24[0], n2 = e24[1];
if (typeof t2 == "number" && typeof n2 == "number")
return this.x = t2, void (this.y = n2);
if (t2 instanceof Qm.Point && n2 instanceof Qm.Point)
return this.x = n2.x - t2.x, void (this.y = n2.y - t2.y);
}
throw Km.ILLEGAL_PARAMETERS;
}
}
clone() {
return new Qm.Vector(this.x, this.y);
}
get slope() {
let e24 = Math.atan2(this.y, this.x);
return e24 < 0 && (e24 = 2 * Math.PI + e24), e24;
}
get length() {
return Math.sqrt(this.dot(this));
}
isZeroLength() {
return Qm.Utils.EQ_0(this.length);
}
equalTo(e24) {
return Qm.Utils.EQ(this.x, e24.x) && Qm.Utils.EQ(this.y, e24.y);
}
multiply(e24) {
return new Qm.Vector(e24 * this.x, e24 * this.y);
}
dot(e24) {
return this.x * e24.x + this.y * e24.y;
}
cross(e24) {
return this.x * e24.y - this.y * e24.x;
}
normalize() {
if (this.isZeroLength())
throw Km.ZERO_DIVISION;
return new Qm.Vector(this.x / this.length, this.y / this.length);
}
rotate(e24, t2 = new Qm.Point) {
if (t2.x === 0 && t2.y === 0)
return this.transform(new kf().rotate(e24));
throw Km.OPERATION_IS_NOT_SUPPORTED;
}
transform(e24) {
return new Qm.Vector(e24.transform([this.x, this.y]));
}
rotate90CCW() {
return new Qm.Vector(-this.y, this.x);
}
rotate90CW() {
return new Qm.Vector(this.y, -this.x);
}
invert() {
return new Qm.Vector(-this.x, -this.y);
}
add(e24) {
return new Qm.Vector(this.x + e24.x, this.y + e24.y);
}
subtract(e24) {
return new Qm.Vector(this.x - e24.x, this.y - e24.y);
}
angleTo(e24) {
let t2 = this.normalize(), n2 = e24.normalize(), o2 = Math.atan2(t2.cross(n2), t2.dot(n2));
return o2 < 0 && (o2 += 2 * Math.PI), o2;
}
projectionOn(e24) {
let t2 = e24.normalize(), n2 = this.dot(t2);
return t2.multiply(n2);
}
get name() {
return "vector";
}
};
Qm.Vector = Xf;
var Wf = (...e24) => new Qm.Vector(...e24);
Qm.vector = Wf;
var Vf = class e24 extends jf {
constructor(...e25) {
if (super(), this.ps = new Qm.Point, this.pe = new Qm.Point, e25.length !== 0) {
if (e25.length === 1 && e25[0] instanceof Array && e25[0].length === 4) {
let t2 = e25[0];
return this.ps = new Qm.Point(t2[0], t2[1]), void (this.pe = new Qm.Point(t2[2], t2[3]));
}
if (e25.length === 1 && e25[0] instanceof Object && e25[0].name === "segment") {
let { ps: t2, pe: n2 } = e25[0];
return this.ps = new Qm.Point(t2.x, t2.y), void (this.pe = new Qm.Point(n2.x, n2.y));
}
if (!(e25.length === 1 && e25[0] instanceof Qm.Point)) {
if (e25.length === 2 && e25[0] instanceof Qm.Point && e25[1] instanceof Qm.Point)
return this.ps = e25[0].clone(), void (this.pe = e25[1].clone());
if (e25.length === 4)
return this.ps = new Qm.Point(e25[0], e25[1]), void (this.pe = new Qm.Point(e25[2], e25[3]));
throw Km.ILLEGAL_PARAMETERS;
}
this.ps = e25[0].clone();
}
}
clone() {
return new Qm.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 Qm.Vector(this.start, this.end).slope;
}
get box() {
return new Qm.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(e25) {
return this.ps.equalTo(e25.ps) && this.pe.equalTo(e25.pe);
}
contains(e25) {
return Qm.Utils.EQ_0(this.distanceToPoint(e25));
}
intersect(e25) {
return e25 instanceof Qm.Point ? this.contains(e25) ? [e25] : [] : e25 instanceof Qm.Line ? cg(this, e25) : e25 instanceof Qm.Ray ? Tg(e25, this) : e25 instanceof Qm.Segment ? lg(this, e25) : e25 instanceof Qm.Circle ? ug(this, e25) : e25 instanceof Qm.Box ? function(e26, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = lg(o2, e26);
for (let e27 of t3)
n2.push(e27);
}
return n2;
}(this, e25) : e25 instanceof Qm.Arc ? pg(this, e25) : e25 instanceof Qm.Polygon ? vg(this, e25) : e25 instanceof Qm.Multiline ? Dg(this, e25) : undefined;
}
distanceTo(e25) {
if (e25 instanceof Qm.Point) {
let [t2, n2] = Qm.Distance.point2segment(e25, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e25 instanceof Qm.Circle) {
let [t2, n2] = Qm.Distance.segment2circle(this, e25);
return [t2, n2];
}
if (e25 instanceof Qm.Line) {
let [t2, n2] = Qm.Distance.segment2line(this, e25);
return [t2, n2];
}
if (e25 instanceof Qm.Segment) {
let [t2, n2] = Qm.Distance.segment2segment(this, e25);
return [t2, n2];
}
if (e25 instanceof Qm.Arc) {
let [t2, n2] = Qm.Distance.segment2arc(this, e25);
return [t2, n2];
}
if (e25 instanceof Qm.Box) {
let [t2, n2] = Qm.Distance.shape2polygon(this, new Qm.Polygon(e25));
return [t2, n2];
}
if (e25 instanceof Qm.Polygon) {
let [t2, n2] = Qm.Distance.shape2polygon(this, e25);
return [t2, n2];
}
if (e25 instanceof Qm.PlanarSet) {
let [t2, n2] = Qm.Distance.shape2planarSet(this, e25);
return [t2, n2];
}
if (e25 instanceof Qm.Multiline)
return Qm.Distance.shape2multiline(this, e25);
}
tangentInStart() {
return new Qm.Vector(this.start, this.end).normalize();
}
tangentInEnd() {
return new Qm.Vector(this.end, this.start).normalize();
}
reverse() {
return new e24(this.end, this.start);
}
split(e25) {
return this.start.equalTo(e25) ? [null, this.clone()] : this.end.equalTo(e25) ? [this.clone(), null] : [new Qm.Segment(this.start, e25), new Qm.Segment(e25, this.end)];
}
middle() {
return new Qm.Point((this.start.x + this.end.x) / 2, (this.start.y + this.end.y) / 2);
}
pointAtLength(e25) {
if (e25 > this.length || e25 < 0)
return null;
if (e25 == 0)
return this.start;
if (e25 == this.length)
return this.end;
let t2 = e25 / this.length;
return new Qm.Point((this.end.x - this.start.x) * t2 + this.start.x, (this.end.y - this.start.y) * t2 + this.start.y);
}
distanceToPoint(e25) {
let [t2, ...n2] = Qm.Distance.point2segment(e25, this);
return t2;
}
definiteIntegral(e25 = 0) {
return (this.end.x - this.start.x) * (this.start.y - e25 + (this.end.y - e25)) / 2;
}
transform(t2 = new Qm.Matrix) {
return new e24(this.ps.transform(t2), this.pe.transform(t2));
}
isZeroLength() {
return this.ps.equalTo(this.pe);
}
sortPoints(e25) {
return new Qm.Line(this.start, this.end).sortPoints(e25);
}
get name() {
return "segment";
}
svg(e25 = {}) {
return `
<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${og(e25)} />`;
}
};
Qm.Segment = Vf;
var Hf = (...e25) => new Qm.Segment(...e25);
Qm.segment = Hf;
var { vector: Gf } = Qm;
Qm.Line = class e25 extends jf {
constructor(...t2) {
if (super(), this.pt = new Qm.Point, this.norm = new Qm.Vector(0, 1), t2.length !== 0) {
if (t2.length === 1 && t2[0] instanceof Object && t2[0].name === "line") {
let { pt: e26, norm: n2 } = t2[0];
return this.pt = new Qm.Point(e26), void (this.norm = new Qm.Vector(n2));
}
if (t2.length === 2) {
let n2 = t2[0], o2 = t2[1];
if (n2 instanceof Qm.Point && o2 instanceof Qm.Point)
return this.pt = n2, this.norm = e25.points2norm(n2, o2), void (this.norm.dot(Gf(this.pt.x, this.pt.y)) >= 0 && this.norm.invert());
if (n2 instanceof Qm.Point && o2 instanceof Qm.Vector) {
if (Qm.Utils.EQ_0(o2.x) && Qm.Utils.EQ_0(o2.y))
throw Km.ILLEGAL_PARAMETERS;
return this.pt = n2.clone(), this.norm = o2.clone(), this.norm = this.norm.normalize(), void (this.norm.dot(Gf(this.pt.x, this.pt.y)) >= 0 && this.norm.invert());
}
if (n2 instanceof Qm.Vector && o2 instanceof Qm.Point) {
if (Qm.Utils.EQ_0(n2.x) && Qm.Utils.EQ_0(n2.y))
throw Km.ILLEGAL_PARAMETERS;
return this.pt = o2.clone(), this.norm = n2.clone(), this.norm = this.norm.normalize(), void (this.norm.dot(Gf(this.pt.x, this.pt.y)) >= 0 && this.norm.invert());
}
}
throw Km.ILLEGAL_PARAMETERS;
}
}
clone() {
return new Qm.Line(this.pt, this.norm);
}
get start() {}
get end() {}
get length() {
return Number.POSITIVE_INFINITY;
}
get box() {
return new Qm.Box(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
}
get middle() {}
get slope() {
return new Qm.Vector(this.norm.y, -this.norm.x).slope;
}
get standard() {
return [this.norm.x, this.norm.y, this.norm.dot(Gf(this.pt.x, this.pt.y))];
}
parallelTo(e26) {
return Qm.Utils.EQ_0(this.norm.cross(e26.norm));
}
incidentTo(e26) {
return this.parallelTo(e26) && this.pt.on(e26);
}
contains(e26) {
if (this.pt.equalTo(e26))
return true;
let t2 = new Qm.Vector(this.pt, e26);
return Qm.Utils.EQ_0(this.norm.dot(t2));
}
coord(e26) {
return Gf(e26.x, e26.y).cross(this.norm);
}
intersect(e26) {
return e26 instanceof Qm.Point ? this.contains(e26) ? [e26] : [] : e26 instanceof Qm.Line ? ig(this, e26) : e26 instanceof Qm.Ray ? Ag(e26, this) : e26 instanceof Qm.Circle ? rg(this, e26) : e26 instanceof Qm.Box ? sg(this, e26) : e26 instanceof Qm.Segment ? cg(e26, this) : e26 instanceof Qm.Arc ? ag(this, e26) : e26 instanceof Qm.Polygon ? Sg(this, e26) : e26 instanceof Qm.Multiline ? Dg(this, e26) : undefined;
}
distanceTo(e26) {
if (e26 instanceof Qm.Point) {
let [t2, n2] = Qm.Distance.point2line(e26, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e26 instanceof Qm.Circle) {
let [t2, n2] = Qm.Distance.circle2line(e26, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e26 instanceof Qm.Segment) {
let [t2, n2] = Qm.Distance.segment2line(e26, this);
return [t2, n2.reverse()];
}
if (e26 instanceof Qm.Arc) {
let [t2, n2] = Qm.Distance.arc2line(e26, this);
return [t2, n2.reverse()];
}
if (e26 instanceof Qm.Box) {
let [t2, n2] = Qm.Distance.shape2polygon(this, new Qm.Polygon(e26));
return [t2, n2];
}
if (e26 instanceof Qm.Polygon) {
let [t2, n2] = Qm.Distance.shape2polygon(this, e26);
return [t2, n2];
}
}
split(e26) {
if (e26 instanceof Qm.Point)
return [new Qm.Ray(e26, this.norm), new Qm.Ray(e26, this.norm)];
{
let t2 = new Qm.Multiline([this]), n2 = this.sortPoints(e26);
return t2.split(n2), t2.toShapes();
}
}
rotate(e26, t2 = new Qm.Point) {
return new Qm.Line(this.pt.rotate(e26, t2), this.norm.rotate(e26));
}
transform(e26) {
return new Qm.Line(this.pt.transform(e26), this.norm.clone());
}
sortPoints(e26) {
return e26.slice().sort((e27, t2) => this.coord(e27) < this.coord(t2) ? -1 : this.coord(e27) > this.coord(t2) ? 1 : 0);
}
get name() {
return "line";
}
svg(e26, t2 = {}) {
let n2 = sg(this, e26);
if (n2.length === 0)
return "";
let o2 = n2[0], i2 = n2.length === 2 ? n2[1] : n2.find((e27) => !e27.equalTo(o2));
return i2 === undefined && (i2 = o2), new Qm.Segment(o2, i2).svg(t2);
}
static points2norm(e26, t2) {
if (e26.equalTo(t2))
throw Km.ILLEGAL_PARAMETERS;
return new Qm.Vector(e26, t2).normalize().rotate90CCW();
}
};
var Uf = (...e26) => new Qm.Line(...e26);
Qm.line = Uf;
var Zf = class extends jf {
constructor(...e26) {
if (super(), this.pc = new Qm.Point, this.r = 1, e26.length === 1 && e26[0] instanceof Object && e26[0].name === "circle") {
let { pc: t2, r: n2 } = e26[0];
this.pc = new Qm.Point(t2), this.r = n2;
} else {
let [t2, n2] = [...e26];
t2 && t2 instanceof Qm.Point && (this.pc = t2.clone()), n2 !== undefined && (this.r = n2);
}
}
clone() {
return new Qm.Circle(this.pc.clone(), this.r);
}
get center() {
return this.pc;
}
get box() {
return new Qm.Box(this.pc.x - this.r, this.pc.y - this.r, this.pc.x + this.r, this.pc.y + this.r);
}
contains(e26) {
return e26 instanceof Qm.Point ? Qm.Utils.LE(e26.distanceTo(this.center)[0], this.r) : e26 instanceof Qm.Segment ? Qm.Utils.LE(e26.start.distanceTo(this.center)[0], this.r) && Qm.Utils.LE(e26.end.distanceTo(this.center)[0], this.r) : e26 instanceof Qm.Arc ? this.intersect(e26).length === 0 && Qm.Utils.LE(e26.start.distanceTo(this.center)[0], this.r) && Qm.Utils.LE(e26.end.distanceTo(this.center)[0], this.r) : e26 instanceof Qm.Circle ? this.intersect(e26).length === 0 && Qm.Utils.LE(e26.r, this.r) && Qm.Utils.LE(e26.center.distanceTo(this.center)[0], this.r) : undefined;
}
toArc(e26 = true) {
return new Qm.Arc(this.center, this.r, Math.PI, -Math.PI, e26);
}
scale(e26, t2) {
if (e26 !== t2)
throw Km.OPERATION_IS_NOT_SUPPORTED;
if (this.pc.x !== 0 || this.pc.y !== 0)
throw Km.OPERATION_IS_NOT_SUPPORTED;
return new Qm.Circle(this.pc, this.r * e26);
}
transform(e26 = new Qm.Matrix) {
return new Qm.Circle(this.pc.transform(e26), this.r);
}
intersect(e26) {
return e26 instanceof Qm.Point ? this.contains(e26) ? [e26] : [] : e26 instanceof Qm.Line ? rg(e26, this) : e26 instanceof Qm.Ray ? Eg(e26, this) : e26 instanceof Qm.Segment ? ug(e26, this) : e26 instanceof Qm.Circle ? mg(e26, this) : e26 instanceof Qm.Box ? function(e27, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = ug(o2, e27);
for (let e28 of t3)
n2.push(e28);
}
return n2;
}(this, e26) : e26 instanceof Qm.Arc ? fg(e26, this) : e26 instanceof Qm.Polygon ? Cg(this, e26) : e26 instanceof Qm.Multiline ? Dg(this, e26) : undefined;
}
distanceTo(e26) {
if (e26 instanceof Qm.Point) {
let [t2, n2] = Qm.Distance.point2circle(e26, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e26 instanceof Qm.Circle) {
let [t2, n2] = Qm.Distance.circle2circle(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.Line) {
let [t2, n2] = Qm.Distance.circle2line(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.Segment) {
let [t2, n2] = Qm.Distance.segment2circle(e26, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e26 instanceof Qm.Arc) {
let [t2, n2] = Qm.Distance.arc2circle(e26, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e26 instanceof Qm.Box) {
let [t2, n2] = Qm.Distance.shape2polygon(this, new Qm.Polygon(e26));
return [t2, n2];
}
if (e26 instanceof Qm.Polygon) {
let [t2, n2] = Qm.Distance.shape2polygon(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.PlanarSet) {
let [t2, n2] = Qm.Distance.shape2planarSet(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.Multiline) {
let [t2, n2] = Qm.Distance.shape2multiline(this, e26);
return [t2, n2];
}
}
get name() {
return "circle";
}
svg(e26 = {}) {
return `
<circle cx="${this.pc.x}" cy="${this.pc.y}" r="${this.r}"
${og({ fill: "none", ...e26 })} />`;
}
};
Qm.Circle = Zf;
Qm.circle = (...e26) => new Qm.Circle(...e26);
var qf = class extends jf {
constructor(...e26) {
if (super(), this.pc = new Qm.Point, this.r = 1, this.startAngle = 0, this.endAngle = 2 * Math.PI, this.counterClockwise = true, e26.length !== 0)
if (e26.length === 1 && e26[0] instanceof Object && e26[0].name === "arc") {
let { pc: t2, r: n2, startAngle: o2, endAngle: i2, counterClockwise: r2 } = e26[0];
this.pc = new Qm.Point(t2.x, t2.y), this.r = n2, this.startAngle = o2, this.endAngle = i2, this.counterClockwise = r2;
} else {
let [t2, n2, o2, i2, r2] = [...e26];
t2 && t2 instanceof Qm.Point && (this.pc = t2.clone()), n2 !== undefined && (this.r = n2), o2 !== undefined && (this.startAngle = o2), i2 !== undefined && (this.endAngle = i2), r2 !== undefined && (this.counterClockwise = r2);
}
}
clone() {
return new Qm.Arc(this.pc.clone(), this.r, this.startAngle, this.endAngle, this.counterClockwise);
}
get sweep() {
let e26 = this.startAngle, t2 = this.endAngle;
if (Qm.Utils.EQ(Math.abs(e26 - t2), Qm.PIx2))
return Qm.PIx2;
Math.abs(e26) > Qm.PIx2 && (e26 -= Math.trunc(e26 / Qm.PIx2) * Qm.PIx2), e26 < 0 && (e26 += Qm.PIx2), Math.abs(t2) > Qm.PIx2 && (t2 -= Math.trunc(t2 / Qm.PIx2) * Qm.PIx2), t2 < 0 && (t2 += Qm.PIx2);
let n2 = this.counterClockwise ? t2 - e26 : e26 - t2;
return n2 < 0 && (n2 += Qm.PIx2), n2;
}
get start() {
return new Qm.Point(this.pc.x + this.r, this.pc.y).rotate(this.startAngle, this.pc);
}
get end() {
return new Qm.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 e26 = this.breakToFunctional().reduce((e27, t2) => e27.merge(t2.start.box), new Qm.Box);
return e26 = e26.merge(this.end.box), e26;
}
contains(e26) {
if (!Qm.Utils.EQ(this.pc.distanceTo(e26)[0], this.r))
return false;
if (e26.equalTo(this.start))
return true;
let t2 = new Qm.Vector(this.pc, e26).slope, n2 = new Qm.Arc(this.pc, this.r, this.startAngle, t2, this.counterClockwise);
return Qm.Utils.LE(n2.length, this.length);
}
split(e26) {
if (this.start.equalTo(e26))
return [null, this.clone()];
if (this.end.equalTo(e26))
return [this.clone(), null];
let t2 = new Qm.Vector(this.pc, e26).slope;
return [new Qm.Arc(this.pc, this.r, this.startAngle, t2, this.counterClockwise), new Qm.Arc(this.pc, this.r, t2, this.endAngle, this.counterClockwise)];
}
middle() {
let e26 = this.counterClockwise ? this.startAngle + this.sweep / 2 : this.startAngle - this.sweep / 2;
return new Qm.Arc(this.pc, this.r, this.startAngle, e26, this.counterClockwise).end;
}
pointAtLength(e26) {
if (e26 > this.length || e26 < 0)
return null;
if (e26 === 0)
return this.start;
if (e26 === this.length)
return this.end;
let t2 = e26 / this.length, n2 = this.counterClockwise ? this.startAngle + this.sweep * t2 : this.startAngle - this.sweep * t2;
return new Qm.Arc(this.pc, this.r, this.startAngle, n2, this.counterClockwise).end;
}
chordHeight() {
return (1 - Math.cos(Math.abs(this.sweep / 2))) * this.r;
}
intersect(e26) {
return e26 instanceof Qm.Point ? this.contains(e26) ? [e26] : [] : e26 instanceof Qm.Line ? ag(e26, this) : e26 instanceof Qm.Ray ? Rg(e26, this) : e26 instanceof Qm.Circle ? fg(this, e26) : e26 instanceof Qm.Segment ? pg(e26, this) : e26 instanceof Qm.Box ? function(e27, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = pg(o2, e27);
for (let e28 of t3)
n2.push(e28);
}
return n2;
}(this, e26) : e26 instanceof Qm.Arc ? gg(this, e26) : e26 instanceof Qm.Polygon ? Ig(this, e26) : e26 instanceof Qm.Multiline ? Dg(this, e26) : undefined;
}
distanceTo(e26) {
if (e26 instanceof Qm.Point) {
let [t2, n2] = Qm.Distance.point2arc(e26, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e26 instanceof Qm.Circle) {
let [t2, n2] = Qm.Distance.arc2circle(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.Line) {
let [t2, n2] = Qm.Distance.arc2line(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.Segment) {
let [t2, n2] = Qm.Distance.segment2arc(e26, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e26 instanceof Qm.Arc) {
let [t2, n2] = Qm.Distance.arc2arc(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.Box) {
let [t2, n2] = Qm.Distance.shape2polygon(this, new Qm.Polygon(e26));
return [t2, n2];
}
if (e26 instanceof Qm.Polygon) {
let [t2, n2] = Qm.Distance.shape2polygon(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.PlanarSet) {
let [t2, n2] = Qm.Distance.shape2planarSet(this, e26);
return [t2, n2];
}
if (e26 instanceof Qm.Multiline)
return Qm.Distance.shape2multiline(this, e26);
}
breakToFunctional() {
let e26 = [], t2 = [0, Math.PI / 2, Math.PI, 3 * Math.PI / 2], n2 = this.startAngle, o2 = this.endAngle;
Qm.Utils.EQ(Math.abs(n2 - o2), Qm.PIx2) && (o2 = n2), Math.abs(n2) > Qm.PIx2 && (n2 -= Math.trunc(n2 / Qm.PIx2) * Qm.PIx2), n2 < 0 && (n2 += Qm.PIx2), Math.abs(o2) > Qm.PIx2 && (o2 -= Math.trunc(o2 / Qm.PIx2) * Qm.PIx2), o2 < 0 && (o2 += Qm.PIx2);
let i2, r2, s2, a2 = n2;
this.counterClockwise ? (r2 = Math.ceil(n2 / (Math.PI / 2)) % 4, s2 = 1) : (r2 = Math.floor(n2 / (Math.PI / 2)) % 4, s2 = -1);
for (let o3 = 0, c2 = r2;o3 < 4; o3++, c2 = (c2 + s2 + 4) % 4) {
if (i2 = t2[c2], i2 === a2)
continue;
let o4 = this.counterClockwise ? i2 - n2 : n2 - i2;
if (o4 < 0 && (o4 += Qm.PIx2), o4 > this.sweep)
break;
e26.push(new Qm.Arc(this.pc, this.r, a2, i2, this.counterClockwise)), a2 = i2;
}
return e26.length === 0 ? (e26.push(this), e26) : (i2 = o2, a2 !== i2 && e26.push(new Qm.Arc(this.pc, this.r, a2, i2, this.counterClockwise)), e26);
}
tangentInStart() {
let e26 = new Qm.Vector(this.pc, this.start), t2 = this.counterClockwise ? Math.PI / 2 : -Math.PI / 2;
return e26.rotate(t2).normalize();
}
tangentInEnd() {
let e26 = new Qm.Vector(this.pc, this.end), t2 = this.counterClockwise ? -Math.PI / 2 : Math.PI / 2;
return e26.rotate(t2).normalize();
}
reverse() {
return new Qm.Arc(this.pc, this.r, this.endAngle, this.startAngle, !this.counterClockwise);
}
transform(e26 = new Qm.Matrix) {
let t2 = this.start.transform(e26), n2 = this.end.transform(e26), o2 = this.pc.transform(e26), i2 = this.counterClockwise;
return e26.a * e26.d < 0 && (i2 = !i2), Qm.Arc.arcSE(o2, t2, n2, i2);
}
static arcSE(e26, t2, n2, o2) {
let { vector: i2 } = Qm, r2 = i2(e26, t2).slope, s2 = i2(e26, n2).slope;
Qm.Utils.EQ(r2, s2) && (s2 += 2 * Math.PI, o2 = true);
let a2 = i2(e26, t2).length;
return new Qm.Arc(e26, a2, r2, s2, o2);
}
definiteIntegral(e26 = 0) {
return this.breakToFunctional().reduce((t2, n2) => t2 + n2.circularSegmentDefiniteIntegral(e26), 0);
}
circularSegmentDefiniteIntegral(e26) {
let t2 = new Qm.Segment(this.start, this.end).definiteIntegral(e26), n2 = Qm.Utils.EQ(this.sweep, Qm.PIx2) ? 0 : this.circularSegmentArea();
return this.counterClockwise ? t2 - n2 : t2 + n2;
}
circularSegmentArea() {
return 0.5 * this.r * this.r * (this.sweep - Math.sin(this.sweep));
}
sortPoints(e26) {
let { vector: t2 } = Qm;
return e26.slice().sort((e27, n2) => {
let o2 = t2(this.pc, e27).slope, i2 = t2(this.pc, n2).slope;
return o2 < i2 ? -1 : o2 > i2 ? 1 : 0;
});
}
get name() {
return "arc";
}
svg(e26 = {}) {
let t2 = this.sweep <= Math.PI ? "0" : "1", n2 = this.counterClockwise ? "1" : "0";
if (Qm.Utils.EQ(this.sweep, 2 * Math.PI)) {
return new Qm.Circle(this.pc, this.r).svg(e26);
}
return `
<path d="M${this.start.x},${this.start.y}
A${this.r},${this.r} 0 ${t2},${n2} ${this.end.x},${this.end.y}"
${og({ fill: "none", ...e26 })} />`;
}
};
Qm.Arc = qf;
Qm.arc = (...e26) => new Qm.Arc(...e26);
var Jf = class e26 extends jf {
constructor(e27 = undefined, t2 = undefined, n2 = undefined, o2 = undefined) {
super(), this.xmin = e27, this.ymin = t2, this.xmax = n2, this.ymax = o2;
}
clone() {
return new e26(this.xmin, this.ymin, this.xmax, this.ymax);
}
get low() {
return new Qm.Point(this.xmin, this.ymin);
}
get high() {
return new Qm.Point(this.xmax, this.ymax);
}
get max() {
return this.clone();
}
get center() {
return new Qm.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(e27) {
return this.xmax < e27.xmin || this.xmin > e27.xmax || this.ymax < e27.ymin || this.ymin > e27.ymax;
}
intersect(e27) {
return !this.not_intersect(e27);
}
merge(t2) {
return new e26(this.xmin === undefined ? t2.xmin : Math.min(this.xmin, t2.xmin), this.ymin === undefined ? t2.ymin : Math.min(this.ymin, t2.ymin), this.xmax === undefined ? t2.xmax : Math.max(this.xmax, t2.xmax), this.ymax === undefined ? t2.ymax : Math.max(this.ymax, t2.ymax));
}
less_than(e27) {
return !!this.low.lessThan(e27.low) || !(!this.low.equalTo(e27.low) || !this.high.lessThan(e27.high));
}
equal_to(e27) {
return this.low.equalTo(e27.low) && this.high.equalTo(e27.high);
}
output() {
return this.clone();
}
comparable_less_than(e27, t2) {
return e27.lessThan(t2);
}
set(e27, t2, n2, o2) {
this.xmin = e27, this.ymin = t2, this.xmax = n2, this.ymax = o2;
}
extend(t2) {
return t2 <= 0 ? this.clone() : new e26(this.xmin - t2, this.ymin - t2, this.xmax + t2, this.ymax + t2);
}
toPoints() {
return [new Qm.Point(this.xmin, this.ymin), new Qm.Point(this.xmax, this.ymin), new Qm.Point(this.xmax, this.ymax), new Qm.Point(this.xmin, this.ymax)];
}
toSegments() {
let e27 = this.toPoints();
return [new Qm.Segment(e27[0], e27[1]), new Qm.Segment(e27[1], e27[2]), new Qm.Segment(e27[2], e27[3]), new Qm.Segment(e27[3], e27[0])];
}
rotate(e27, t2 = new Qm.Point) {
throw Km.OPERATION_IS_NOT_SUPPORTED;
}
transform(t2 = new Qm.Matrix) {
return this.toPoints().map((e27) => e27.transform(t2)).reduce((e27, t3) => e27.merge(t3.box), new e26);
}
contains(e27) {
return e27 instanceof Qm.Point ? e27.x >= this.xmin && e27.x <= this.xmax && e27.y >= this.ymin && e27.y <= this.ymax : e27 instanceof Qm.Segment ? e27.vertices.every((e28) => this.contains(e28)) : e27 instanceof Qm.Box ? e27.toSegments().every((e28) => this.contains(e28)) : e27 instanceof Qm.Circle ? this.contains(e27.box) : e27 instanceof Qm.Arc ? e27.vertices.every((e28) => this.contains(e28)) && this.toSegments().every((t2) => pg(t2, e27).length === 0) : !(e27 instanceof Qm.Line || e27 instanceof Qm.Ray) && (e27 instanceof Qm.Multiline ? e27.toShapes().every((e28) => this.contains(e28)) : e27 instanceof Qm.Polygon ? this.contains(e27.box) : undefined);
}
distanceTo(e27) {
const t2 = this.toSegments().map((t3) => t3.distanceTo(e27));
let n2 = [Number.MAX_SAFE_INTEGER, null];
return t2.forEach((e28) => {
e28[0] < n2[0] && (n2 = e28);
}), n2;
}
get name() {
return "box";
}
svg(e27 = {}) {
const t2 = this.xmax - this.xmin, n2 = this.ymax - this.ymin;
return `
<rect x="${this.xmin}" y="${this.ymin}" width="${t2}" height="${n2}"
${og({ fill: "none", ...e27 })} />`;
}
};
Qm.Box = Jf;
Qm.box = (...e27) => new Qm.Box(...e27);
Qm.Edge = class {
constructor(e27) {
this.shape = e27, this.next = undefined, this.prev = undefined, this.face = undefined, this.arc_length = 0, this.bvStart = undefined, this.bvEnd = undefined, this.bv = undefined, this.overlap = undefined;
}
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 Qm.Segment;
}
get isArc() {
return this.shape instanceof Qm.Arc;
}
get isLine() {
return this.shape instanceof Qm.Line;
}
get isRay() {
return this.shape instanceof Qm.Ray;
}
middle() {
return this.shape.middle();
}
pointAtLength(e27) {
return this.shape.pointAtLength(e27);
}
contains(e27) {
return this.shape.contains(e27);
}
setInclusion(e27) {
if (this.bv !== undefined)
return this.bv;
if (this.shape instanceof Qm.Line || this.shape instanceof Qm.Ray)
return this.bv = Qm.OUTSIDE, this.bv;
if (this.bvStart === undefined && (this.bvStart = Pf(e27, this.start)), this.bvEnd === undefined && (this.bvEnd = Pf(e27, this.end)), this.bvStart === Qm.OUTSIDE || this.bvEnd == Qm.OUTSIDE)
this.bv = Qm.OUTSIDE;
else if (this.bvStart === Qm.INSIDE || this.bvEnd == Qm.INSIDE)
this.bv = Qm.INSIDE;
else {
let t2 = Pf(e27, this.middle());
this.bv = t2;
}
return this.bv;
}
setOverlap(e27) {
let t2, n2 = this.shape, o2 = e27.shape;
n2 instanceof Qm.Segment && o2 instanceof Qm.Segment ? n2.start.equalTo(o2.start) && n2.end.equalTo(o2.end) ? t2 = Qm.OVERLAP_SAME : n2.start.equalTo(o2.end) && n2.end.equalTo(o2.start) && (t2 = Qm.OVERLAP_OPPOSITE) : (n2 instanceof Qm.Arc && o2 instanceof Qm.Arc || n2 instanceof Qm.Segment && o2 instanceof Qm.Arc || n2 instanceof Qm.Arc && o2 instanceof Qm.Segment) && (n2.start.equalTo(o2.start) && n2.end.equalTo(o2.end) && n2.middle().equalTo(o2.middle()) ? t2 = Qm.OVERLAP_SAME : n2.start.equalTo(o2.end) && n2.end.equalTo(o2.start) && n2.middle().equalTo(o2.middle()) && (t2 = Qm.OVERLAP_OPPOSITE)), this.overlap === undefined && (this.overlap = t2), e27.overlap === undefined && (e27.overlap = t2);
}
svg() {
if (this.shape instanceof Qm.Segment)
return ` L${this.shape.end.x},${this.shape.end.y}`;
if (this.shape instanceof Qm.Arc) {
let e27, t2 = this.shape, n2 = t2.counterClockwise ? "1" : "0";
if (Qm.Utils.EQ(t2.sweep, 2 * Math.PI)) {
let o2 = t2.counterClockwise ? 1 : -1, i2 = new Qm.Arc(t2.pc, t2.r, t2.startAngle, t2.startAngle + o2 * Math.PI, t2.counterClockwise), r2 = new Qm.Arc(t2.pc, t2.r, t2.startAngle + o2 * Math.PI, t2.endAngle, t2.counterClockwise);
return e27 = "0", ` A${i2.r},${i2.r} 0 ${e27},${n2} ${i2.end.x},${i2.end.y}
A${r2.r},${r2.r} 0 ${e27},${n2} ${r2.end.x},${r2.end.y}`;
}
return e27 = t2.sweep <= Math.PI ? "0" : "1", ` A${t2.r},${t2.r} 0 ${e27},${n2} ${t2.end.x},${t2.end.y}`;
}
}
toJSON() {
return this.shape.toJSON();
}
};
var Qf = class extends eg {
constructor(e27, t2) {
super(e27, t2), this.setCircularLinks();
}
setCircularLinks() {
this.isEmpty() || (this.last.next = this.first, this.first.prev = this.last);
}
[Symbol.iterator]() {
let e27;
return { next: () => {
let t2 = e27 || this.first, n2 = !this.first || !!e27 && e27 === this.first;
return e27 = t2 ? t2.next : undefined, { value: t2, done: n2 };
} };
}
append(e27) {
return super.append(e27), this.setCircularLinks(), this;
}
insert(e27, t2) {
return super.insert(e27, t2), this.setCircularLinks(), this;
}
remove(e27) {
return super.remove(e27), this;
}
};
Qm.Face = class e27 extends Qf {
constructor(t2, ...n2) {
if (super(), this._box = undefined, this._orientation = undefined, n2.length !== 0) {
if (n2.length === 1) {
if (n2[0] instanceof Array) {
let o2 = n2[0];
if (o2.length === 0)
return;
if (o2.every((e28) => e28 instanceof Qm.Point)) {
let n3 = e27.points2segments(o2);
this.shapes2face(t2.edges, n3);
} else if (o2.every((e28) => e28 instanceof Array && e28.length === 2)) {
let n3 = o2.map((e28) => new Qm.Point(e28[0], e28[1])), i2 = e27.points2segments(n3);
this.shapes2face(t2.edges, i2);
} else if (o2.every((e28) => e28 instanceof Qm.Segment || e28 instanceof Qm.Arc))
this.shapes2face(t2.edges, o2);
else if (o2.every((e28) => e28.name === "segment" || e28.name === "arc")) {
let e28 = [];
for (let t3 of o2) {
let n3;
n3 = t3.name === "segment" ? new Qm.Segment(t3) : new Qm.Arc(t3), e28.push(n3);
}
this.shapes2face(t2.edges, e28);
}
} else if (n2[0] instanceof e27) {
let e28 = n2[0];
this.first = e28.first, this.last = e28.last;
for (let n3 of e28)
t2.edges.add(n3);
} else if (n2[0] instanceof Qm.Circle)
this.shapes2face(t2.edges, [n2[0].toArc($m)]);
else if (n2[0] instanceof Qm.Box) {
let e28 = n2[0];
this.shapes2face(t2.edges, [new Qm.Segment(new Qm.Point(e28.xmin, e28.ymin), new Qm.Point(e28.xmax, e28.ymin)), new Qm.Segment(new Qm.Point(e28.xmax, e28.ymin), new Qm.Point(e28.xmax, e28.ymax)), new Qm.Segment(new Qm.Point(e28.xmax, e28.ymax), new Qm.Point(e28.xmin, e28.ymax)), new Qm.Segment(new Qm.Point(e28.xmin, e28.ymax), new Qm.Point(e28.xmin, e28.ymin))]);
}
}
n2.length === 2 && n2[0] instanceof Qm.Edge && n2[1] instanceof Qm.Edge && (this.first = n2[0], this.last = n2[1], this.last.next = this.first, this.first.prev = this.last, this.setArcLength());
}
}
get edges() {
return this.toArray();
}
get vertices() {
return this.edges.map((e28) => e28.shape.start.clone());
}
get shapes() {
return this.edges.map((e28) => e28.shape.clone());
}
get box() {
if (this._box === undefined) {
let e28 = new Qm.Box;
for (let t2 of this)
e28 = e28.merge(t2.box);
this._box = e28;
}
return this._box;
}
get perimeter() {
return this.last.arc_length + this.last.length;
}
pointAtLength(e28) {
if (e28 > this.perimeter || e28 < 0)
return null;
let t2 = null;
for (let n2 of this)
if (e28 >= n2.arc_length && (n2 === this.last || e28 < n2.next.arc_length)) {
t2 = n2.pointAtLength(e28 - n2.arc_length);
break;
}
return t2;
}
static points2segments(e28) {
let t2 = [];
for (let n2 = 0;n2 < e28.length; n2++)
e28[n2].equalTo(e28[(n2 + 1) % e28.length]) || t2.push(new Qm.Segment(e28[n2], e28[(n2 + 1) % e28.length]));
return t2;
}
shapes2face(e28, t2) {
for (let n2 of t2) {
let t3 = new Qm.Edge(n2);
this.append(t3), e28.add(t3);
}
}
append(e28) {
return super.append(e28), this.setOneEdgeArcLength(e28), e28.face = this, this;
}
insert(e28, t2) {
return super.insert(e28, t2), this.setOneEdgeArcLength(e28), e28.face = this, this;
}
remove(e28) {
return super.remove(e28), this.setArcLength(), this;
}
merge_with_next_edge(e28) {
return e28.shape.end.x = e28.next.shape.end.x, e28.shape.end.y = e28.next.shape.end.y, this.remove(e28.next), this;
}
reverse() {
let e28 = [], t2 = this.last;
do {
t2.shape = t2.shape.reverse(), e28.push(t2), t2 = t2.prev;
} while (t2 !== this.last);
this.first = undefined, this.last = undefined;
for (let t3 of e28)
this.first === undefined ? (t3.prev = t3, t3.next = t3, this.first = t3, this.last = t3) : (t3.prev = this.last, this.last.next = t3, this.last = t3, this.last.next = this.first, this.first.prev = this.last), this.setOneEdgeArcLength(t3);
this._orientation !== undefined && (this._orientation = undefined, this._orientation = this.orientation());
}
setArcLength() {
for (let e28 of this)
this.setOneEdgeArcLength(e28), e28.face = this;
}
setOneEdgeArcLength(e28) {
e28 === this.first ? e28.arc_length = 0 : e28.arc_length = e28.prev.arc_length + e28.prev.length;
}
area() {
return Math.abs(this.signedArea());
}
signedArea() {
let e28 = 0, t2 = this.box.ymin;
for (let n2 of this)
e28 += n2.shape.definiteIntegral(t2);
return e28;
}
orientation() {
if (this._orientation === undefined) {
let e28 = this.signedArea();
Qm.Utils.EQ_0(e28) ? this._orientation = Ym.NOT_ORIENTABLE : Qm.Utils.LT(e28, 0) ? this._orientation = Ym.CCW : this._orientation = Ym.CW;
}
return this._orientation;
}
isSimple(t2) {
return e27.getSelfIntersections(this, t2, true).length === 0;
}
static getSelfIntersections(e28, t2, n2 = false) {
let o2 = [];
for (let i2 of e28) {
let r2 = t2.search(i2.box);
for (let t3 of r2) {
if (i2 === t3)
continue;
if (t3.face !== e28)
continue;
if (i2.shape instanceof Qm.Segment && t3.shape instanceof Qm.Segment && (i2.next === t3 || i2.prev === t3))
continue;
let r3 = i2.shape.intersect(t3.shape);
for (let e29 of r3)
if ((!e29.equalTo(i2.start) || !e29.equalTo(t3.end) || t3 !== i2.prev) && (!e29.equalTo(i2.end) || !e29.equalTo(t3.start) || t3 !== i2.next) && (o2.push(e29), n2))
break;
if (o2.length > 0 && n2)
break;
}
if (o2.length > 0 && n2)
break;
}
return o2;
}
findEdgeByPoint(e28) {
let t2;
for (let n2 of this)
if (!e28.equalTo(n2.shape.start) && (e28.equalTo(n2.shape.end) || n2.shape.contains(e28))) {
t2 = n2;
break;
}
return t2;
}
toPolygon() {
return new Qm.Polygon(this.shapes);
}
toJSON() {
return this.edges.map((e28) => e28.toJSON());
}
svg() {
let e28 = `M${this.first.start.x},${this.first.start.y}`;
for (let t2 of this)
e28 += t2.svg();
return e28 += " z", e28;
}
};
Qm.Ray = class e28 extends jf {
constructor(...e29) {
if (super(), this.pt = new Qm.Point, this.norm = new Qm.Vector(0, 1), e29.length !== 0 && (e29.length >= 1 && e29[0] instanceof Qm.Point && (this.pt = e29[0].clone()), e29.length !== 1)) {
if (!(e29.length === 2 && e29[1] instanceof Qm.Vector))
throw Km.ILLEGAL_PARAMETERS;
this.norm = e29[1].clone();
}
}
clone() {
return new e28(this.pt, this.norm);
}
get slope() {
return new Qm.Vector(this.norm.y, -this.norm.x).slope;
}
get box() {
let e29 = this.slope;
return new Qm.Box(e29 > Math.PI / 2 && e29 < 3 * Math.PI / 2 ? Number.NEGATIVE_INFINITY : this.pt.x, e29 >= 0 && e29 <= Math.PI ? this.pt.y : Number.NEGATIVE_INFINITY, e29 >= Math.PI / 2 && e29 <= 3 * Math.PI / 2 ? this.pt.x : Number.POSITIVE_INFINITY, e29 >= Math.PI && e29 <= 2 * Math.PI || e29 === 0 ? this.pt.y : Number.POSITIVE_INFINITY);
}
get start() {
return this.pt;
}
get end() {}
get length() {
return Number.POSITIVE_INFINITY;
}
contains(e29) {
if (this.pt.equalTo(e29))
return true;
let t2 = new Qm.Vector(this.pt, e29);
return Qm.Utils.EQ_0(this.norm.dot(t2)) && Qm.Utils.GE(t2.cross(this.norm), 0);
}
coord(e29) {
return Wf(e29.x, e29.y).cross(this.norm);
}
split(e29) {
return this.contains(e29) ? this.pt.equalTo(e29) ? [this] : [new Qm.Segment(this.pt, e29), new Qm.Ray(e29, this.norm)] : [];
}
intersect(e29) {
return e29 instanceof Qm.Point ? this.contains(e29) ? [e29] : [] : e29 instanceof Qm.Segment ? Tg(this, e29) : e29 instanceof Qm.Arc ? Rg(this, e29) : e29 instanceof Qm.Line ? Ag(this, e29) : e29 instanceof Qm.Ray ? (n2 = e29, ig(Ng(t2 = this), Ng(n2)).filter((e30) => t2.contains(e30)).filter((e30) => n2.contains(e30))) : e29 instanceof Qm.Circle ? Eg(this, e29) : e29 instanceof Qm.Box ? (i2 = e29, sg(Ng(o2 = this), i2).filter((e30) => o2.contains(e30))) : e29 instanceof Qm.Polygon ? Og(this, e29) : e29 instanceof Qm.Multiline ? Dg(this, e29) : undefined;
var t2, n2, o2, i2;
}
rotate(e29, t2 = new Qm.Point) {
return new Qm.Ray(this.pt.rotate(e29, t2), this.norm.rotate(e29));
}
transform(e29) {
return new Qm.Ray(this.pt.transform(e29), this.norm.clone());
}
get name() {
return "ray";
}
svg(e29, t2 = {}) {
let n2 = sg(new Qm.Line(this.pt, this.norm), e29);
return n2 = n2.filter((e30) => this.contains(e30)), n2.length === 0 || n2.length === 2 ? "" : new Qm.Segment(this.pt, n2[0]).svg(t2);
}
};
Qm.ray = (...e29) => new Qm.Ray(...e29);
var Kf = class e29 {
constructor() {
this.faces = new Qm.PlanarSet, this.edges = new Qm.PlanarSet;
let e30 = [...arguments];
if (e30.length === 1 && (e30[0] instanceof Array && e30[0].length > 0 || e30[0] instanceof Qm.Circle || e30[0] instanceof Qm.Box)) {
let t2 = e30[0];
if (e30[0] instanceof Array && e30[0].every((e31) => e31 instanceof Array))
if (t2.every((e31) => e31 instanceof Array && e31.length === 2 && typeof e31[0] == "number" && typeof e31[1] == "number"))
this.faces.add(new Qm.Face(this, t2));
else
for (let e31 of t2)
if (e31 instanceof Array && e31[0] instanceof Array && e31[0].every((e32) => e32 instanceof Array && e32.length === 2 && typeof e32[0] == "number" && typeof e32[1] == "number"))
for (let t3 of e31)
this.faces.add(new Qm.Face(this, t3));
else
this.faces.add(new Qm.Face(this, e31));
else
this.faces.add(new Qm.Face(this, t2));
}
}
get box() {
return [...this.faces].reduce((e30, t2) => e30.merge(t2.box), new Qm.Box);
}
get vertices() {
return [...this.faces].flatMap((e30) => e30.vertices);
}
clone() {
let t2 = new e29;
for (let e30 of this.faces)
t2.addFace(e30.shapes);
return t2;
}
createFromArray(t2) {
const n2 = new e29;
return t2.forEach((e30) => [...e30.faces].forEach((e31) => n2.addFace(e31.shapes))), n2;
}
isEmpty() {
return this.edges.size === 0 || this.faces.size === 0;
}
isValid() {
let e30 = true;
for (let t2 of this.faces)
if (!t2.isSimple(this.edges)) {
e30 = false;
break;
}
return e30;
}
area() {
let e30 = [...this.faces].reduce((e31, t2) => e31 + t2.signedArea(), 0);
return Math.abs(e30);
}
addFace(...e30) {
let t2 = new Qm.Face(this, ...e30);
return this.faces.add(t2), t2;
}
deleteFace(e30) {
for (let t2 of e30)
this.edges.delete(t2);
return this.faces.delete(e30);
}
recreateFaces() {
this.faces.clear();
for (let e31 of this.edges)
e31.face = null;
let e30, t2 = true;
for (;t2; ) {
t2 = false;
for (let n2 of this.edges)
if (n2.face === null) {
e30 = n2, t2 = true;
break;
}
if (t2) {
let t3 = e30;
do {
t3 = t3.next;
} while (t3.next !== e30);
this.addFace(e30, t3);
}
}
}
removeChain(e30, t2, n2) {
if (n2.next !== t2) {
for (let o2 = t2;o2 !== n2.next; o2 = o2.next)
if (e30.remove(o2), this.edges.delete(o2), e30.isEmpty()) {
this.deleteFace(e30);
break;
}
} else
this.deleteFace(e30);
}
addVertex(e30, t2) {
let n2 = t2.shape.split(e30);
if (n2[0] === null)
return t2.prev;
if (n2[1] === null)
return t2;
let o2 = new Qm.Edge(n2[0]), i2 = t2.prev;
return t2.face.insert(o2, i2), this.edges.delete(t2), this.edges.add(o2), t2.shape = n2[1], this.edges.add(t2), o2;
}
removeEndVertex(e30) {
const t2 = e30.next;
t2 !== e30 && (e30.face.merge_with_next_edge(e30), this.edges.delete(t2));
}
cut(e30) {
const t2 = this.splitToIslands().flatMap((t3) => t3._cutSingleIsland(e30)).filter((e31) => e31.isValid() && e31.isEmpty() === false);
return this.createFromArray(t2);
}
_cutSingleIsland(e30) {
let t2 = this.clone();
const n2 = e30.clone();
let o2, i2, r2 = { int_points1: [], int_points2: [], int_points1_sorted: [], int_points2_sorted: [] };
for (let e31 of n2.edges)
for (let n3 of t2.edges) {
let t3 = Pg(e31, n3);
for (let o3 of t3)
zg(e31, o3, r2.int_points1), zg(n3, o3, r2.int_points2);
}
if (r2.int_points1.length === 0)
return t2;
r2.int_points1_sorted = Fg(r2.int_points1), r2.int_points2_sorted = Fg(r2.int_points2), Vg(n2, r2.int_points1_sorted), Vg(t2, r2.int_points2_sorted), $g(r2), r2.int_points1_sorted = Fg(r2.int_points1), r2.int_points2_sorted = Fg(r2.int_points2), Yg(r2.int_points1), Xg(r2.int_points1, t2);
for (let e31 of r2.int_points1_sorted)
e31.edge_before && e31.edge_after && e31.edge_before.bv === e31.edge_after.bv && (r2.int_points2[e31.id] = -1, e31.id = -1);
if (r2.int_points1 = r2.int_points1.filter((e31) => e31.id >= 0), r2.int_points2 = r2.int_points2.filter((e31) => e31.id >= 0), r2.int_points1.forEach((e31, t3) => {
e31.id = t3;
}), r2.int_points2.forEach((e31, t3) => {
e31.id = t3;
}), r2.int_points1.length === 0)
return t2;
r2.int_points1_sorted = Fg(r2.int_points1), r2.int_points2_sorted = Fg(r2.int_points2);
for (let e31 = 1;e31 < r2.int_points1_sorted.length; e31++)
if (i2 = r2.int_points1_sorted[e31], o2 = r2.int_points1_sorted[e31 - 1], i2.edge_before && i2.edge_before.bv === 1) {
let e32 = o2.edge_after, s2 = i2.edge_before, a2 = n2.getChain(e32, s2);
Hg(r2.int_points2[o2.id], r2.int_points2[i2.id], a2), a2.forEach((e33) => t2.edges.add(e33)), a2 = a2.reverse().map((e33) => new Qm.Edge(e33.shape.reverse()));
for (let e33 = 0;e33 < a2.length - 1; e33++)
a2[e33].next = a2[e33 + 1], a2[e33 + 1].prev = a2[e33];
Hg(r2.int_points2[i2.id], r2.int_points2[o2.id], a2), a2.forEach((e33) => t2.edges.add(e33));
}
return t2.recreateFaces(), t2;
}
cutWithLine(e30) {
let t2 = new Lg([e30]);
return this.cut(t2);
}
findEdgeByPoint(e30) {
let t2;
for (let n2 of this.faces)
if (t2 = n2.findEdgeByPoint(e30), t2 !== undefined)
break;
return t2;
}
splitToIslands() {
if (this.isEmpty())
return [];
let e30 = this.toArray();
e30.sort((e31, t3) => t3.area() - e31.area());
let t2 = [...e30[0].faces][0].orientation(), n2 = e30.filter((e31) => [...e31.faces][0].orientation() === t2);
for (let o2 of e30) {
let e31 = [...o2.faces][0];
if (e31.orientation() !== t2) {
for (let t3 of n2)
if (e31.shapes.every((e32) => t3.contains(e32))) {
t3.addFace(e31.shapes);
break;
}
}
}
return n2;
}
rearrange() {
if (this.faces.size <= 1)
return this.clone();
const t2 = this.splitToIslands(), n2 = new e29;
return t2.forEach((e30) => {
e30.faces.forEach((e31) => n2.addFace(e31.shapes));
}), n2;
}
orientation() {
return this.isEmpty() ? Ym.NOT_ORIENTABLE : [...this.faces][0].orientation();
}
isOuter(e30) {
return e30.orientation() === this.orientation();
}
isMultiPolygon() {
let e30 = 0;
return this.faces.forEach((t2) => {
this.isOuter(t2) && e30++;
}), e30 > 1;
}
reverse() {
for (let e30 of this.faces)
e30.reverse();
return this;
}
contains(e30) {
if (e30 instanceof Qm.Point) {
let t2 = Pf(this, e30);
return t2 === 1 || t2 === 2;
}
return Tf(this, e30);
}
distanceTo(e30) {
if (e30 instanceof Qm.Point) {
let [t2, n2] = Qm.Distance.point2polygon(e30, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e30 instanceof Qm.Circle || e30 instanceof Qm.Line || e30 instanceof Qm.Segment || e30 instanceof Qm.Arc) {
let [t2, n2] = Qm.Distance.shape2polygon(e30, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e30 instanceof Qm.Box)
return this.distanceTo(new Qm.Polygon(e30));
if (e30 instanceof Qm.Polygon) {
let t2, n2, o2 = [Number.POSITIVE_INFINITY, new Qm.Segment];
for (let i2 of this.edges) {
let r2 = o2[0];
[t2, n2] = Qm.Distance.shape2planarSet(i2.shape, e30.edges, r2), Qm.Utils.LT(t2, r2) && (o2 = [t2, n2]);
}
return o2;
}
}
intersect(e30) {
return e30 instanceof Qm.Point ? this.contains(e30) ? [e30] : [] : e30 instanceof Qm.Line ? Sg(e30, this) : e30 instanceof Qm.Ray ? Og(e30, this) : e30 instanceof Qm.Circle ? Cg(e30, this) : e30 instanceof Qm.Segment ? vg(e30, this) : e30 instanceof Qm.Arc ? Ig(e30, this) : e30 instanceof Qm.Polygon ? function(e31, t2) {
let n2 = [];
if (e31.isEmpty() || t2.isEmpty())
return n2;
if (e31.box.not_intersect(t2.box))
return n2;
for (let o2 of e31.edges)
n2 = [...n2, ...Mg(o2, t2)];
return n2;
}(e30, this) : e30 instanceof Qm.Multiline ? function(e31, t2) {
let n2 = [];
if (t2.isEmpty() || e31.size === 0)
return n2;
for (let o2 of e31)
n2 = [...n2, ...Mg(o2, t2)];
return n2;
}(e30, this) : undefined;
}
translate(t2) {
let n2 = new e29;
for (let e30 of this.faces)
n2.addFace(e30.shapes.map((e31) => e31.translate(t2)));
return n2;
}
rotate(t2 = 0, n2 = new Qm.Point) {
let o2 = new e29;
for (let e30 of this.faces)
o2.addFace(e30.shapes.map((e31) => e31.rotate(t2, n2)));
return o2;
}
scale(t2, n2) {
let o2 = new e29;
for (let e30 of this.faces)
o2.addFace(e30.shapes.map((e31) => e31.scale(t2, n2)));
return o2;
}
transform(t2 = new Qm.Matrix) {
let n2 = new e29;
for (let e30 of this.faces)
n2.addFace(e30.shapes.map((e31) => e31.transform(t2)));
return n2;
}
toJSON() {
return [...this.faces].map((e30) => e30.toJSON());
}
toArray() {
return [...this.faces].map((e30) => e30.toPolygon());
}
dpath() {
return [...this.faces].reduce((e30, t2) => e30 + t2.svg(), "");
}
svg(e30 = {}) {
let t2 = `
<path ${og({ fillRule: "evenodd", fill: "lightcyan", ...e30 })} d="`;
for (let e31 of this.faces)
t2 += `
${e31.svg()}`;
return t2 += `" >
</path>`, t2;
}
};
Qm.Polygon = Kf;
Qm.polygon = (...e30) => new Qm.Polygon(...e30);
var { Circle: e_, Line: t_, Point: n_, Vector: o_, Utils: i_ } = Qm;
Qm.Inversion = class e30 {
constructor(e31) {
this.circle = e31;
}
get inversion_circle() {
return this.circle;
}
static inversePoint(e31, t2) {
const n2 = new o_(e31.pc, t2), o2 = e31.r * e31.r, i2 = n2.dot(n2);
return i_.EQ_0(i2) ? new n_(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY) : e31.pc.translate(n2.multiply(o2 / i2));
}
static inverseCircle(e31, t2) {
const n2 = e31.pc.distanceTo(t2.pc)[0];
if (i_.EQ(n2, t2.r)) {
let n3 = e31.r * e31.r / (2 * t2.r), o2 = new o_(e31.pc, t2.pc);
o2 = o2.normalize();
let i2 = e31.pc.translate(o2.multiply(n3));
return new t_(i2, o2);
}
{
let n3 = new o_(e31.pc, t2.pc), o2 = e31.r * e31.r / (n3.dot(n3) - t2.r * t2.r), i2 = e31.pc.translate(n3.multiply(o2)), r2 = Math.abs(o2) * t2.r;
return new e_(i2, r2);
}
}
static inverseLine(e31, t2) {
const [n2, o2] = e31.pc.distanceTo(t2);
if (i_.EQ_0(n2))
return t2.clone();
{
let t3 = e31.r * e31.r / (2 * n2), i2 = new o_(e31.pc, o2.end);
return i2 = i2.multiply(t3 / n2), new e_(e31.pc.translate(i2), t3);
}
}
inverse(t2) {
return t2 instanceof n_ ? e30.inversePoint(this.circle, t2) : t2 instanceof e_ ? e30.inverseCircle(this.circle, t2) : t2 instanceof t_ ? e30.inverseLine(this.circle, t2) : undefined;
}
};
Qm.inversion = (e31) => new Qm.Inversion(e31);
Qm.Distance = class e31 {
static point2point(e32, t2) {
return e32.distanceTo(t2);
}
static point2line(e32, t2) {
let n2 = e32.projectionOn(t2);
return [new Qm.Vector(e32, n2).length, new Qm.Segment(e32, n2)];
}
static point2circle(e32, t2) {
let [n2, o2] = e32.distanceTo(t2.center);
if (Qm.Utils.EQ_0(n2))
return [t2.r, new Qm.Segment(e32, t2.toArc().start)];
{
let o3 = Math.abs(n2 - t2.r), i2 = new Qm.Vector(t2.pc, e32).normalize().multiply(t2.r), r2 = t2.pc.translate(i2);
return [o3, new Qm.Segment(e32, r2)];
}
}
static point2segment(t2, n2) {
if (n2.start.equalTo(n2.end))
return e31.point2point(t2, n2.start);
let o2, i2, r2 = new Qm.Vector(n2.start, n2.end), s2 = new Qm.Vector(n2.start, t2), a2 = new Qm.Vector(n2.end, t2), c2 = r2.dot(s2), l2 = -r2.dot(a2);
if (Qm.Utils.GE(c2, 0) && Qm.Utils.GE(l2, 0)) {
let e32 = n2.tangentInStart();
return o2 = Math.abs(e32.cross(s2)), i2 = n2.start.translate(e32.multiply(e32.dot(s2))), [o2, new Qm.Segment(t2, i2)];
}
return c2 < 0 ? t2.distanceTo(n2.start) : t2.distanceTo(n2.end);
}
static point2arc(t2, n2) {
let o2, i2, r2 = new Qm.Circle(n2.pc, n2.r), s2 = [];
return [o2, i2] = e31.point2circle(t2, r2), i2.end.on(n2) && s2.push(e31.point2circle(t2, r2)), s2.push(e31.point2point(t2, n2.start)), s2.push(e31.point2point(t2, n2.end)), e31.sort(s2), s2[0];
}
static point2edge(t2, n2) {
return n2.shape instanceof Qm.Segment ? e31.point2segment(t2, n2.shape) : e31.point2arc(t2, n2.shape);
}
static segment2line(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let i2 = [];
return i2.push(e31.point2line(t2.start, n2)), i2.push(e31.point2line(t2.end, n2)), e31.sort(i2), i2[0];
}
static segment2segment(t2, n2) {
let o2 = lg(t2, n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let i2, r2, s2 = [];
return [i2, r2] = e31.point2segment(n2.start, t2), s2.push([i2, r2.reverse()]), [i2, r2] = e31.point2segment(n2.end, t2), s2.push([i2, r2.reverse()]), s2.push(e31.point2segment(t2.start, n2)), s2.push(e31.point2segment(t2.end, n2)), e31.sort(s2), s2[0];
}
static segment2circle(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let i2 = new Qm.Line(t2.ps, t2.pe), [r2, s2] = e31.point2line(n2.center, i2);
if (Qm.Utils.GE(r2, n2.r) && s2.end.on(t2))
return e31.point2circle(s2.end, n2);
{
let [o3, i3] = e31.point2circle(t2.start, n2), [r3, s3] = e31.point2circle(t2.end, n2);
return Qm.Utils.LT(o3, r3) ? [o3, i3] : [r3, s3];
}
}
static segment2arc(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let i2 = new Qm.Line(t2.ps, t2.pe), r2 = new Qm.Circle(n2.pc, n2.r), [s2, a2] = e31.point2line(r2.center, i2);
if (Qm.Utils.GE(s2, r2.r) && a2.end.on(t2)) {
let [t3, o3] = e31.point2circle(a2.end, r2);
if (o3.end.on(n2))
return [t3, o3];
}
let c2, l2, h2 = [];
return h2.push(e31.point2arc(t2.start, n2)), h2.push(e31.point2arc(t2.end, n2)), [c2, l2] = e31.point2segment(n2.start, t2), h2.push([c2, l2.reverse()]), [c2, l2] = e31.point2segment(n2.end, t2), h2.push([c2, l2.reverse()]), e31.sort(h2), h2[0];
}
static circle2circle(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
if (t2.center.equalTo(n2.center)) {
let o3 = t2.toArc(), i2 = n2.toArc();
return e31.point2point(o3.start, i2.start);
}
{
let o3 = new Qm.Line(t2.center, n2.center), i2 = o3.intersect(t2), r2 = o3.intersect(n2), s2 = [];
return s2.push(e31.point2point(i2[0], r2[0])), s2.push(e31.point2point(i2[0], r2[1])), s2.push(e31.point2point(i2[1], r2[0])), s2.push(e31.point2point(i2[1], r2[1])), e31.sort(s2), s2[0];
}
}
static circle2line(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let [i2, r2] = e31.point2line(t2.center, n2), [s2, a2] = e31.point2circle(r2.end, t2);
return a2 = a2.reverse(), [s2, a2];
}
static arc2line(t2, n2) {
let o2 = n2.intersect(t2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let i2 = new Qm.Circle(t2.center, t2.r), [r2, s2] = e31.point2line(i2.center, n2);
if (!Qm.Utils.GE(r2, i2.r)) {
let o3 = [];
return o3.push(e31.point2line(t2.start, n2)), o3.push(e31.point2line(t2.end, n2)), e31.sort(o3), o3[0];
}
{
let [n3, o3] = e31.point2circle(s2.end, i2);
if (o3.end.on(t2))
return [n3, o3];
}
}
static arc2circle(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let i2 = new Qm.Circle(t2.center, t2.r), [r2, s2] = e31.circle2circle(i2, n2);
if (s2.start.on(t2))
return [r2, s2];
{
let o3 = [];
return o3.push(e31.point2circle(t2.start, n2)), o3.push(e31.point2circle(t2.end, n2)), e31.sort(o3), o3[0];
}
}
static arc2arc(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new Qm.Segment(o2[0], o2[0])];
let i2 = new Qm.Circle(t2.center, t2.r), r2 = new Qm.Circle(n2.center, n2.r), [s2, a2] = e31.circle2circle(i2, r2);
if (a2.start.on(t2) && a2.end.on(n2))
return [s2, a2];
{
let o3, i3, r3 = [];
return [o3, i3] = e31.point2arc(t2.start, n2), i3.end.on(n2) && r3.push([o3, i3]), [o3, i3] = e31.point2arc(t2.end, n2), i3.end.on(n2) && r3.push([o3, i3]), [o3, i3] = e31.point2arc(n2.start, t2), i3.end.on(t2) && r3.push([o3, i3.reverse()]), [o3, i3] = e31.point2arc(n2.end, t2), i3.end.on(t2) && r3.push([o3, i3.reverse()]), [o3, i3] = e31.point2point(t2.start, n2.start), r3.push([o3, i3]), [o3, i3] = e31.point2point(t2.start, n2.end), r3.push([o3, i3]), [o3, i3] = e31.point2point(t2.end, n2.start), r3.push([o3, i3]), [o3, i3] = e31.point2point(t2.end, n2.end), r3.push([o3, i3]), e31.sort(r3), r3[0];
}
}
static point2polygon(t2, n2) {
let o2 = [Number.POSITIVE_INFINITY, new Qm.Segment];
for (let i2 of n2.edges) {
let [n3, r2] = e31.point2edge(t2, i2);
Qm.Utils.LT(n3, o2[0]) && (o2 = [n3, r2]);
}
return o2;
}
static shape2polygon(e32, t2) {
let n2 = [Number.POSITIVE_INFINITY, new Qm.Segment];
for (let o2 of t2.edges) {
let [t3, i2] = e32.distanceTo(o2.shape);
Qm.Utils.LT(t3, n2[0]) && (n2 = [t3, i2]);
}
return n2;
}
static polygon2polygon(e32, t2) {
let n2 = [Number.POSITIVE_INFINITY, new Qm.Segment];
for (let o2 of e32.edges)
for (let e33 of t2.edges) {
let [t3, i2] = o2.shape.distanceTo(e33.shape);
Qm.Utils.LT(t3, n2[0]) && (n2 = [t3, i2]);
}
return n2;
}
static box2box_minmax(e32, t2) {
let n2 = Math.max(Math.max(e32.xmin - t2.xmax, 0), Math.max(t2.xmin - e32.xmax, 0)), o2 = Math.max(Math.max(e32.ymin - t2.ymax, 0), Math.max(t2.ymin - e32.ymax, 0)), i2 = n2 * n2 + o2 * o2, r2 = e32.merge(t2), s2 = r2.xmax - r2.xmin, a2 = r2.ymax - r2.ymin;
return [i2, s2 * s2 + a2 * a2];
}
static minmax_tree_process_level(t2, n2, o2, i2) {
let r2, s2;
for (let a3 of n2) {
[r2, s2] = e31.box2box_minmax(t2.box, a3.item.key);
for (let e32 of a3.item.values)
e32 instanceof Qm.Edge ? i2.insert([r2, s2], e32.shape) : i2.insert([r2, s2], e32);
Qm.Utils.LT(s2, o2) && (o2 = s2);
}
if (n2.length === 0)
return o2;
let a2 = [...n2.map((e32) => e32.left.isNil() ? undefined : e32.left).filter((e32) => e32 !== undefined), ...n2.map((e32) => e32.right.isNil() ? undefined : e32.right).filter((e32) => e32 !== undefined)].filter((n3) => {
let [i3, r3] = e31.box2box_minmax(t2.box, n3.max);
return Qm.Utils.LE(i3, o2);
});
return o2 = e31.minmax_tree_process_level(t2, a2, o2, i2);
}
static minmax_tree(t2, n2, o2) {
let i2 = new Bf, r2 = [n2.index.root], s2 = o2 < Number.POSITIVE_INFINITY ? o2 * o2 : Number.POSITIVE_INFINITY;
return s2 = e31.minmax_tree_process_level(t2, r2, s2, i2), i2;
}
static minmax_tree_calc_distance(t2, n2, o2) {
let i2, r2;
if (n2 != null && !n2.isNil()) {
if ([i2, r2] = e31.minmax_tree_calc_distance(t2, n2.left, o2), r2)
return [i2, r2];
if (Qm.Utils.LT(i2[0], Math.sqrt(n2.item.key.low)))
return [i2, true];
let [s2, a2] = e31.distanceToArray(t2, n2.item.values);
return Qm.Utils.LT(s2, i2[0]) && (i2 = [s2, a2]), [i2, r2] = e31.minmax_tree_calc_distance(t2, n2.right, i2), [i2, r2];
}
return [o2, false];
}
static shape2planarSet(t2, n2, o2 = Number.POSITIVE_INFINITY) {
let i2 = [o2, new Qm.Segment], r2 = false;
if (n2 instanceof Qm.PlanarSet) {
let s2 = e31.minmax_tree(t2, n2, o2);
[i2, r2] = e31.minmax_tree_calc_distance(t2, s2.root, i2);
}
return i2;
}
static sort(e32) {
e32.sort((e33, t2) => Qm.Utils.LT(e33[0], t2[0]) ? -1 : Qm.Utils.GT(e33[0], t2[0]) ? 1 : 0);
}
static distance(e32, t2) {
return e32.distanceTo(t2);
}
static distanceToArray(e32, t2) {
let n2 = [Number.POSITIVE_INFINITY, new Qm.Segment];
for (let o2 of t2) {
let [t3, i2] = e32.distanceTo(o2);
Qm.Utils.LT(t3, n2[0]) && (n2 = [t3, i2]);
}
return n2;
}
static shape2multiline(t2, n2) {
let o2 = [Number.POSITIVE_INFINITY, new Qm.Segment];
for (let i2 of n2) {
let [n3, r2] = e31.distance(t2, i2.shape);
Qm.Utils.LT(n3, o2[0]) && (o2 = [n3, r2]);
}
return o2;
}
static multiline2multiline(t2, n2) {
let o2 = [Number.POSITIVE_INFINITY, new Qm.Segment];
for (let i2 of t2)
for (let t3 of n2) {
let [n3, r2] = e31.distance(i2.shape, t3.shape);
Qm.Utils.LT(n3, o2[0]) && (o2 = [n3, r2]);
}
return o2;
}
};
var { Multiline: r_, Point: s_, Segment: a_, Polygon: c_ } = Qm;
function l_(e32) {
return new s_(e32.split(" ").map(Number));
}
function h_(e32) {
return e32.split(", ").map(l_);
}
function d_(e32) {
const t2 = h_(e32);
let n2 = [];
for (let e33 = 0;e33 < t2.length - 1; e33++)
n2.push(new a_(t2[e33], t2[e33 + 1]));
return new r_(n2);
}
function u_(e32) {
const t2 = e32.replace(/\(\(/, "").replace(/\)\)$/, "").split("), ("), n2 = new c_;
let o2;
return t2.forEach((e33, t3) => {
let i2 = e33.split(", ").map((e34) => new s_(e34.split(" ").map(Number)));
const r2 = n2.addFace(i2);
t3 === 0 ? o2 = r2.orientation() : r2.orientation() === o2 && r2.reverse();
}), n2;
}
function p_(e32) {
if (e32.startsWith("POLYGON")) {
return u_(e32.replace(/^POLYGON /, ""));
}
return function(e33) {
const t2 = e33.split(/\)\), \(\(/).map((e34) => "((" + e34 + "))").map(u_), n2 = new c_;
return t2.reduce((e34, t3) => [...e34, ...t3?.faces], []).forEach((e34) => n2.addFace([...e34?.shapes])), n2;
}(e32.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/, "$1"));
}
function m_(e32) {
return e32.split(`
`)?.every((e33) => e33.includes("POINT"));
}
function g_(e32) {
return e32.split(`
`)?.every((e33) => e33.includes("LINESTRING"));
}
Qm.isWktString = function(e33) {
return e33.startsWith("POINT") || m_(e33) || e33.startsWith("LINESTRING") || g_(e33) || e33.startsWith("MULTILINESTRING") || e33.startsWith("POLYGON") || e33.startsWith("MULTIPOINT") || e33.startsWith("MULTIPOLYGON") || e33.startsWith("GEOMETRYCOLLECTION");
}, Qm.parseWKT = function e32(t2) {
if (t2.startsWith("POINT")) {
return l_(t2.replace(/^POINT \(/, "").replace(/\)$/, ""));
}
if (t2.startsWith("MULTIPOINT")) {
return h_(t2.replace(/^MULTIPOINT \(/, "").replace(/\)$/, ""));
}
if (t2.startsWith("LINESTRING")) {
return d_(t2.replace(/^LINESTRING \(/, "").replace(/\)$/, ""));
}
if (t2.startsWith("MULTILINESTRING")) {
return function(e33) {
return e33.replace(/\(\(/, "").replace(/\)\)$/, "").split("), (").map(d_);
}(t2.replace(/^MULTILINESTRING /, ""));
}
if (t2.startsWith("POLYGON") || t2.startsWith("MULTIPOLYGON"))
return p_(t2);
if (t2.startsWith("GEOMETRYCOLLECTION")) {
const n2 = /(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g, o2 = t2.match(n2);
o2[0].startsWith("GEOMETRYCOLLECTION") && (o2[0] = o2[0].replace("GEOMETRYCOLLECTION (", ""));
return o2.map(e32).map((e33) => e33 instanceof Array ? e33 : [e33]).reduce((e33, t3) => [...e33, ...t3], []);
}
return m_(t2) ? function(e33) {
return e33.split(`
`).map((e34) => e34.match(/\(([^)]+)\)/)[1]).map(l_);
}(t2) : g_(t2) ? function(e33) {
return e33.split(`
`).map((e34) => e34.match(/\(([^)]+)\)/)[1]).map(d_).reduce((e34, t3) => [...e34, ...t3], []);
}(t2) : [];
}, Qm.BooleanOperations = yf, Qm.Relations = Of;
var f_ = [0, 1, -1, 2, -2, 3, -3, 4];
(f_.flatMap((e33) => f_.map((t2) => [e33, t2])).sort(([e33, t2], [n2, o2]) => Math.abs(e33) + Math.abs(t2) - Math.abs(n2) - Math.abs(o2)).length, [0.2, 0.4, 0.8, 1.2].flatMap((e33) => [0.2, 0.3, 0.45, 0.6].flatMap((t2) => [-1, 1].map((n2) => ({ halfSpan: e33, offset: t2, directionSign: n2 })))).flatMap((e33) => [0, 1].map((t2) => ({ kind: "segment", routeSide: t2, ...e33 }))));
[{ dx: -2.4, dy: -0.4 }, { dx: -2.4, dy: 0.4 }, { dx: 2.4, dy: -0.4 }, { dx: 2.4, dy: 0.4 }, { dx: -0.4, dy: -2.4 }, { dx: -0.4, dy: 2.4 }, { dx: 0.4, dy: -2.4 }, { dx: 0.4, dy: 2.4 }].flatMap((e33) => [0, 1].map((t2) => ({ kind: "waypoint", routeSide: t2, spanExpansion: 2, ...e33 }))), [{ dx: -0.17, dy: 0 }, { dx: 0.17, dy: 0 }, { dx: 0, dy: -0.17 }, { dx: 0, dy: 0.17 }].flatMap((e33) => [0, 1].map((t2) => ({ kind: "waypoint", routeSide: t2, spanExpansion: 0, ...e33 })));
function y_(e33) {
if (e33.isNonPlatedHole && e33.shape === "circle")
return { type: "oval", a: { x: 0, y: 0 }, b: { x: 0, y: 0 }, radius: e33.width / 2 };
if (e33.type === "rect")
return { type: "rect", bounds: { minX: -e33.width / 2, maxX: e33.width / 2, minY: -e33.height / 2, maxY: e33.height / 2 } };
if (e33.type !== "oval")
throw new Error("repair04 found an unsupported obstacle shape");
const t2 = Math.abs(e33.width - e33.height) / 2, n2 = e33.width >= e33.height ? t2 : 0, o2 = e33.height > e33.width ? t2 : 0;
return { type: "oval", a: { x: -n2, y: -o2 }, b: { x: n2, y: o2 }, radius: Math.min(e33.width, e33.height) / 2 };
}
function b_(e33, t2, n2) {
return n2.type === "rect" ? Dt(e33, t2, n2.bounds) : Math.max(0, kt(e33, t2, n2.a, n2.b) - n2.radius);
}
var x_ = (e33, t2) => {
const n2 = new Map, o2 = (e34) => {
const t3 = n2.get(e34);
if (t3 === undefined)
return n2.set(e34, e34), e34;
if (t3 === e34)
return e34;
const i3 = o2(t3);
return n2.set(e34, i3), i3;
}, i2 = (e34) => {
const t3 = e34.filter((e35) => typeof e35 == "string" && e35.length > 0);
if (t3.length === 0)
return;
const i3 = o2(t3[0]);
for (const e35 of t3)
n2.set(o2(e35), i3);
};
for (const t3 of e33.connections) {
const e34 = t3;
i2([e34.name, e34.rootConnectionName, e34.netConnectionName, e34.__netConnectionName, ...e34.mergedConnectionNames ?? [], ...e34.__rootConnectionNames ?? [], ...e34.pointsToConnect.flatMap((e35) => [e35.pointId, e35.pcb_port_id])]);
}
for (const t3 of e33.obstacles)
i2(t3.connectedTo);
for (const e34 of t2)
i2([e34.connectionName, e34.rootConnectionName]);
for (const e34 of n2.keys())
n2.set(e34, o2(e34));
return n2;
};
var v_ = (e33, t2) => {
const n2 = e33.__zLayers;
if (n2)
return new Set(n2);
if (e33.zLayers)
return new Set(e33.zLayers);
const o2 = new Set;
for (const n3 of e33.layers) {
const e34 = n3 === "top" ? 0 : n3 === "bottom" ? t2 - 1 : /^inner\d+$/.test(n3) ? Number(n3.slice(5)) : -1;
if (e34 < 0 || e34 >= t2)
throw new Error(`repair04 obstacle has an unknown layer: ${n3}`);
o2.add(e34);
}
return o2;
};
var I_ = ({ srj: e33, routes: t2, traceClearance: n2 = 0.1, viaClearance: o2 = 0.1 }) => {
let i2;
const r2 = new Map, s2 = [];
let a2 = false;
return (c2) => {
const l2 = i2 ??= x_(e33, t2), h2 = new Map, d2 = a2 ? s2 : function* (t3) {
for (let i3 = 0;i3 < e33.obstacles.length; i3++) {
if (r2.has(i3)) {
const e34 = r2.get(i3);
e34 && (yield e34);
continue;
}
const a3 = e33.obstacles[i3], c3 = a3.connectedTo.some((e34) => /^(pcb_smtpad_|pcb_plated_hole_|pcb_port_)/.test(e34)), l3 = Math.abs((a3.ccwRotationDegrees ?? 0) % 180) > 0.00000001, h3 = a3.type === "rect" && a3.layers.length > 1 && Math.abs(a3.width - a3.height) < 0.001;
if (c3 && !l3 && !h3) {
r2.set(i3, null);
continue;
}
if (![a3.center.x, a3.center.y, a3.width, a3.height, a3.ccwRotationDegrees ?? 0].every(Number.isFinite) || a3.width < 0 || a3.height < 0)
throw new Error("repair04 fixed obstacle geometry must be finite and nonnegative");
const d3 = v_(a3, e33.layerCount), u2 = new Set(a3.connectedTo.map((e34) => t3.get(e34) ?? e34)), p2 = y_(a3), m2 = (a3.ccwRotationDegrees ?? 0) * Math.PI / 180, g2 = Math.cos(m2), f2 = Math.sin(m2), _2 = Math.hypot(a3.width, a3.height) / 2, y2 = (e34) => {
const t4 = e34.x - a3.center.x, n3 = e34.y - a3.center.y;
return { x: t4 * g2 + n3 * f2, y: -t4 * f2 + n3 * g2 };
}, b2 = (e34, t4, n3) => Math.max(e34.x, t4.x) + n3 < a3.center.x - _2 || Math.min(e34.x, t4.x) - n3 > a3.center.x + _2 || Math.max(e34.y, t4.y) + n3 < a3.center.y - _2 || Math.min(e34.y, t4.y) - n3 > a3.center.y + _2, x2 = a3.obstacleId?.startsWith("repair04_board_edge_") === true, v2 = x2 ? 0 : a3.isNonPlatedHole && e33.minTraceToHoleEdgeClearance !== undefined ? e33.minTraceToHoleEdgeClearance : Math.max(n2, e33.defaultObstacleMargin ?? 0, e33.minTraceToPadEdgeClearance ?? 0), I2 = x2 ? 0 : Math.max(o2, e33.defaultObstacleMargin ?? 0, e33.minViaEdgeToPadEdgeClearance ?? 0), S2 = { obstacleIndex: i3, obstacle: a3, zLayers: d3, obstacleNets: u2, shape: p2, toLocal: y2, separated: b2, wireGap: v2, viaGap: I2 };
r2.set(i3, S2), s2.push(S2), yield S2;
}
a2 = true;
}(l2);
for (const { obstacleIndex: t3, obstacle: n3, zLayers: o3, obstacleNets: i3, shape: r3, toLocal: s3, separated: a3, wireGap: u2, viaGap: p2 } of d2)
for (let d3 = 0;d3 < c2.length; d3 += 1) {
const m2 = c2[d3];
if (!(m2.route.length < 2) && ![m2.connectionName, m2.rootConnectionName].some((e34) => e34 !== undefined && i3.has(l2.get(e34) ?? e34)))
for (let i4 = 1;i4 < m2.route.length; i4 += 1) {
const c3 = m2.route[i4 - 1], l3 = m2.route[i4];
if (c3.toNextSegmentType === "through_obstacle")
continue;
if (c3.z !== l3.z) {
const n4 = Us(e33, c3, l3);
if (!Array.from(o3).some((e34) => e34 >= n4.minZ && e34 <= n4.maxZ))
continue;
if (Math.abs(c3.x - l3.x) > 0.00000001 || Math.abs(c3.y - l3.y) > 0.00000001)
throw new Error("repair04 found a non-colocated via transition");
if (a3(c3, c3, m2.viaDiameter / 2 + p2 + 0.00000001))
continue;
const i5 = s3(c3), u3 = b_(i5, i5, r3), g3 = m2.viaDiameter / 2 + p2 - u3;
if (g3 <= 0.00000001)
continue;
const f3 = `fixed-obstacle:${d3}:${t3}:via`;
(h2.get(f3)?.severity ?? -1 / 0) < g3 && h2.set(f3, { key: f3, center: { x: c3.x, y: c3.y }, routeIndex: d3, obstacleIndex: t3, kind: "via", severity: g3 });
continue;
}
if (!o3.has(c3.z))
continue;
const g2 = Math.max(c3.traceThickness ?? m2.traceThickness, l3.traceThickness ?? m2.traceThickness) / 2;
if (a3(c3, l3, g2 + u2 + 0.00000001))
continue;
const f2 = g2 + u2 - b_(s3(c3), s3(l3), r3);
if (f2 <= 0.00000001)
continue;
const _2 = `fixed-obstacle:${d3}:${t3}:wire`;
(h2.get(_2)?.severity ?? -1 / 0) < f2 && h2.set(_2, { key: _2, center: Bt(n3.center, c3, l3), routeIndex: d3, obstacleIndex: t3, kind: "wire", severity: f2 });
}
}
return Array.from(h2.values());
};
};
var S_ = (e33) => I_(e33)(e33.routes);
var C_ = (e33, t2) => {
const n2 = [];
for (let o2 = 1;o2 < e33.route.length; o2++) {
const i2 = e33.route[o2 - 1], r2 = e33.route[o2];
if (i2.z === r2.z || i2.toNextSegmentType === "through_obstacle")
continue;
if (i2.x !== r2.x || i2.y !== r2.y || ![i2.x, i2.y, i2.z, r2.z, e33.viaDiameter].every(Number.isFinite) || !Number.isInteger(i2.z) || !Number.isInteger(r2.z) || Math.min(i2.z, r2.z) < 0 || Math.max(i2.z, r2.z) >= t2 || e33.viaDiameter <= 0)
throw new Error("repair04 new-via guard requires valid colocated vias");
const s2 = o2 - 1, a2 = [i2.z, r2.z];
let c2 = Math.min(i2.z, r2.z), l2 = Math.max(i2.z, r2.z);
for (;o2 + 1 < e33.route.length && e33.route[o2].toNextSegmentType !== "through_obstacle"; ) {
const n3 = e33.route[o2 + 1];
if (n3.x !== r2.x || n3.y !== r2.y)
break;
if (!Number.isInteger(n3.z) || n3.z < 0 || n3.z >= t2)
throw new Error("repair04 new-via guard found an invalid layer span");
n3.z !== a2.at(-1) && a2.push(n3.z), c2 = Math.min(c2, n3.z), l2 = Math.max(l2, n3.z), o2++;
}
n2.push({ pointIndices: Array.from({ length: o2 - s2 + 1 }, (e34, t3) => s2 + t3), layerSequence: a2, x: r2.x, y: r2.y, minZ: c2, maxZ: l2, diameter: e33.viaDiameter, identity: JSON.stringify([r2.x, r2.y, c2, l2, e33.viaDiameter]) });
}
return n2;
};
var P_ = (e33) => (({ srj: e34, viaClearance: t2 = 0.1 }) => {
const n2 = new Map, o2 = new Map, i2 = [t2, e34.defaultObstacleMargin ?? 0, e34.minViaEdgeToPadEdgeClearance ?? 0], r2 = Math.max(...i2), s2 = Js(e34, t2, true);
let a2, c2 = [];
const l2 = (t3) => {
const i3 = o2.get(t3.identity);
if (i3)
return i3;
const s3 = [], a3 = Us(e34, { z: t3.minZ }, { z: t3.maxZ });
for (let o3 = 0;o3 < e34.obstacles.length; o3++) {
const i4 = e34.obstacles[o3];
let c3 = n2.get(o3);
if (!c3) {
const t4 = i4.__zLayers ?? i4.zLayers ?? i4.layers.map((t5) => t5 === "top" ? 0 : t5 === "bottom" ? e34.layerCount - 1 : /^inner\d+$/.test(t5) ? Number(t5.slice(5)) : -1);
if (t4.some((t5) => !Number.isInteger(t5) || t5 < 0 || t5 >= e34.layerCount))
throw new Error("repair04 new-via guard found an unknown obstacle layer");
c3 = { zs: t4 }, n2.set(o3, c3);
}
if (!c3.zs.some((e35) => e35 >= a3.minZ && e35 <= a3.maxZ))
continue;
if (!c3.geometry) {
if (![i4.center.x, i4.center.y, i4.width, i4.height, i4.ccwRotationDegrees ?? 0].every(Number.isFinite) || i4.width < 0 || i4.height < 0)
throw new Error("repair04 new-via guard found invalid obstacle geometry");
const e35 = (i4.ccwRotationDegrees ?? 0) * Math.PI / 180;
c3.geometry = { x: i4.center.x, y: i4.center.y, cosine: Math.cos(e35), sine: Math.sin(e35), extent: Math.hypot(i4.width, i4.height) / 2, shape: y_(i4) };
}
const l3 = c3.geometry, h2 = l3.extent + t3.diameter / 2 + r2 + 0.00000001;
if (Math.abs(t3.x - l3.x) > h2 || Math.abs(t3.y - l3.y) > h2)
continue;
const d2 = t3.x - l3.x, u2 = t3.y - l3.y, p2 = { x: d2 * l3.cosine + u2 * l3.sine, y: -d2 * l3.sine + u2 * l3.cosine }, m2 = b_(p2, p2, l3.shape), g2 = t3.diameter / 2 + r2 - m2;
g2 <= 0.00000001 || s3.push({ obstacleIndex: o3, severity: g2 });
}
return o2.set(t3.identity, s3), s3;
};
return ({ previousRoutes: t3, routes: n3, includeExistingVias: o3 = [] }) => {
if (t3.length !== n3.length)
throw new Error("repair04 new-via guard requires matching route ordering");
if (i2.some((e35) => !Number.isFinite(e35) || e35 < 0))
throw new Error("repair04 new-via guard requires nonnegative finite margins");
const h2 = [];
a2 && c2.length === n3.length && !c2.some((e35, t4) => e35.connectionName !== n3[t4].connectionName || e35.rootConnectionName !== n3[t4].rootConnectionName) || (a2 = x_(e34, n3), c2 = n3.map((e35) => ({ connectionName: e35.connectionName, rootConnectionName: e35.rootConnectionName })));
for (let i3 = 0;i3 < n3.length; i3++) {
const c3 = n3[i3], d2 = t3[i3], u2 = a2.get(c3.connectionName) ?? c3.connectionName, p2 = (t4) => l2(t4).flatMap((t5) => {
const n4 = e34.obstacles[t5.obstacleIndex].connectedTo.some((e35) => (a2.get(e35) ?? e35) === u2), o4 = t5.severity - (n4 ? r2 - s2 : 0);
return o4 > 0.00000001 ? [{ obstacleIndex: t5.obstacleIndex, severity: o4 }] : [];
}), m2 = C_(d2, e34.layerCount), g2 = c3.connectionName === d2.connectionName && c3.rootConnectionName === d2.rootConnectionName, f2 = new Set(g2 ? m2.map((e35) => e35.identity) : []), _2 = C_(c3, e34.layerCount), y2 = g2 && c3.route.length === d2.route.length && c3.route.every((e35, t4) => {
const n4 = d2.route[t4];
return (!(t4 === 0 || t4 === c3.route.length - 1 || e35.pcb_port_id || e35.insideJumperPad || e35.toNextSegmentType) || e35.x === n4.x && e35.y === n4.y) && e35.z === n4.z && e35.pcb_port_id === n4.pcb_port_id && e35.toNextSegmentType === n4.toNextSegmentType && e35.insideJumperPad === n4.insideJumperPad;
}) && _2.length === m2.length && new Set(_2.map((e35) => e35.identity)).size === _2.length && _2.every((e35, t4) => {
const n4 = m2[t4];
return e35.diameter === n4.diameter && e35.pointIndices.length === n4.pointIndices.length && e35.pointIndices.every((e36, t5) => e36 === n4.pointIndices[t5]) && e35.layerSequence.length === n4.layerSequence.length && e35.layerSequence.every((e36, t5) => e36 === n4.layerSequence[t5]) && !m2.some((n5, o4) => o4 !== t4 && n5.identity === e35.identity);
});
for (let e35 = 0;e35 < _2.length; e35++) {
const t4 = _2[e35];
if (f2.has(t4.identity) && !o3.some((t5) => t5.routeIndex === i3 && t5.viaIndex === e35))
continue;
const n4 = y2 && !o3.some((t5) => t5.routeIndex === i3 && t5.viaIndex === e35) ? new Map(p2(m2[e35]).map((e36) => [e36.obstacleIndex, e36.severity])) : undefined;
for (const o4 of p2(t4)) {
const r3 = n4?.get(o4.obstacleIndex);
r3 !== undefined && o4.severity <= r3 + 0.00000001 || h2.push({ key: `new-via-pad:${i3}:${o4.obstacleIndex}:${e35}`, routeIndex: i3, obstacleIndex: o4.obstacleIndex, center: { x: t4.x, y: t4.y }, kind: "via", severity: o4.severity });
}
}
}
return h2;
};
})(e33)(e33);
var M_ = (e33, t2, n2) => {
if (n2 <= Qs)
return structuredClone(e33);
if (n2 >= 0.99999999)
return structuredClone(t2);
const o2 = { ...structuredClone(e33), x: e33.x + (t2.x - e33.x) * n2, y: e33.y + (t2.y - e33.y) * n2 };
return delete o2.start_pcb_port_id, delete o2.end_pcb_port_id, o2;
};
var w_ = (e33, t2) => {
const n2 = e33.end.x - e33.start.x, o2 = e33.end.y - e33.start.y, i2 = t2.end.x - t2.start.x, r2 = t2.end.y - t2.start.y, s2 = t2.start.x - e33.start.x, a2 = t2.start.y - e33.start.y, c2 = n2 * r2 - o2 * i2, l2 = (e34, t3) => ({ x: e34.start.x + (e34.end.x - e34.start.x) * t3, y: e34.start.y + (e34.end.y - e34.start.y) * t3 }), h2 = (e34, t3) => {
const n3 = t3.end.x - t3.start.x, o3 = t3.end.y - t3.start.y, i3 = n3 * n3 + o3 * o3, r3 = i3 > 0.00000000000000010000000000000001 ? Math.max(0, Math.min(1, ((e34.x - t3.start.x) * n3 + (e34.y - t3.start.y) * o3) / i3)) : 0;
return l2(t3, r3);
};
if (Math.abs(c2) > Qs) {
const t3 = (s2 * r2 - a2 * i2) / c2, h3 = (s2 * o2 - a2 * n2) / c2;
if (t3 >= 0 && t3 <= 1 && h3 >= 0 && h3 <= 1) {
const n3 = l2(e33, t3);
return [n3, n3];
}
} else {
const i3 = n2 * n2 + o2 * o2;
if (i3 > 0.00000000000000010000000000000001) {
const r3 = (s2 * n2 + a2 * o2) / i3, c3 = ((t2.end.x - e33.start.x) * n2 + (t2.end.y - e33.start.y) * o2) / i3, d3 = Math.max(0, Math.min(r3, c3)), u2 = Math.min(1, Math.max(r3, c3));
if (d3 <= u2) {
const n3 = l2(e33, (d3 + u2) / 2);
return [n3, h2(n3, t2)];
}
}
}
const d2 = [[e33.start, h2(e33.start, t2)], [e33.end, h2(e33.end, t2)], [h2(t2.start, e33), t2.start], [h2(t2.end, e33), t2.end]];
return d2.sort((e34, t3) => Math.hypot(e34[0].x - e34[1].x, e34[0].y - e34[1].y) - Math.hypot(t3[0].x - t3[1].x, t3[0].y - t3[1].y)), d2[0];
};
var N_ = (e33, t2) => {
const n2 = e33 === "top" ? 0 : e33 === "bottom" ? t2 - 1 : /^inner\d+$/.test(e33) ? Number(e33.slice(5)) : -1;
if (!Number.isInteger(n2) || n2 < 0 || n2 >= t2)
throw new Error(`repair04 preload has an unknown layer: ${e33}`);
return n2;
};
var T_ = (e33, t2, n2) => {
const o2 = ((e34, t3) => {
const n3 = new Map, o3 = (e35) => {
const t4 = n3.get(e35);
if (t4 === undefined || t4 === e35)
return e35;
const i4 = o3(t4);
return n3.set(e35, i4), i4;
}, i3 = (e35) => {
const t4 = e35.filter((e36) => typeof e36 == "string" && e36.length > 0);
if (t4.length === 0)
return;
const i4 = o3(t4[0]);
for (const e36 of t4)
n3.set(o3(e36), i4);
};
for (const t4 of e34.connections) {
const e35 = t4;
i3([e35.name, e35.rootConnectionName, e35.netConnectionName, e35.__netConnectionName, ...e35.mergedConnectionNames ?? [], ...e35.__rootConnectionNames ?? []]);
}
for (const e35 of t3)
i3([e35.connectionName, e35.rootConnectionName]);
for (const t4 of e34.traces ?? [])
i3([t4.connection_name, ...t4.connectsTo ?? []]);
return o3;
})(e33, t2), i2 = t2.map((e34, t3) => t3), r2 = (e34) => {
const t3 = i2[e34];
if (t3 === e34)
return e34;
const n3 = r2(t3);
return i2[e34] = n3, n3;
}, s2 = new Map, a2 = new Map;
for (let t3 = 0;t3 < e33.obstacles.length; t3 += 1)
for (const n3 of e33.obstacles[t3].connectedTo) {
const e34 = a2.get(n3) ?? [];
e34.push(t3), a2.set(n3, e34);
}
for (let n3 = 0;n3 < t2.length; n3 += 1) {
const c3 = t2[n3];
for (const t3 of [c3.route[0], c3.route.at(-1)]) {
if (!t3)
continue;
const l3 = o2(c3.connectionName), h3 = [JSON.stringify([l3, "point", t3.x, t3.y, t3.z])], d3 = t3.pcb_port_id ? a2.get(t3.pcb_port_id) ?? [] : [];
for (const n4 of d3) {
const o3 = e33.obstacles[n4];
if (!(o3.zLayers ?? o3.layers.map((t4) => N_(t4, e33.layerCount))).includes(t3.z))
continue;
const i3 = (o3.ccwRotationDegrees ?? 0) * Math.PI / 180, r3 = t3.x - o3.center.x, s3 = t3.y - o3.center.y, a3 = { x: r3 * Math.cos(i3) + s3 * Math.sin(i3), y: -r3 * Math.sin(i3) + s3 * Math.cos(i3) };
b_(a3, a3, y_(o3)) > Qs || h3.push(JSON.stringify([l3, "pad", n4]));
}
for (const e34 of h3) {
const t4 = s2.get(e34);
t4 === undefined ? s2.set(e34, n3) : i2[r2(n3)] = r2(t4);
}
}
}
const c2 = (e34, t3) => !(!e34.startsWith("route:") || !t3.startsWith("route:")) && r2(Number(e34.slice(6))) === r2(Number(t3.slice(6))), l2 = [], h2 = [], d2 = [], u2 = t2.map(() => ({ segmentTimes: new Map, viaPositions: [] })), p2 = (e34) => {
if (Ks(e34, n2)) {
d2.push(e34);
for (let t3 = e34.minZ;t3 <= e34.maxZ; t3 += 1)
l2.push({ x: e34.x, y: e34.y, z: t3, radius: e34.radius, net: e34.net, source: e34.source, ...e34.routeIndex !== undefined ? { viaOwner: e34.routeIndex } : {} });
}
};
for (let e34 = 0;e34 < t2.length; e34 += 1) {
const i3 = t2[e34], r3 = o2(i3.connectionName), s3 = `route:${e34}`;
for (let t3 = 0;t3 < i3.route.length; t3 += 1) {
const o3 = i3.route[t3];
if ((t3 === 0 || t3 === i3.route.length - 1 || o3.pcb_port_id) && Ks(o3, n2) && l2.push({ x: o3.x, y: o3.y, z: o3.z, radius: (o3.traceThickness ?? i3.traceThickness) / 2, net: r3, source: s3 }), t3 === 0)
continue;
const a3 = i3.route[t3 - 1];
a3.toNextSegmentType !== "through_obstacle" && (a3.z === o3.z ? h2.push({ start: a3, end: o3, z: o3.z, radius: Math.max(a3.traceThickness ?? i3.traceThickness, o3.traceThickness ?? i3.traceThickness) / 2, net: r3, source: s3, routeIndex: e34, segmentIndex: t3 - 1 }) : p2({ x: o3.x, y: o3.y, minZ: Math.min(a3.z, o3.z), maxZ: Math.max(a3.z, o3.z), radius: i3.viaDiameter / 2, net: r3, source: s3, routeIndex: e34 }));
}
}
for (let t3 = 0;t3 < (e33.traces ?? []).length; t3 += 1) {
const i3 = qs(e33.traces[t3], e33.minTraceWidth), r3 = o2(i3.connection_name), s3 = `fixed:${t3}`;
for (let t4 = 0;t4 < i3.route.length; t4 += 1) {
const o3 = i3.route[t4], a3 = i3.route[t4 - 1];
if (o3.route_type === "wire") {
const c3 = N_(o3.layer, e33.layerCount);
(t4 === 0 || t4 === i3.route.length - 1 || o3.start_pcb_port_id || o3.end_pcb_port_id) && Ks(o3, n2) && l2.push({ x: o3.x, y: o3.y, z: c3, radius: o3.width / 2, net: r3, source: s3 }), a3?.route_type === "wire" && a3.layer === o3.layer && h2.push({ start: a3, end: o3, z: c3, radius: Math.max(a3.width, o3.width) / 2, net: r3, source: s3 });
} else if (o3.route_type === "via") {
const t5 = N_(o3.from_layer, e33.layerCount), n3 = N_(o3.to_layer, e33.layerCount);
p2({ x: o3.x, y: o3.y, minZ: Math.min(t5, n3), maxZ: Math.max(t5, n3), radius: (o3.via_diameter ?? e33.minViaDiameter ?? 0.3) / 2, net: r3, source: s3 });
}
}
}
const m2 = new Map;
for (const e34 of l2) {
const t3 = JSON.stringify([e34.net, e34.z]), n3 = m2.get(t3) ?? [];
n3.push(e34), m2.set(t3, n3);
}
const g2 = (e34, t3) => {
if (e34 === undefined)
return;
const n3 = u2[e34].viaPositions;
n3.some((e35) => Math.hypot(e35.x - t3.x, e35.y - t3.y) <= Qs) || n3.push({ x: t3.x, y: t3.y });
};
for (const e34 of h2) {
if (!ea(e34.start, e34.end, n2))
continue;
const t3 = e34.end.x - e34.start.x, o3 = e34.end.y - e34.start.y, i3 = t3 * t3 + o3 * o3;
if (!(i3 <= 0.00000000000000010000000000000001))
for (const r3 of m2.get(JSON.stringify([e34.net, e34.z])) ?? []) {
if (r3.source === e34.source || c2(r3.source, e34.source))
continue;
const s3 = Math.max(0, Math.min(1, ((r3.x - e34.start.x) * t3 + (r3.y - e34.start.y) * o3) / i3)), a3 = { x: e34.start.x + t3 * s3, y: e34.start.y + o3 * s3 };
if (Ks(a3, n2) && !(Math.hypot(a3.x - r3.x, a3.y - r3.y) > e34.radius + r3.radius + Qs)) {
if (e34.routeIndex !== undefined && e34.segmentIndex !== undefined) {
const t4 = u2[e34.routeIndex].segmentTimes.get(e34.segmentIndex) ?? [];
t4.some((e35) => Math.abs(e35 - s3) <= Qs) || t4.push(s3), u2[e34.routeIndex].segmentTimes.set(e34.segmentIndex, t4);
}
g2(r3.viaOwner, r3);
}
}
}
for (const e34 of d2)
for (let t3 = e34.minZ;t3 <= e34.maxZ; t3 += 1)
for (const n3 of m2.get(JSON.stringify([e34.net, t3])) ?? [])
n3.source === e34.source || c2(n3.source, e34.source) || Math.hypot(e34.x - n3.x, e34.y - n3.y) > e34.radius + n3.radius + Qs || (g2(e34.routeIndex, e34), g2(n3.viaOwner, n3));
return ((e34, t3, n3, o3) => {
const i3 = new Map, r3 = new Set, s3 = [], a3 = (e35, t4) => {
if (e35.routeIndex === undefined || e35.segmentIndex === undefined)
return;
const o4 = e35.end.x - e35.start.x, i4 = e35.end.y - e35.start.y, r4 = o4 * o4 + i4 * i4;
if (r4 <= 0.00000000000000010000000000000001)
return;
const s4 = Math.max(0, Math.min(1, ((t4.x - e35.start.x) * o4 + (t4.y - e35.start.y) * i4) / r4)), a4 = n3[e35.routeIndex].segmentTimes.get(e35.segmentIndex) ?? [];
a4.some((e36) => Math.abs(e36 - s4) <= Qs) || a4.push(s4), n3[e35.routeIndex].segmentTimes.set(e35.segmentIndex, a4);
};
for (const n4 of e34) {
const e35 = ea(n4.start, n4.end, t3);
if (!e35 || e35[1] - e35[0] <= Qs)
continue;
const c3 = (e36) => ({ x: n4.start.x + (n4.end.x - n4.start.x) * e36, y: n4.start.y + (n4.end.y - n4.start.y) * e36 }), l3 = { ...n4, start: c3(e35[0]), end: c3(e35[1]) }, h3 = s3.length;
s3.push({ original: n4, clipped: l3 });
const d3 = Math.floor((Math.min(l3.start.x, l3.end.x) - l3.radius) / 2), u3 = Math.floor((Math.max(l3.start.x, l3.end.x) + l3.radius) / 2), p3 = Math.floor((Math.min(l3.start.y, l3.end.y) - l3.radius) / 2), m3 = Math.floor((Math.max(l3.start.y, l3.end.y) + l3.radius) / 2);
for (let e36 = d3;e36 <= u3; e36 += 1)
for (let t4 = p3;t4 <= m3; t4 += 1) {
const c4 = JSON.stringify([l3.net, l3.z, e36, t4]), d4 = i3.get(c4) ?? [];
for (const e37 of d4) {
const t5 = s3[e37];
if (t5.original.source === n4.source || o3(t5.original.source, n4.source) || t5.original.routeIndex === undefined && n4.routeIndex === undefined)
continue;
const i4 = `${e37}:${h3}`;
if (r3.has(i4))
continue;
r3.add(i4);
const [c5, d5] = w_(l3, t5.clipped);
Math.hypot(c5.x - d5.x, c5.y - d5.y) > l3.radius + t5.clipped.radius + Qs || (a3(n4, c5), a3(t5.original, d5));
}
d4.push(h3), i3.set(c4, d4);
}
}
})(h2, n2, u2, c2), u2;
};
var R_ = (e33, t2) => ({ minX: e33.minX - t2, maxX: e33.maxX + t2, minY: e33.minY - t2, maxY: e33.maxY + t2 });
var E_ = (e33, t2, n2, o2) => {
const i2 = [];
let r2;
const s2 = e33.route, a2 = (e34) => e34 === 0 || e34 === s2.length - 1 || s2[e34]?.pcb_port_id !== undefined, c2 = () => {
r2 !== undefined && r2.points.length > 0 && (r2.locks[0] = true, r2.locks[r2.points.length - 1] = true, i2.push(r2)), r2 = undefined;
};
if (s2.length === 1 && s2[0] && Ks(s2[0], t2))
return [{ points: structuredClone(s2), locks: [true], start: { segmentIndex: 0, t: 0 }, end: { segmentIndex: 0, t: 0 } }];
for (let i3 = 0;i3 < s2.length - 1; i3 += 1) {
const l2 = s2[i3], h2 = s2[i3 + 1];
if (!l2 || !h2)
throw new Error("repair04 found a missing route point");
if (![l2.x, l2.y, l2.z, h2.x, h2.y, h2.z].every(Number.isFinite))
throw new Error("repair04 route coordinates must be finite");
if (l2.z !== h2.z && !na({ x: l2.x, y: l2.y }, { x: h2.x, y: h2.y }) && l2.toNextSegmentType !== "through_obstacle")
throw new Error("repair04 requires colocated points at a via transition");
const d2 = ea(l2, h2, t2);
if (!d2) {
c2();
continue;
}
const [u2, p2] = d2;
if (p2 - u2 <= Qs && !na(l2, h2)) {
c2();
continue;
}
const m2 = ea(l2, h2, n2), g2 = [u2, p2], f2 = o2.segmentTimes.get(i3) ?? [];
for (const e34 of f2)
e34 >= u2 - Qs && e34 <= p2 + Qs && g2.push(Math.max(u2, Math.min(p2, e34)));
if (m2 && l2.z === h2.z)
for (const e34 of m2)
e34 > u2 + Qs && e34 < p2 - Qs && g2.push(e34);
g2.sort((e34, t3) => e34 - t3);
const _2 = g2.filter((e34, t3) => t3 === 0 || Math.abs(e34 - g2[t3 - 1]) > Qs), y2 = ta(l2, h2, u2);
r2 && !na(r2.points[r2.points.length - 1], y2) && c2(), r2 || (r2 = { points: [], locks: [], start: { segmentIndex: i3, t: u2 }, end: { segmentIndex: i3, t: p2 } });
for (const t3 of _2) {
const s3 = ta(l2, h2, t3), c3 = t3 <= Qs ? i3 : t3 >= 0.99999999 ? i3 + 1 : undefined, d3 = !Ks(s3, n2, 0.00000004) || f2.some((e34) => Math.abs(e34 - t3) <= Qs) || o2.viaPositions.some((e34) => Math.hypot(e34.x - s3.x, e34.y - s3.y) <= Qs) || c3 !== undefined && a2(c3) || l2.toNextSegmentType === "through_obstacle" || s3.toNextSegmentType === "through_obstacle" || l2.insideJumperPad === true || h2.insideJumperPad === true || (e33.jumpers ?? []).some((e34) => na(s3, { ...e34.start, z: s3.z }) || na(s3, { ...e34.end, z: s3.z })), u3 = r2.points[r2.points.length - 1];
u3 && u3.x === s3.x && u3.y === s3.y && u3.z === s3.z ? r2.locks[r2.locks.length - 1] = r2.locks[r2.locks.length - 1] || d3 : (r2.points.push(s3), r2.locks.push(d3));
}
r2.end = { segmentIndex: i3, t: p2 }, p2 < 0.99999999 && c2();
}
c2();
for (const e34 of i2)
for (let t3 = 1;t3 < e34.points.length; t3 += 1) {
const n3 = e34.points[t3 - 1], o3 = e34.points[t3];
if (n3.z !== o3.z && (e34.locks[t3 - 1] || e34.locks[t3])) {
let n4 = t3 - 1, i3 = t3;
for (;n4 > 0 && na({ x: e34.points[n4 - 1].x, y: e34.points[n4 - 1].y }, { x: o3.x, y: o3.y }); )
n4 -= 1;
for (;i3 + 1 < e34.points.length && na({ x: e34.points[i3 + 1].x, y: e34.points[i3 + 1].y }, { x: o3.x, y: o3.y }); )
i3 += 1;
for (let t4 = n4;t4 <= i3; t4 += 1)
e34.locks[t4] = true;
}
}
return i2;
};
var A_ = (e33, t2) => {
const n2 = e33.bounds, o2 = e33.outline && e33.outline.length >= 3 ? e33.outline : [{ x: n2.minX, y: n2.minY }, { x: n2.maxX, y: n2.minY }, { x: n2.maxX, y: n2.maxY }, { x: n2.minX, y: n2.maxY }], i2 = [];
for (let n3 = 0;n3 < o2.length; n3 += 1) {
const r2 = o2[n3], s2 = o2[(n3 + 1) % o2.length], a2 = ea(r2, s2, t2);
if (!a2)
continue;
const c2 = s2.x - r2.x, l2 = s2.y - r2.y, h2 = Math.hypot(c2, l2);
if (h2 <= Qs)
continue;
const d2 = (a2[0] + a2[1]) / 2;
i2.push({ obstacleId: `repair04_board_edge_${n3}`, type: "rect", center: { x: r2.x + c2 * d2, y: r2.y + l2 * d2 }, width: h2 * (a2[1] - a2[0]), height: Math.max(2 * (e33.minBoardEdgeClearance ?? 0), Qs), ccwRotationDegrees: 180 * Math.atan2(l2, c2) / Math.PI, layers: Array.from({ length: e33.layerCount }, (t3, n4) => n4 === 0 ? "top" : n4 === e33.layerCount - 1 ? "bottom" : `inner${n4}`), zLayers: Array.from({ length: e33.layerCount }, (e34, t3) => t3), connectedTo: [] });
}
return i2;
};
var O_ = ({ srj: e33, routes: t2, bounds: n2, boundaryMargin: o2 = 0.5, clearanceHalo: i2 }) => {
if (((e34) => {
if (!Object.values(e34).every(Number.isFinite))
throw new Error("repair04 bounds must contain finite coordinates");
if (e34.maxX - e34.minX < 9.99999999 || e34.maxY - e34.minY < 9.99999999)
throw new Error("repair04 requires bounds at least 10 mm by 10 mm");
})(n2), !Number.isFinite(o2) || o2 < 0 || i2 !== undefined && (!Number.isFinite(i2) || i2 < 0))
throw new Error("repair04 collar and halo must be finite and nonnegative");
const r2 = Math.max(e33.defaultObstacleMargin ?? 0.2, e33.minTraceToPadEdgeClearance ?? 0, e33.minTraceToHoleEdgeClearance ?? 0, e33.minViaEdgeToPadEdgeClearance ?? 0);
let s2 = Math.max(e33.minTraceWidth, e33.minViaDiameter ?? 0);
for (const e34 of t2) {
s2 = Math.max(s2, e34.traceThickness, e34.viaDiameter);
for (const t3 of e34.route)
s2 = Math.max(s2, t3.traceThickness ?? 0);
}
for (const t3 of e33.traces ?? [])
for (const n3 of t3.route)
n3.route_type === "wire" && (s2 = Math.max(s2, n3.width)), n3.route_type === "via" && (s2 = Math.max(s2, n3.via_diameter ?? e33.minViaDiameter ?? 0.3));
if (!Number.isFinite(s2) || s2 <= 0)
throw new Error("repair04 requires finite positive copper widths");
const a2 = Math.max(o2, s2 + r2);
if (2 * a2 >= Math.min(n2.maxX - n2.minX, n2.maxY - n2.minY))
throw new Error("repair04 bounds are too small for their required copper safety collar");
const c2 = R_(n2, Math.max(i2 ?? a2, r2 + s2)), l2 = R_(n2, -a2), h2 = T_(e33, t2, c2), d2 = ((e34, t3, n3) => {
const o3 = [];
for (const i3 of e34) {
const e35 = qs(i3, n3), r3 = [];
let s3 = [];
const a3 = () => {
s3.length > 0 && r3.push(s3), s3 = [];
}, c3 = (e36) => {
oa(s3[s3.length - 1]) !== oa(e36) && s3.push(structuredClone(e36));
};
for (let n4 = 0;n4 < e35.route.length; n4 += 1) {
const o4 = e35.route[n4], i4 = e35.route[n4 - 1];
if (o4.route_type === "wire" && i4?.route_type === "wire" && o4.layer === i4.layer) {
const e36 = ea(i4, o4, t3);
if (!e36) {
a3();
continue;
}
const n5 = M_(i4, o4, e36[0]), r4 = M_(i4, o4, e36[1]), l3 = s3[s3.length - 1];
l3?.route_type === "wire" && (l3.layer !== n5.layer || Math.hypot(l3.x - n5.x, l3.y - n5.y) > Qs) && a3(), c3(n5), c3(r4), e36[1] < 0.99999999 && a3();
} else if (o4.route_type === "via") {
if (!Ks(o4, t3)) {
a3();
continue;
}
if (i4?.route_type !== "wire")
throw new Error("repair04 normalized preload via has no incoming wire");
c3(i4), c3(o4);
const r4 = e35.route[n4 + 1];
if (r4?.route_type !== "wire")
throw new Error("repair04 normalized preload via has no outgoing wire");
c3(r4);
} else if (o4.route_type === "wire")
Ks(o4, t3) && c3(o4);
else if ("start" in o4 && "end" in o4) {
const e36 = ea(o4.start, o4.end, t3);
if (!e36) {
a3();
continue;
}
const n5 = (e37) => ({ x: o4.start.x + (o4.end.x - o4.start.x) * e37, y: o4.start.y + (o4.end.y - o4.start.y) * e37 });
c3({ ...structuredClone(o4), start: n5(e36[0]), end: n5(e36[1]) }), e36[1] < 0.99999999 && a3();
}
}
a3();
for (let e36 = 0;e36 < r3.length; e36 += 1)
o3.push({ ...structuredClone(i3), pcb_trace_id: r3.length === 1 ? i3.pcb_trace_id : `${i3.pcb_trace_id}__repair04_fixed_${e36}`, route: r3[e36] });
}
return o3;
})(e33.traces ?? [], c2, e33.minTraceWidth), u2 = [], p2 = [], m2 = [];
for (let e34 = 0;e34 < t2.length; e34 += 1) {
const n3 = t2[e34];
for (const t3 of E_(n3, c2, l2, h2[e34])) {
const o3 = { ...structuredClone(Object.fromEntries(Object.entries(n3).filter(([e35]) => e35 !== "route" && e35 !== "vias" && e35 !== "jumpers"))), connectionName: n3.connectionName, traceThickness: n3.traceThickness, viaDiameter: n3.viaDiameter, route: t3.points, vias: n3.vias.filter((e35) => t3.points.some((t4) => Math.abs(t4.x - e35.x) <= Qs && Math.abs(t4.y - e35.y) <= Qs)).map((e35) => structuredClone(e35)), ...n3.jumpers !== undefined ? { jumpers: n3.jumpers.filter((e35) => ea(e35.start, e35.end, c2) !== undefined).map((e35) => structuredClone(e35)) } : {} };
u2.push(o3), p2.push(t3.locks), m2.push({ sourceRouteIndex: e34, start: t3.start, end: t3.end, sourceGeometryKey: ra(n3, t3.start.segmentIndex + t3.start.t, t3.end.segmentIndex + t3.end.t), originalFragment: structuredClone(o3) });
}
}
const g2 = new Set([...u2.flatMap((e34) => [e34.connectionName, ...e34.rootConnectionName ? [e34.rootConnectionName] : []]), ...d2.map((e34) => e34.connection_name)]), f2 = e33.connections.filter((e34) => g2.has(e34.name) || e34.pointsToConnect.some((e35) => Ks(e35, c2))).map((e34) => ({ ...structuredClone(Object.fromEntries(Object.entries(e34).filter(([e35]) => e35 !== "pointsToConnect"))), name: e34.name, pointsToConnect: e34.pointsToConnect.filter((e35) => Ks(e35, c2)).map((e35) => structuredClone(e35)) }));
for (let t3 = 0;t3 < u2.length; t3 += 1) {
const n3 = u2[t3];
let o3 = f2.find((e34) => e34.name === n3.connectionName);
o3 || (o3 = { name: n3.connectionName, ...n3.rootConnectionName ? { rootConnectionName: n3.rootConnectionName } : {}, pointsToConnect: [] }, f2.push(o3));
for (const [i3, r3] of [["start", n3.route[0]], ["end", n3.route[n3.route.length - 1]]]) {
if (!r3)
continue;
const n4 = r3.z === 0 ? "top" : r3.z === e33.layerCount - 1 ? "bottom" : `inner${r3.z}`;
o3.pointsToConnect.some((e34) => Math.abs(e34.x - r3.x) <= Qs && Math.abs(e34.y - r3.y) <= Qs && ("layer" in e34 ? e34.layer === n4 : e34.layers.includes(n4))) || o3.pointsToConnect.push({ x: r3.x, y: r3.y, layer: n4, pointId: `repair04_${t3}_${i3}`, ...r3.pcb_port_id ? { pcb_port_id: r3.pcb_port_id } : {} });
}
}
const _2 = { ...Object.fromEntries(Object.entries(e33).filter(([e34, t3]) => e34 !== "sourceCircuitJson" && e34 !== "sourceKicadPcb" && (typeof t3 == "number" || typeof t3 == "boolean" || typeof t3 == "string"))), layerCount: e33.layerCount, minTraceWidth: e33.minTraceWidth, bounds: structuredClone(c2), obstacles: [...e33.obstacles.filter((e34) => ((e35, t3) => {
const n3 = (e35.ccwRotationDegrees ?? 0) * Math.PI / 180, o3 = (Math.abs(e35.width * Math.cos(n3)) + Math.abs(e35.height * Math.sin(n3))) / 2, i3 = (Math.abs(e35.width * Math.sin(n3)) + Math.abs(e35.height * Math.cos(n3))) / 2;
return e35.center.x + o3 >= t3.minX && e35.center.x - o3 <= t3.maxX && e35.center.y + i3 >= t3.minY && e35.center.y - i3 <= t3.maxY;
})(e34, c2)).map((e34) => structuredClone(e34)), ...A_(e33, c2)], connections: f2, ...e33.traces !== undefined ? { traces: d2 } : {}, ...e33.allowJumpers !== undefined ? { allowJumpers: e33.allowJumpers } : {}, ...e33.availableJumperTypes ? { availableJumperTypes: structuredClone(e33.availableJumperTypes) } : {} };
return { srj: _2, routes: u2, bounds: structuredClone(n2), contextBounds: c2, mutableBounds: l2, boundaryMargin: a2, lockedPointIndices: p2, routeMappings: m2 };
};
var k_ = (e33) => oa(Object.fromEntries(Object.entries(e33).filter(([e34]) => e34 !== "route" && e34 !== "vias")));
var D_ = (e33, t2) => {
const n2 = [];
for (let o2 = 1;o2 < e33.route.length; o2 += 1) {
const i2 = e33.route[o2 - 1], r2 = e33.route[o2], s2 = ea(i2, r2, t2), a2 = s2 ? [...s2[0] > Qs ? [[0, s2[0]]] : [], ...s2[1] < 0.99999999 ? [[s2[1], 1]] : []] : [[0, 1]];
s2 && !Ks(ta(i2, r2, 0.5), t2, 0.00000004) && a2.length === 0 && a2.push([0, 1]);
for (const [e34, t3] of a2)
n2.push(oa([ta(i2, r2, e34), ta(i2, r2, t3)]));
}
return n2;
};
var L_ = (e33, t2, n2, o2, i2, r2) => {
if (k_(e33) !== k_(t2))
throw new Error("repair04 merge rejected changed net, width, jumper, or route metadata");
if (n2.length !== e33.route.length)
throw new Error("repair04 merge received an invalid lock mask");
if (t2.route.length === 0)
throw new Error("repair04 merge rejected an empty replacement route");
if (oa(e33.route[0]) !== oa(t2.route[0]) || oa(e33.route[e33.route.length - 1]) !== oa(t2.route[t2.route.length - 1]))
throw new Error("repair04 merge rejected a moved fragment endpoint");
let s2 = 0;
for (let o3 = 0;o3 < e33.route.length; o3 += 1) {
if (!n2[o3])
continue;
const i3 = oa(e33.route[o3]);
for (;s2 < t2.route.length && oa(t2.route[s2]) !== i3; )
s2 += 1;
if (s2 === t2.route.length)
throw new Error("repair04 merge rejected a moved or removed locked point");
s2 += 1;
}
if (oa(D_(e33, o2)) !== oa(D_(t2, o2)))
throw new Error("repair04 merge rejected modified geometry in the fixed boundary collar");
for (let n3 = 1;n3 < e33.route.length; n3 += 1) {
const o3 = e33.route[n3 - 1], i3 = e33.route[n3];
if (!(o3.toNextSegmentType === "through_obstacle" || o3.insideJumperPad === true || i3.insideJumperPad === true || (e33.jumpers ?? []).some((e34) => na(o3, { ...e34.start, z: o3.z }) && na(i3, { ...e34.end, z: i3.z }) || na(o3, { ...e34.end, z: o3.z }) && na(i3, { ...e34.start, z: i3.z }))))
continue;
const r3 = oa([o3, i3]);
if (!t2.route.some((e34, n4) => n4 + 1 < t2.route.length && oa([e34, t2.route[n4 + 1]]) === r3))
throw new Error("repair04 merge rejected a changed atomic jumper or through-obstacle span");
}
for (const n3 of t2.route) {
if (![n3.x, n3.y, n3.z].every(Number.isFinite) || !Number.isInteger(n3.z) || n3.z < 0 || n3.z >= r2 || !Ks(n3, i2))
throw new Error("repair04 merge rejected invalid or out-of-region geometry");
if ((n3.pcb_port_id !== undefined || n3.insideJumperPad === true || n3.toNextSegmentCircuitJsonMetadata !== undefined) && !e33.route.some((e34) => oa(e34) === oa(n3)))
throw new Error("repair04 merge rejected invented or moved terminal/circuit metadata");
if (n3.traceThickness !== undefined && (!Number.isFinite(n3.traceThickness) || n3.traceThickness <= 0 || n3.traceThickness > Math.max(e33.traceThickness, ...e33.route.map((e34) => e34.traceThickness ?? 0)) + Qs))
throw new Error("repair04 merge rejected increased per-point copper width");
}
for (let n3 = 1;n3 < t2.route.length; n3 += 1) {
const o3 = t2.route[n3 - 1], i3 = t2.route[n3];
if (o3.toNextSegmentType === "through_obstacle" && !e33.route.some((t3, n4) => n4 + 1 < e33.route.length && oa([t3, e33.route[n4 + 1]]) === oa([o3, i3])))
throw new Error("repair04 merge rejected an invented through-obstacle span");
if (o3.z !== i3.z && o3.toNextSegmentType !== "through_obstacle" && (Math.abs(o3.x - i3.x) > Qs || Math.abs(o3.y - i3.y) > Qs || !t2.vias.some((e34) => Math.abs(e34.x - o3.x) <= Qs && Math.abs(e34.y - o3.y) <= Qs)))
throw new Error("repair04 merge rejected a disconnected or missing via");
}
for (const n3 of t2.vias) {
if (!(Number.isFinite(n3.x) && Number.isFinite(n3.y) && Ks(n3, i2) && t2.route.some((e34) => Math.abs(e34.x - n3.x) <= Qs && Math.abs(e34.y - n3.y) <= Qs)))
throw new Error("repair04 merge rejected an invalid via position");
if (!Ks(n3, o2, 0.00000004) && !e33.vias.some((e34) => oa(e34) === oa(n3)))
throw new Error("repair04 merge rejected a new via in the boundary collar");
}
for (const n3 of e33.vias)
if (!Ks(n3, o2, 0.00000004) && !t2.vias.some((e34) => oa(e34) === oa(n3)))
throw new Error("repair04 merge rejected a changed via in the boundary collar");
};
var z_ = (e33, t2) => {
for (const n2 of t2) {
const t3 = e33[e33.length - 1];
t3 && na(t3, n2) && oa(t3) === oa(n2) || e33.push(structuredClone(n2));
}
};
var B_ = (e33, t2, n2) => {
const o2 = new Set(t2.route.map(oa)), i2 = new Set(n2.flatMap((e34) => e34.originalFragment.route.map(oa)).filter((e34) => !o2.has(e34))), r2 = [];
for (const t3 of e33)
for (r2.push(t3);r2.length >= 3; ) {
const e34 = r2[r2.length - 3], t4 = r2[r2.length - 2], n3 = r2[r2.length - 1];
if (!i2.has(oa(t4)))
break;
if (e34.z !== t4.z || t4.z !== n3.z && e34.toNextSegmentType !== "through_obstacle")
break;
if (e34.toNextSegmentType !== t4.toNextSegmentType || e34.insideJumperPad !== t4.insideJumperPad || e34.traceThickness !== t4.traceThickness || oa(e34.toNextSegmentCircuitJsonMetadata) !== oa(t4.toNextSegmentCircuitJsonMetadata))
break;
const o3 = n3.x - e34.x, s2 = n3.y - e34.y, a2 = o3 * o3 + s2 * s2;
if (a2 <= 0.00000000000000010000000000000001)
break;
const c2 = (t4.x - e34.x) * s2 - (t4.y - e34.y) * o3, l2 = ((t4.x - e34.x) * o3 + (t4.y - e34.y) * s2) / a2;
if (Math.abs(c2) > Qs * Math.sqrt(a2) || l2 < 0 || l2 > 1)
break;
r2.splice(r2.length - 2, 1);
}
return r2;
};
var F_ = (e33) => {
if (!Number.isInteger(e33.segmentIndex) || e33.segmentIndex < 0 || !Number.isFinite(e33.t) || e33.t < 0 || e33.t > 1)
throw new Error("repair04 merge received invalid fragment provenance");
return e33.segmentIndex + e33.t;
};
var j_ = (e33, t2) => {
const n2 = Math.max(Math.abs(e33), Math.abs(t2));
if (n2 === 0 || n2 === Number.POSITIVE_INFINITY)
return n2;
const o2 = e33 / n2, i2 = t2 / n2;
return n2 * Math.sqrt(o2 * o2 + i2 * i2);
};
function $_(e33, t2, n2) {
return e33.minX - n2 - Qs > t2.maxX || e33.maxX + n2 + Qs < t2.minX || e33.minY - n2 - Qs > t2.maxY || e33.maxY + n2 + Qs < t2.minY;
}
var Y_ = class extends De {
input;
stats;
phase = "initialize";
cursor = 0;
barrierCount = 0;
output;
prepareObstacle;
prepareRoute;
prepareTrace;
indexBarrier;
seedSearch;
searchBatch;
constructor(e33) {
super(), this.input = e33, this.stats = e33.stats ?? { nodesPopped: 0, completionReason: "no-path" }, this.MAX_ITERATIONS = Math.ceil((e33.maxNodes ?? 30000) / 128) + Math.ceil(e33.srj.obstacles.length / 128) + Math.ceil(e33.routes.length / 32) + Math.ceil((e33.srj.traces?.length ?? 0) / 32) + e33.srj.obstacles.length * e33.srj.layerCount + e33.routes.reduce((e34, t2) => e34 + t2.route.length, 0) + (e33.srj.traces ?? []).reduce((e34, t2) => e34 + t2.route.length, 0) + 32;
}
finish(e33) {
this.output = e33, this.phase = "finished", this.solved = true, this.progress = 1, this.prepareObstacle = undefined, this.prepareRoute = undefined, this.prepareTrace = undefined, this.indexBarrier = undefined, this.seedSearch = undefined, this.searchBatch = undefined;
}
_step() {
if (this.phase === "initialize")
return void this.initialize();
if (this.phase === "seed")
return void this.seedSearch();
if (this.phase === "search")
return this.searchBatch(), void (this.solved || (this.progress = Math.min(0.99, this.stats.nodesPopped / (this.input.maxNodes ?? 30000))));
const e33 = this.cursor;
if (this.phase === "obstacles") {
const t2 = this.input.srj.obstacles;
for (;this.cursor < Math.min(e33 + 128, t2.length); this.cursor++)
this.prepareObstacle(t2[this.cursor]);
return void (this.cursor === t2.length && (this.phase = "routes", this.cursor = 0));
}
if (this.phase !== "routes") {
if (this.phase === "traces") {
const t2 = this.input.srj.traces ?? [];
for (;this.cursor < Math.min(e33 + 32, t2.length); this.cursor++)
this.prepareTrace(t2[this.cursor]);
return void (this.cursor === t2.length && (this.phase = "index", this.cursor = 0));
}
if (this.phase !== "index")
throw new Error("repair04: clearance path stepped after completion");
for (;this.cursor < Math.min(e33 + 128, this.barrierCount); this.cursor++)
this.indexBarrier(this.cursor);
this.cursor === this.barrierCount && (this.phase = "seed");
} else {
for (;this.cursor < Math.min(e33 + 32, this.input.routes.length); this.cursor++)
this.prepareRoute(this.input.routes[this.cursor]);
this.cursor === this.input.routes.length && (this.phase = "traces", this.cursor = 0);
}
}
initialize() {
const e33 = this.input, { srj: t2, routes: n2, routeIndex: o2, start: i2, end: r2, bounds: s2, traceThickness: a2 } = e33, c2 = e33.heuristicWeight ?? 1;
if (!Number.isFinite(c2) || c2 < 1)
throw new Error("repair04: heuristic weight must be finite and at least one");
const l2 = (t3, n3) => {
const o3 = e33.getAdditionalEdgeCost?.(t3, n3) ?? 0;
if (Number.isNaN(o3) || o3 < 0)
throw new Error("repair04: additional edge costs must be nonnegative");
return o3;
};
if (e33.maxNodes !== undefined && (!Number.isSafeInteger(e33.maxNodes) || e33.maxNodes < 1))
throw new Error("repair04: maxNodes must be a positive safe integer");
if (this.stats && (this.stats.nodesPopped = 0, this.stats.completionReason = "no-path"), e33.allowLayerChanges === false && i2.z !== r2.z)
return void this.finish(null);
const h2 = n2[o2], d2 = e33.viaHoleDiameter ?? h2.viaDiameter;
if (!Number.isFinite(d2) || d2 <= 0 || d2 > h2.viaDiameter)
throw new Error("repair04: via hole diameter must be positive and fit the copper");
const u2 = d2 + e33.viaClearance, p2 = (e34, t3) => {
for (let n3 = t3;n3; n3 = n3.previous)
if ((e34.x !== n3.x || e34.y !== n3.y) && Math.hypot(e34.x - n3.x, e34.y - n3.y) + Qs < u2)
return false;
return true;
}, m2 = (e34) => {
let t3;
for (let n3 = 1;n3 < e34.length; n3++) {
const o3 = e34[n3 - 1], i3 = e34[n3];
if (o3.z !== i3.z && o3.toNextSegmentType !== "through_obstacle") {
if (!p2(o3, t3))
return false;
o3.x === t3?.x && o3.y === t3?.y || (t3 = { x: o3.x, y: o3.y, previous: t3 });
}
}
return true;
}, g2 = new Map, f2 = (e34) => {
const t3 = g2.get(e34);
if (t3 === undefined || t3 === e34)
return e34;
const n3 = f2(t3);
return g2.set(e34, n3), n3;
}, _2 = (e34) => {
const t3 = e34.filter((e35) => Boolean(e35));
if (!t3.length)
return;
const n3 = f2(t3[0]);
for (const e35 of t3)
g2.set(f2(e35), n3);
};
for (const e34 of t2.connections) {
const t3 = e34;
_2([t3.name, t3.rootConnectionName, t3.netConnectionName, t3.__netConnectionName, ...t3.mergedConnectionNames ?? [], ...t3.__rootConnectionNames ?? [], ...t3.pointsToConnect.flatMap((e35) => [e35.pcb_port_id, e35.pointId])]);
}
for (const e34 of t2.obstacles)
_2(e34.connectedTo);
for (const e34 of n2)
_2([e34.connectionName, e34.rootConnectionName]);
const y2 = f2(h2.connectionName), b2 = (e34) => e34 === "top" ? 0 : e34 === "bottom" ? t2.layerCount - 1 : Number(e34.slice(5)), x2 = [s2.minX, s2.maxX, s2.minY, s2.maxY, i2.x, i2.y, r2.x, r2.y, a2, h2.viaDiameter, e33.traceClearance, e33.viaClearance, t2.defaultObstacleMargin ?? 0, t2.minTraceToPadEdgeClearance ?? 0, t2.minTraceToHoleEdgeClearance ?? 0, t2.minViaEdgeToPadEdgeClearance ?? 0].every((e34) => Number.isFinite(e34) && Math.abs(e34) <= 1e4), v2 = [], I2 = (e34, n3, o3, i3, r3 = false, s3 = false, a3 = false) => {
const c3 = i3 ? Math.hypot(i3.width, i3.height) / 2 : o3, l3 = i3 ? Math.cos(i3.rotation) : 1, h3 = i3 ? Math.sin(i3.rotation) : 0, d3 = { minX: Math.min(e34.x, n3.x) - c3, maxX: Math.max(e34.x, n3.x) + c3, minY: Math.min(e34.y, n3.y) - c3, maxY: Math.max(e34.y, n3.y) + c3 }, u3 = i3 && x2 ? ((e35, t3, n4, o4, i4, r4) => {
if (e35.x !== t3.x || e35.y !== t3.y || !Number.isFinite(n4.rotation) || n4.width <= 0 || n4.height <= 0 || ![e35.x, e35.y, n4.width, n4.height, r4.minX, r4.maxX, r4.minY, r4.maxY].every((e36) => Number.isFinite(e36) && Math.abs(e36) <= 1e4))
return r4;
const s4 = o4 * o4 + i4 * i4;
if (!Number.isFinite(s4) || Math.abs(s4 - 1) > 0.000000000001)
return r4;
const a4 = n4.width / 2, c4 = n4.height / 2, l4 = (Math.abs(o4) * a4 + Math.abs(i4) * c4) / s4 + 0.00000001, h4 = (Math.abs(i4) * a4 + Math.abs(o4) * c4) / s4 + 0.00000001, d4 = { minX: e35.x - l4, maxX: e35.x + l4, minY: e35.y - h4, maxY: e35.y + h4 };
return d4.minX < r4.minX || d4.maxX > r4.maxX || d4.minY < r4.minY || d4.maxY > r4.maxY ? r4 : d4;
})(e34, n3, i3, l3, h3, d3) : d3;
v2.push({ a: e34, b: n3, radius: o3, rect: i3, viaOnly: r3, pad: s3, isNonPlatedHole: a3, rectCos: l3, rectSin: h3, rectBounds: i3 ? { minX: -i3.width / 2, maxX: i3.width / 2, minY: -i3.height / 2, maxY: i3.height / 2 } : undefined, visitedQuery: 0, ...u3, ...Us(t2, e34, n3) });
};
this.prepareObstacle = (e34) => {
const t3 = e34.connectedTo.some((e35) => f2(e35) === y2), n3 = e34.__zLayers ?? e34.zLayers ?? e34.layers.map(b2), o3 = e34.isNonPlatedHole && e34.shape === "circle" || e34.type === "oval" && e34.width === e34.height && e34.ccwRotationDegrees === undefined && n3.length > 1;
for (const i3 of n3) {
const n4 = { ...e34.center, z: i3 };
I2(n4, n4, o3 ? e34.width / 2 : 0, o3 ? undefined : { width: e34.width, height: e34.height, rotation: (e34.ccwRotationDegrees ?? 0) * Math.PI / 180 }, t3, o3, e34.isNonPlatedHole);
}
this.barrierCount = v2.length;
}, this.prepareRoute = (e34) => {
if (f2(e34.connectionName) !== y2) {
for (let t3 = 1;t3 < e34.route.length; t3++) {
const n3 = e34.route[t3 - 1], o3 = e34.route[t3];
n3.toNextSegmentType !== "through_obstacle" && I2(n3, o3, n3.z !== o3.z ? e34.viaDiameter / 2 : Math.max(n3.traceThickness ?? e34.traceThickness, o3.traceThickness ?? e34.traceThickness) / 2);
}
this.barrierCount = v2.length;
}
}, this.prepareTrace = (e34) => {
if (f2(e34.connection_name) === y2)
return;
const n3 = qs(e34, t2.minTraceWidth);
for (let e35 = 1;e35 < n3.route.length; e35++) {
const t3 = n3.route[e35 - 1], o3 = n3.route[e35];
t3.route_type === "wire" && o3.route_type === "wire" && t3.layer === o3.layer && I2({ x: t3.x, y: t3.y, z: b2(t3.layer) }, { x: o3.x, y: o3.y, z: b2(o3.layer) }, Math.max(t3.width, o3.width) / 2), o3.route_type === "via" && I2({ x: o3.x, y: o3.y, z: b2(o3.from_layer) }, { x: o3.x, y: o3.y, z: b2(o3.to_layer) }, (o3.via_diameter ?? h2.viaDiameter) / 2);
}
this.barrierCount = v2.length;
};
const S2 = new Map, C2 = Math.max(h2.viaDiameter, a2) / 2 + Math.max(e33.traceClearance, e33.viaClearance, t2.defaultObstacleMargin ?? 0, t2.minTraceToPadEdgeClearance ?? 0, t2.minTraceToHoleEdgeClearance ?? 0, t2.minViaEdgeToPadEdgeClearance ?? 0) + 0.00001;
this.indexBarrier = (e34) => {
const t3 = v2[e34];
for (let e35 = Math.floor(Math.max(t3.minX, s2.minX - C2));e35 <= Math.floor(Math.min(t3.maxX, s2.maxX + C2)); e35++) {
let n3 = S2.get(e35);
for (let o3 = Math.floor(Math.max(t3.minY, s2.minY - C2));o3 <= Math.floor(Math.min(t3.maxY, s2.maxY + C2)); o3++) {
n3 || (n3 = new Map, S2.set(e35, n3));
const i3 = n3.get(o3);
i3 ? i3.push(t3) : n3.set(o3, [t3]);
}
}
};
let P2 = 0;
const M2 = { x: 0, y: 0 }, w2 = { x: 0, y: 0 }, N2 = (n3, o3) => {
const i3 = n3.z !== o3.z, r3 = i3 ? h2.viaDiameter / 2 : a2 / 2, s3 = Math.max(i3 ? e33.viaClearance : e33.traceClearance, t2.defaultObstacleMargin ?? 0, i3 ? t2.minViaEdgeToPadEdgeClearance ?? 0 : t2.minTraceToPadEdgeClearance ?? 0), c3 = r3 + Math.max(s3, t2.minTraceToHoleEdgeClearance ?? 0) + 0.00001, l3 = ++P2, d3 = Math.min(n3.x, o3.x), u3 = Math.max(n3.x, o3.x), p3 = Math.min(n3.y, o3.y), m3 = Math.max(n3.y, o3.y), { minZ: g3, maxZ: f3 } = Us(t2, n3, o3);
for (let a3 = Math.floor(d3 - c3);a3 <= Math.floor(u3 + c3); a3++) {
const h3 = S2.get(a3);
if (h3)
for (let a4 = Math.floor(p3 - c3);a4 <= Math.floor(m3 + c3); a4++) {
const c4 = h3.get(a4);
if (c4)
for (const a5 of c4) {
if (a5.viaOnly && !i3)
continue;
if (a5.visitedQuery === l3)
continue;
if (a5.visitedQuery = l3, a5.maxZ < g3 || a5.minZ > f3)
continue;
const c5 = r3 + (a5.isNonPlatedHole && !i3 && t2.minTraceToHoleEdgeClearance !== undefined ? t2.minTraceToHoleEdgeClearance : a5.viaOnly ? Js(t2, e33.viaClearance, true) : a5.rect || a5.pad ? s3 : i3 && a5.minZ !== a5.maxZ ? e33.viaClearance : e33.traceClearance);
if (u3 + c5 < a5.minX || d3 - c5 > a5.maxX || m3 + c5 < a5.minY || p3 - c5 > a5.maxY)
continue;
let h4;
if (a5.rect ? (M2.x = (n3.x - a5.a.x) * a5.rectCos + (n3.y - a5.a.y) * a5.rectSin, M2.y = -(n3.x - a5.a.x) * a5.rectSin + (n3.y - a5.a.y) * a5.rectCos, w2.x = (o3.x - a5.a.x) * a5.rectCos + (o3.y - a5.a.y) * a5.rectSin, w2.y = -(o3.x - a5.a.x) * a5.rectSin + (o3.y - a5.a.y) * a5.rectCos, h4 = Dt(M2, w2, a5.rectBounds)) : h4 = kt(n3, o3, a5.a, a5.b) - a5.radius, h4 + Qs < c5)
return false;
}
}
}
return true;
};
this.seedSearch = () => {
if (!N2(i2, i2) || !N2(r2, r2))
return void this.finish(null);
if (e33.existingPath) {
const t3 = e33.existingPath, n4 = t3[0], o4 = t3.at(-1);
if (!n4 || !o4 || n4.x !== i2.x || n4.y !== i2.y || n4.z !== i2.z || o4.x !== r2.x || o4.y !== r2.y || o4.z !== r2.z)
throw new Error("repair04: existing clearance path must match its anchors");
if (t3.some((e34, n5) => {
const o5 = t3[n5 - 1];
return Boolean(o5 && o5.z !== e34.z && (o5.x !== e34.x || o5.y !== e34.y));
}))
throw new Error("repair04: existing clearance path has a non-colocated layer transition");
if (m2(t3) && (e33.allowLayerChanges !== false || t3.every((e34) => e34.z === i2.z)) && t3.slice(1).every((e34, n5) => N2(t3[n5], e34) && l2(t3[n5], e34) === 0))
return this.stats && (this.stats.completionReason = "found"), void this.finish(t3.map((e34) => ({ ...e34 })));
}
const n3 = e33.gridSize ?? 0.1;
if (!Number.isFinite(n3) || n3 <= 0)
throw new Error("repair04: clearance grid size must be positive and finite");
const o3 = Math.floor((s2.maxX - s2.minX) / n3), h3 = Math.floor((s2.maxY - s2.minY) / n3), d3 = (e34) => ({ x: s2.minX + (e34 % o3 + 0.5) * n3, y: s2.minY + (Math.floor(e34 / o3) % h3 + 0.5) * n3, z: Math.floor(e34 / (o3 * h3)), traceThickness: a2 }), u3 = (e34, t3, n4) => (n4 * h3 + t3) * o3 + e34, g3 = (e34) => Math.hypot(e34.x - r2.x, e34.y - r2.y) + (e34.z === r2.z ? 0 : 1), f3 = o3 * h3 * t2.layerCount, _3 = o3 > 0 && h3 > 0 && Number.isSafeInteger(t2.layerCount) && Number.isSafeInteger(f3) && f3 > 0 && f3 <= 1e6 && Number.isInteger(i2.z) && i2.z >= 0 && i2.z < t2.layerCount, y3 = new Zs(_3 ? f3 : undefined), b3 = new Map, x3 = new Map, v3 = new Map, I3 = (P3 = i2, u3(Math.max(0, Math.min(o3 - 1, Math.floor((P3.x - s2.minX) / n3))), Math.max(0, Math.min(h3 - 1, Math.floor((P3.y - s2.minY) / n3))), P3.z)), S3 = I3 % o3, C3 = Math.floor(I3 / o3) % h3;
var P3;
for (let e34 = -2;e34 <= 2; e34++)
for (let t3 = -2;t3 <= 2; t3++) {
const n4 = S3 + e34, r3 = C3 + t3;
if (n4 < 0 || n4 >= o3 || r3 < 0 || r3 >= h3)
continue;
const s3 = u3(n4, r3, i2.z), a3 = d3(s3);
if (!N2(i2, a3))
continue;
const p3 = Math.hypot(a3.x - i2.x, a3.y - i2.y) + l2(i2, a3);
Number.isFinite(p3) && (b3.set(s3, p3), x3.set(s3, -1), y3.push({ id: s3, cost: p3, priority: p3 + c2 * g3(a3) }));
}
const M3 = o3 * h3 * t2.layerCount, w3 = o3 > 0 && h3 > 0 && Number.isSafeInteger(t2.layerCount) && Number.isSafeInteger(M3) && M3 > 0 && Number.isSafeInteger(M3 * M3 - 1) && Number.isInteger(i2.z) && i2.z >= 0 && i2.z < t2.layerCount, T2 = c2 > 1 ? new Set : undefined, R2 = new Map, E2 = new Map;
let A2 = 0;
this.searchBatch = () => {
const s3 = Math.min(A2 + 128, e33.maxNodes ?? 30000);
for (;y3.length && A2 < s3; ) {
const s4 = y3.pop();
if (A2++, this.stats && (this.stats.nodesPopped = A2), s4.cost !== b3.get(s4.id))
continue;
T2?.add(s4.id);
const a3 = d3(s4.id), f4 = v3.get(s4.id);
if (a3.z === r2.z && Math.hypot(a3.x - r2.x, a3.y - r2.y) < 3 * n3 && N2(a3, r2) && Number.isFinite(l2(a3, r2))) {
const t3 = [r2];
for (let e34 = s4.id;e34 !== -1; e34 = x3.get(e34))
t3.push(d3(e34));
t3.push(i2);
const n4 = t3.reverse(), o4 = [i2], a4 = [0];
for (let t4 = 1;e33.getAdditionalEdgeCost && t4 < n4.length; t4++) {
const e34 = n4[t4 - 1], o5 = n4[t4];
a4.push(a4[t4 - 1] + (e34.z === o5.z ? Math.hypot(e34.x - o5.x, e34.y - o5.y) : 1) + l2(e34, o5));
}
let c3 = 0;
for (let t4 = 1;t4 < n4.length; ) {
let i3 = t4;
if (n4[t4].z === o4.at(-1).z)
for (let r3 = t4 + 1;r3 < n4.length && n4[r3].z === n4[t4].z; r3++)
N2(o4.at(-1), n4[r3]) && (!e33.getAdditionalEdgeCost || Math.hypot(n4[r3].x - n4[c3].x, n4[r3].y - n4[c3].y) + l2(n4[c3], n4[r3]) <= a4[r3] - a4[c3] + Qs) && (i3 = r3);
o4.push(n4[i3]), c3 = i3, t4 = i3 + 1;
}
if (!m2(o4))
throw new Error("repair04: search generated conflicting drill sites");
return this.stats && (this.stats.completionReason = "found"), void this.finish(o4);
}
const _4 = s4.id % o3, I4 = Math.floor(s4.id / o3) % h3, S4 = [];
for (let e34 = -1;e34 <= 1; e34++)
for (let t3 = -1;t3 <= 1; t3++)
e34 === 0 && t3 === 0 || _4 + e34 < 0 || _4 + e34 >= o3 || I4 + t3 < 0 || I4 + t3 >= h3 || S4.push(u3(_4 + e34, I4 + t3, a3.z));
if (e33.allowLayerChanges !== false && p2(a3, f4))
for (let e34 = 0;e34 < t2.layerCount; e34++)
e34 !== a3.z && S4.push(u3(_4, I4, e34));
for (const e34 of S4) {
if (T2?.has(e34))
continue;
const n4 = d3(e34), i3 = s4.cost + (a3.z === n4.z ? Math.hypot(a3.x - n4.x, a3.y - n4.y) : 1), r3 = b3.get(e34) ?? 1 / 0;
if (i3 >= r3)
continue;
const u4 = Math.min(s4.id, e34), p3 = Math.max(s4.id, e34), m3 = w3 ? u4 * M3 + p3 : `${u4},${p3}`, _5 = w3 && a3.z !== n4.z && t2.allowBlindAndBuriedVias !== true ? s4.id % (o3 * h3) : undefined;
let I5 = _5 === undefined ? R2.get(m3) : E2.get(_5);
if (I5 === undefined && (I5 = N2(a3, n4), _5 === undefined ? R2.set(m3, I5) : E2.set(_5, I5)), !I5)
continue;
const S5 = i3 + l2(a3, n4);
S5 >= r3 || (a3.z === n4.z || a3.x === f4?.x && a3.y === f4?.y ? f4 ? v3.set(e34, f4) : v3.delete(e34) : v3.set(e34, { x: a3.x, y: a3.y, previous: f4 }), b3.set(e34, S5), x3.set(e34, s4.id), y3.push({ id: e34, cost: S5, priority: S5 + c2 * g3(n4) }));
}
}
y3.length && A2 < (e33.maxNodes ?? 30000) || (this.stats.completionReason = y3.length ? "node-limit" : "no-path", this.finish(null));
}, this.phase = "search";
}, this.phase = "obstacles";
}
getOutput() {
if (!this.solved || this.failed || this.output === undefined)
throw new Error("repair04: clearance path output requested before completion");
return this.output;
}
getResult() {
return this.getOutput();
}
};
function X_(e33, t2) {
const n2 = [];
for (let e34 = 1;e34 < t2.length; e34++) {
const o2 = t2[e34 - 1], i2 = t2[e34];
if (o2.z !== i2.z && o2.toNextSegmentType !== "through_obstacle") {
if (o2.x !== i2.x || o2.y !== i2.y)
throw new Error("repair04: negotiated via endpoints must coincide");
n2.some((e35) => e35.x === i2.x && e35.y === i2.y) || n2.push({ x: i2.x, y: i2.y });
}
}
return { ...e33, route: t2, vias: n2 };
}
var W_ = class extends De {
input;
phase = "initialize";
routeCursor = 0;
copperCursor = 0;
spanCount = 0;
output;
pathSolver;
prepareRoute;
finishSetup;
selectSpan;
prepareCopper;
startPath;
applyPath;
updateWorkStats;
constructor(e33) {
super(), this.input = e33, this.stats = { pathSearchNodes: 0, pathSearchCalls: 0, unresolvedSpanCount: 0 }, this.MAX_ITERATIONS = Math.ceil(e33.maxPathSearchNodes / 128) + e33.maxPathSearchCalls * (e33.routes.reduce((e34, t2) => e34 + t2.route.length, 0) + e33.srj.obstacles.length * e33.srj.layerCount + 128) + e33.routes.length + 32;
}
_step() {
if (this.phase !== "initialize") {
if (this.phase === "spans") {
const e33 = Math.min(this.routeCursor + 32, this.input.routes.length);
for (;this.routeCursor < e33; this.routeCursor++)
this.prepareRoute(this.routeCursor);
return void (this.routeCursor === this.input.routes.length && (this.phase = "setup"));
}
if (this.phase !== "setup") {
if (this.phase === "select")
return this.selectSpan(), void this.updateWorkStats();
if (this.phase === "coppers") {
const e33 = Math.min(this.copperCursor + 32, this.spanCount);
for (;this.copperCursor < e33; this.copperCursor++)
this.prepareCopper(this.copperCursor);
return void (this.copperCursor === this.spanCount && (this.phase = "start-path"));
}
if (this.phase !== "start-path") {
if (this.phase === "path") {
const e33 = this.pathSolver;
if (!e33)
throw new Error("repair04: negotiated search child is missing");
return e33.step(), e33.failed ? (this.failed = true, this.error = e33.error) : e33.solved && (this.activeSubSolver = null, this.phase = "apply-path"), void this.updateWorkStats();
}
if (this.phase === "apply-path") {
const e33 = this.pathSolver;
if (!e33)
throw new Error("repair04: completed negotiated search child is missing");
return this.applyPath(e33.getOutput()), this.applyPath = undefined, void this.updateWorkStats();
}
throw new Error("repair04: negotiated clearance stepped after completion");
}
this.startPath();
} else
this.finishSetup();
} else
this.initialize();
}
initialize() {
const e33 = this.input;
for (const t3 of [e33.maxPathSearchNodes, e33.maxPathSearchCalls])
if (!Number.isSafeInteger(t3) || t3 < 0)
throw new Error("repair04: negotiated work budgets must be nonnegative integers");
if (e33.maxPathSearchNodesPerCall !== undefined && (!Number.isSafeInteger(e33.maxPathSearchNodesPerCall) || e33.maxPathSearchNodesPerCall < 1))
throw new Error("repair04: per-path work budget must be a positive integer");
if (e33.pathHeuristicWeight !== undefined && (!Number.isFinite(e33.pathHeuristicWeight) || e33.pathHeuristicWeight < 1))
throw new Error("repair04: heuristic weight must be finite and at least one");
if (e33.pathGridSizeScale !== undefined && (!Number.isFinite(e33.pathGridSizeScale) || e33.pathGridSizeScale <= 0))
throw new Error("repair04: path grid scale must be positive and finite");
if (e33.viaHoleDiameter !== undefined && (!Number.isFinite(e33.viaHoleDiameter) || e33.viaHoleDiameter <= 0 || e33.routes.some((t3) => e33.viaHoleDiameter > t3.viaDiameter)))
throw new Error("repair04: via hole diameter must be positive and fit the copper");
const t2 = (t3) => t3.x >= e33.bounds.minX - Qs && t3.x <= e33.bounds.maxX + Qs && t3.y >= e33.bounds.minY - Qs && t3.y <= e33.bounds.maxY + Qs, n2 = [], o2 = e33.routes.map(() => []);
this.prepareRoute = (i2) => {
const r2 = e33.routes[i2], s2 = r2.route, a2 = s2.flatMap((t3, n3) => {
const o3 = s2[n3 - 1], a3 = s2[n3 + 1], c2 = t3.traceThickness ?? r2.traceThickness, l2 = o3 && (o3.traceThickness ?? r2.traceThickness) !== c2 || a3 && (a3.traceThickness ?? r2.traceThickness) !== c2, h2 = o3 && o3.z !== t3.z && (!e33.allowLayerChanges || e33.isLocked(i2, n3) || e33.isLocked(i2, n3 - 1)) || a3 && a3.z !== t3.z && (!e33.allowLayerChanges || e33.isLocked(i2, n3) || e33.isLocked(i2, n3 + 1));
return n3 === 0 || n3 === s2.length - 1 || e33.isLocked(i2, n3) || t3.pcb_port_id || t3.toNextSegmentType || t3.insideJumperPad || l2 || h2 ? [n3] : [];
});
for (let c2 = 1;c2 < a2.length; c2++) {
const l2 = s2.slice(a2[c2 - 1], a2[c2] + 1), h2 = l2[0].traceThickness ?? r2.traceThickness, d2 = l2.slice(1).every((t3, n3) => {
const o3 = l2[n3], i3 = (o3.x + t3.x) / 2, r3 = (o3.y + t3.y) / 2;
return i3 > e33.bounds.minX + 0.00000004 && i3 < e33.bounds.maxX - 0.00000004 && r3 > e33.bounds.minY + 0.00000004 && r3 < e33.bounds.maxY - 0.00000004;
}), u2 = l2.slice(1).every((t3, n3) => {
const o3 = l2[n3], r3 = a2[c2 - 1] + n3;
return o3.z === t3.z || !e33.isLocked(i2, r3) && !e33.isLocked(i2, r3 + 1);
}), p2 = l2.every(t2) && d2 && u2 && !r2.jumpers?.length && l2.every((e34) => !e34.toNextSegmentType && !e34.insideJumperPad && (e34.traceThickness ?? r2.traceThickness) === h2) && (e33.allowLayerChanges || l2.every((e34) => e34.z === l2[0].z));
o2[i2].push(n2.length), n2.push({ routeIndex: i2, mutable: Boolean(p2), route: X_({ ...r2, traceThickness: h2 }, l2) });
}
}, this.finishSetup = () => {
const t3 = n2.map((e34) => e34.route), i2 = n2.filter((e34) => !e34.mutable).map((e34) => e34.route), r2 = x_(e33.srj, e33.routes), s2 = (e34) => r2.get(e34.connectionName) ?? e34.connectionName, a2 = new Set;
for (const e34 of n2)
for (const t4 of [e34.route.route[0], e34.route.route.at(-1)]) {
const n3 = t4.traceThickness ?? e34.route.traceThickness, o3 = `${s2(e34.route)}|${t4.x}|${t4.y}|${t4.z}|${n3}`;
if (a2.has(o3))
continue;
a2.add(o3);
const r3 = { x: t4.x, y: t4.y, z: t4.z };
i2.push({ ...e34.route, traceThickness: n3, route: [r3, r3], vias: [] });
}
const c2 = n2.map(({ route: e34 }) => {
let t4 = 0;
for (let n3 = 1;n3 < e34.route.length; n3++) {
const o3 = e34.route[n3 - 1], i3 = e34.route[n3];
t4 += o3.z === i3.z ? Math.hypot(o3.x - i3.x, o3.y - i3.y) : 1;
}
return t4;
}), l2 = new Set, h2 = new Set(e33.dirtyRouteIndices), d2 = [], u2 = new Set, p2 = (e34) => {
u2.has(e34) || l2.has(e34) || !n2[e34].mutable || (u2.add(e34), d2.push(e34));
};
n2.forEach((e34, t4) => {
h2.has(e34.routeIndex) && p2(t4);
});
let m2 = 0, g2 = 0, f2 = 0;
this.spanCount = n2.length, this.updateWorkStats = () => {
this.stats = { pathSearchNodes: m2 + (this.pathSolver?.stats.nodesPopped ?? 0), pathSearchCalls: g2, unresolvedSpanCount: u2.size + l2.size }, this.progress = this.solved ? 1 : Math.min(0.99, Math.max(this.stats.pathSearchNodes / Math.max(1, e33.maxPathSearchNodes), g2 / Math.max(1, e33.maxPathSearchCalls)));
}, this.selectSpan = () => {
if (!(f2 < d2.length && m2 < e33.maxPathSearchNodes && g2 < e33.maxPathSearchCalls))
return this.output = { routes: e33.routes.map((e34, n3) => {
if (!o2[n3].length)
return e34;
return X_(e34, o2[n3].flatMap((e35, n4) => n4 === 0 ? t3[e35].route : t3[e35].route.slice(1)));
}), pathSearchNodes: m2, pathSearchCalls: g2, unresolvedSpanCount: u2.size + l2.size }, this.solved = true, void (this.phase = "finished");
const r3 = d2[f2++];
u2.delete(r3);
const a3 = t3[r3], h3 = s2(a3), _2 = [];
this.copperCursor = 0, this.prepareCopper = (o3) => {
if (o3 === r3)
return;
const i3 = t3[o3], a4 = s2(i3);
for (let t4 = 1;t4 < i3.route.length; t4++) {
const r4 = i3.route[t4 - 1], s3 = i3.route[t4];
if (r4.toNextSegmentType === "through_obstacle")
continue;
const c3 = !n2[o3].mutable || l2.has(o3);
if (r4.z === s3.z && (a4 === h3 || c3))
continue;
const d3 = (r4.z !== s3.z ? i3.viaDiameter : Math.max(r4.traceThickness ?? i3.traceThickness, s3.traceThickness ?? i3.traceThickness)) / 2, u3 = { a: r4, b: s3, radius: d3, minX: Math.min(r4.x, s3.x), maxX: Math.max(r4.x, s3.x), minY: Math.min(r4.y, s3.y), maxY: Math.max(r4.y, s3.y), ...Us(e33.srj, r4, s3), spanIndex: o3, owner: a4, index: _2.length, cellX: Math.floor(Math.min(r4.x, s3.x) - d3), cellY: Math.floor(Math.min(r4.y, s3.y) - d3), immutable: c3 };
_2.push(u3);
}
}, this.startPath = () => {
const n3 = (e34) => {
if (!e34.length)
return;
const t4 = new je(e34.length);
for (const n4 of e34)
t4.add(n4.minX - n4.radius - Qs, n4.minY - n4.radius - Qs, n4.maxX + n4.radius + Qs, n4.maxY + n4.radius + Qs);
return t4.finish(), { index: t4, copper: e34 };
}, o3 = n3(_2), s3 = new Map;
for (let t4 = 0;t4 < e33.srj.layerCount; t4++)
s3.set(t4, n3(_2.filter((e34) => e34.minZ <= t4 && e34.maxZ >= t4)));
const d3 = (t4, n4) => {
const i3 = t4.z !== n4.z, r4 = Math.min(t4.x, n4.x), c3 = Math.max(t4.x, n4.x), l3 = Math.min(t4.y, n4.y), d4 = Math.max(t4.y, n4.y), u4 = (i3 ? a3.viaDiameter : a3.traceThickness) / 2 + Math.max(e33.traceClearance, e33.viaClearance), p3 = [], m3 = Us(e33.srj, t4, n4), g3 = i3 ? o3 : s3.get(t4.z), f4 = g3?.index.search(r4 - u4 - Qs, l3 - u4 - Qs, c3 + u4 + Qs, d4 + u4 + Qs) ?? [];
for (const o4 of f4) {
const s4 = g3.copper[o4], u5 = i3 && s4.minZ !== s4.maxZ, f5 = s4.minZ <= m3.maxZ && s4.maxZ >= m3.minZ;
if (!f5 && !u5)
continue;
if (s4.immutable && !u5)
continue;
if (s4.owner === h3 && (!u5 || t4.x === s4.a.x && t4.y === s4.a.y))
continue;
const _4 = (i3 ? a3.viaDiameter : a3.traceThickness) / 2 + (u5 ? e33.viaClearance : e33.traceClearance) + s4.radius, y4 = (e33.viaHoleDiameter ?? a3.viaDiameter) / 2 + (e33.viaHoleDiameter ?? 2 * s4.radius) / 2 + e33.viaClearance, b3 = u5 ? f5 && s4.owner !== h3 ? Math.max(_4, y4) : y4 : _4;
if (r4 - b3 - Qs > s4.maxX || c3 + b3 + Qs < s4.minX || l3 - b3 - Qs > s4.maxY || d4 + b3 + Qs < s4.minY)
continue;
const x2 = kt(t4, n4, s4.a, s4.b);
x2 < b3 - Qs && p3.push({ copper: s4, ratio: (b3 - x2) / (b3 * b3) });
}
const _3 = Math.floor(r4 - u4), y3 = Math.floor(l3 - u4);
return p3.sort((e34, t5) => {
const n5 = Math.max(_3, e34.copper.cellX) - Math.max(_3, t5.copper.cellX);
if (n5 !== 0)
return n5;
return Math.max(y3, e34.copper.cellY) - Math.max(y3, t5.copper.cellY) || e34.copper.index - t5.copper.index;
}), p3;
}, u3 = (t4, n4) => {
const o4 = (t4.x + n4.x) / 2, i3 = (t4.y + n4.y) / 2;
if (o4 <= e33.bounds.minX + 0.00000004 || o4 >= e33.bounds.maxX - 0.00000004 || i3 <= e33.bounds.minY + 0.00000004 || i3 >= e33.bounds.maxY - 0.00000004)
return 1 / 0;
const r4 = new Map;
for (const { copper: e34, ratio: o5 } of d3(t4, n4)) {
if (e34.owner === h3 || e34.immutable)
return 1 / 0;
r4.set(e34.owner, Math.max(r4.get(e34.owner) ?? 0, o5 * c2[e34.spanIndex]));
}
let s4 = 0;
for (const e34 of r4.values())
s4 += e34;
return (t4.z === n4.z ? Math.hypot(t4.x - n4.x, t4.y - n4.y) : 1) * s4;
}, f3 = new Map, y2 = { nodesPopped: 0, completionReason: "no-path" }, b2 = new Y_({ srj: e33.srj, routes: [...i2, a3], routeIndex: i2.length, start: a3.route[0], end: a3.route.at(-1), bounds: e33.bounds, traceThickness: a3.traceThickness, traceClearance: e33.traceClearance, viaClearance: e33.viaClearance, gridSize: Math.min(0.1, a3.traceThickness * (e33.pathGridSizeScale ?? 1) / 2), allowLayerChanges: e33.allowLayerChanges, maxNodes: Math.min(e33.maxPathSearchNodesPerCall ?? e33.maxPathSearchNodes, e33.maxPathSearchNodes - m2), heuristicWeight: e33.pathHeuristicWeight, stats: y2, getAdditionalEdgeCost: (t4, n4) => {
if (t4.z === n4.z || e33.srj.allowBlindAndBuriedVias === true || t4.x !== n4.x || t4.y !== n4.y)
return u3(t4, n4);
let o4 = f3.get(t4.x);
const i3 = o4?.get(t4.y);
if (i3 !== undefined)
return i3;
const r4 = u3(t4, n4);
return o4 || (o4 = new Map, f3.set(t4.x, o4)), o4.set(t4.y, r4), r4;
}, existingPath: a3.route, viaHoleDiameter: e33.viaHoleDiameter });
this.pathSolver = b2, this.activeSubSolver = b2, this.MAX_ITERATIONS = Math.max(this.MAX_ITERATIONS, this.iterations + b2.MAX_ITERATIONS + 3), this.phase = "path", this.applyPath = (n4) => {
if (g2++, m2 += y2.nodesPopped, e33.onSearch?.(y2), !n4)
return l2.add(r3), i2.push(a3), this.phase = "select", void (this.pathSolver = undefined);
t3[r3] = X_(a3, n4);
const o4 = new Set;
for (let e34 = 1;e34 < n4.length; e34++)
for (const { copper: t4 } of d3(n4[e34 - 1], n4[e34]))
o4.add(t4.spanIndex);
for (const e34 of [...o4].sort((e35, t4) => e35 - t4))
c2[e34]++, p2(e34);
o4.size && (c2[r3]++, p2(r3)), this.phase = "select", this.pathSolver = undefined;
};
}, this.phase = "coppers";
}, this.phase = "select", this.updateWorkStats();
}, this.phase = "spans";
}
getOutput() {
if (!this.solved || this.failed || !this.output)
throw new Error("repair04: negotiated clearance output requested before completion");
return this.output;
}
getResult() {
return this.getOutput();
}
};
var V_ = 256;
var H_ = 0.25;
function G_(e33, t2, n2, o2) {
const i2 = t2.x - e33.x, r2 = t2.y - e33.y, s2 = o2.x - n2.x, a2 = o2.y - n2.y, c2 = e33.x - n2.x, l2 = e33.y - n2.y, h2 = i2 * i2 + r2 * r2, d2 = i2 * s2 + r2 * a2, u2 = s2 * s2 + a2 * a2, p2 = i2 * c2 + r2 * l2, m2 = s2 * c2 + a2 * l2, g2 = h2 * u2 - d2 * d2;
let f2 = g2 > 0.000000000000001 ? Math.max(0, Math.min(1, (d2 * m2 - u2 * p2) / g2)) : 0;
u2 < 0.000000000000001 && (f2 = h2 > 0.000000000000001 ? Math.max(0, Math.min(1, -p2 / h2)) : 0);
let _2 = u2 > 0.000000000000001 ? (d2 * f2 + m2) / u2 : 0;
_2 < 0 ? (_2 = 0, f2 = h2 > 0.000000000000001 ? Math.max(0, Math.min(1, -p2 / h2)) : 0) : _2 > 1 && (_2 = 1, f2 = h2 > 0.000000000000001 ? Math.max(0, Math.min(1, (d2 - p2) / h2)) : 0);
const y2 = e33.x + f2 * i2 - n2.x - _2 * s2, b2 = e33.y + f2 * r2 - n2.y - _2 * a2;
return { s: f2, t: _2, x: y2, y: b2, distance: j_(y2, b2) };
}
function U_(e33, t2) {
let n2 = { x: 0, y: 0, depth: 1 / 0 };
for (let o2 = 0;o2 < t2.length; o2++) {
const i2 = t2[o2], r2 = t2[(o2 + 1) % t2.length], s2 = r2.x - i2.x, a2 = r2.y - i2.y, c2 = j_(s2, a2), l2 = a2 / c2, h2 = -s2 / c2, d2 = -((e33.x - i2.x) * l2 + (e33.y - i2.y) * h2);
if (d2 < 0)
return null;
d2 < n2.depth && (n2 = { x: l2, y: h2, depth: d2 });
}
return n2;
}
var Z_ = class extends De {
input;
phase = "geometry";
routes = [];
nets = new Map;
vertices = new Map;
segments = [];
pairs = [];
padContacts = [];
viaPadConstraints = new Map;
traceClearance = 0.1;
viaClearance = 0.1;
pairOuterIndex = 0;
pairInnerIndex = 1;
obstacleIndex = 0;
sweepIndex = 0;
sweepPairIndex = 0;
sweepPadIndex = 0;
preparedPairCount = 0;
projectedConstraintCount = 0;
constructor(e33) {
super(), this.input = e33, this.MAX_ITERATIONS = 1024;
}
prepareGeometry() {
const e33 = this.input, t2 = structuredClone(e33.routes), n2 = x_(e33.srj, t2), o2 = e33.traceClearance ?? 0.1, i2 = e33.viaClearance ?? 0.1, r2 = { minX: e33.bounds.minX + e33.boundaryMargin, maxX: e33.bounds.maxX - e33.boundaryMargin, minY: e33.bounds.minY + e33.boundaryMargin, maxY: e33.bounds.maxY - e33.boundaryMargin }, s2 = T_(e33.srj, t2, e33.bounds), a2 = new Map, c2 = t2.map((t3, o3) => t3.route.map((i3, c3) => {
const l3 = `${n2.get(t3.connectionName)}:${i3.x}:${i3.y}`;
let h3 = a2.get(l3);
return h3 || (h3 = { x: i3.x, y: i3.y, original: { x: i3.x, y: i3.y }, locked: false, radius: 0, revision: 0, bounds: r2, points: [] }, a2.set(l3, h3)), h3.points.push(i3), h3.locked ||= Boolean(e33.lockedPointIndices[o3][c3] || s2[o3].segmentTimes.has(c3) || s2[o3].segmentTimes.has(c3 - 1) || s2[o3].viaPositions.some((e34) => Math.hypot(e34.x - i3.x, e34.y - i3.y) <= Qs) || c3 === 0 || c3 === t3.route.length - 1 || i3.pcb_port_id || i3.insideJumperPad || i3.toNextSegmentType || i3.x <= r2.minX || i3.x >= r2.maxX || i3.y <= r2.minY || i3.y >= r2.maxY), h3;
})), l2 = [];
for (let o3 = 0;o3 < t2.length; o3++) {
const i3 = t2[o3];
for (let t3 = 1;t3 < i3.route.length; t3++) {
const r3 = i3.route[t3 - 1], s3 = i3.route[t3];
if (r3.toNextSegmentType || r3.insideJumperPad || s3.insideJumperPad)
continue;
const a3 = c2[o3][t3 - 1], h3 = c2[o3][t3], d3 = r3.z !== s3.z;
d3 && e33.allowViaMovement !== true && (a3.locked = h3.locked = true), l2.push({ a: a3, b: h3, initialBounds: { minX: Math.min(a3.x, h3.x), maxX: Math.max(a3.x, h3.x), minY: Math.min(a3.y, h3.y), maxY: Math.max(a3.y, h3.y) }, ...Us(e33.srj, r3, s3), radius: d3 ? i3.viaDiameter / 2 : Math.max(r3.traceThickness ?? i3.traceThickness, s3.traceThickness ?? i3.traceThickness) / 2, net: n2.get(i3.connectionName), routeIndex: o3, via: d3 });
}
}
for (const e34 of l2)
e34.a.radius = Math.max(e34.a.radius, e34.radius), e34.b.radius = Math.max(e34.b.radius, e34.radius);
if (e33.boardEdgeClearance !== undefined) {
const t3 = e33.srj.bounds;
for (const n3 of a2.values()) {
const o3 = n3.radius + e33.boardEdgeClearance;
n3.bounds = { minX: Math.max(r2.minX, Math.min(n3.original.x, t3.minX + o3)), maxX: Math.min(r2.maxX, Math.max(n3.original.x, t3.maxX - o3)), minY: Math.max(r2.minY, Math.min(n3.original.y, t3.minY + o3)), maxY: Math.min(r2.maxY, Math.max(n3.original.y, t3.maxY - o3)) };
}
}
this.routes = t2, this.nets = n2, this.vertices = a2, this.segments = l2, this.traceClearance = o2, this.viaClearance = i2;
const h2 = l2.length * (l2.length - 1) / 2, d2 = l2.length * e33.srj.obstacles.length;
this.MAX_ITERATIONS = this.iterations + Math.ceil(h2 / 4096) + Math.ceil(e33.srj.obstacles.length / 16) + V_ * Math.max(1, Math.ceil((h2 + d2) / 4096)) + 4, this.phase = "pairs";
}
preparePairs() {
let e33 = 0;
for (;e33 < 4096 && this.pairOuterIndex < this.segments.length; ) {
if (this.pairInnerIndex >= this.segments.length) {
this.pairOuterIndex++, this.pairInnerIndex = this.pairOuterIndex + 1;
continue;
}
const t2 = this.segments[this.pairOuterIndex], n2 = this.segments[this.pairInnerIndex++];
if (e33++, this.preparedPairCount++, t2.net === n2.net || t2.maxZ < n2.minZ || n2.maxZ < t2.minZ)
continue;
const o2 = t2.radius + n2.radius + Math.max(this.traceClearance, this.viaClearance) + 2 * Math.SQRT2 * H_;
$_(t2.initialBounds, n2.initialBounds, o2) || kt(t2.a, t2.b, n2.a, n2.b) <= o2 && this.pairs.push({ a: t2, b: n2, revisions: [-1, -1, -1, -1], contact: null });
}
this.pairOuterIndex >= this.segments.length && (this.phase = "obstacles"), this.stats = { ...this.stats, preparedPairCount: this.preparedPairCount, pairCount: this.pairs.length, lastPreparedPairBatchCount: e33 };
}
prepareObstacles() {
const { input: e33, nets: t2, segments: n2, traceClearance: o2, viaClearance: i2, padContacts: r2, viaPadConstraints: s2 } = this;
let a2 = 0;
for (;a2 < 16 && this.obstacleIndex < e33.srj.obstacles.length; ) {
const c2 = e33.srj.obstacles[this.obstacleIndex++];
a2++;
const l2 = (c2.ccwRotationDegrees ?? 0) * Math.PI / 180, h2 = Math.cos(l2), d2 = Math.sin(l2), u2 = new Set(c2.connectedTo.map((e34) => t2.get(e34) ?? e34)), p2 = c2.__zLayers ?? c2.zLayers ?? c2.layers.map((t3) => t3 === "top" ? 0 : t3 === "bottom" ? e33.srj.layerCount - 1 : Number(t3.slice(5))), m2 = [[-1, -1], [1, -1], [1, 1], [-1, 1]].map(([e34, t3]) => ({ x: c2.center.x + h2 * e34 * c2.width / 2 - d2 * t3 * c2.height / 2, y: c2.center.y + d2 * e34 * c2.width / 2 + h2 * t3 * c2.height / 2 })), g2 = { minX: Math.min(...m2.map((e34) => e34.x)), maxX: Math.max(...m2.map((e34) => e34.x)), minY: Math.min(...m2.map((e34) => e34.y)), maxY: Math.max(...m2.map((e34) => e34.y)) };
for (const t3 of n2) {
if (!t3.via && u2.has(t3.net) || !p2.some((e34) => e34 >= t3.minZ && e34 <= t3.maxZ))
continue;
const n3 = t3.radius + Math.max(o2, i2, e33.srj.defaultObstacleMargin ?? 0, e33.srj.minTraceToPadEdgeClearance ?? 0, e33.srj.minTraceToHoleEdgeClearance ?? 0, e33.srj.minViaEdgeToPadEdgeClearance ?? 0) + Math.SQRT2 * H_;
if ($_(t3.initialBounds, g2, n3))
continue;
if (Math.min(...m2.map((e34, n4) => kt(t3.a, t3.b, e34, m2[(n4 + 1) % 4]))) > n3)
continue;
const a3 = t3.radius + (t3.via ? Js(e33.srj, i2, u2.has(t3.net)) : c2.isNonPlatedHole && e33.srj.minTraceToHoleEdgeClearance !== undefined ? e33.srj.minTraceToHoleEdgeClearance : Math.max(o2, e33.srj.defaultObstacleMargin ?? 0, e33.srj.minTraceToPadEdgeClearance ?? 0));
if (r2.push({ segment: t3, corners: m2, required: a3, revisions: [-1, -1], contact: null }), t3.via) {
const e34 = { center: c2.center, cosine: h2, sine: d2, shape: y_(c2), clearance: a3 }, n4 = t3.a.original.x - c2.center.x, o3 = t3.a.original.y - c2.center.y, i3 = { x: n4 * h2 + o3 * d2, y: -n4 * d2 + o3 * h2 };
e34.clearance = Math.min(e34.clearance, b_(i3, i3, e34.shape));
for (const n5 of new Set([t3.a, t3.b])) {
const t4 = s2.get(n5);
t4 ? t4.push(e34) : s2.set(n5, [e34]);
}
}
}
}
this.stats = { ...this.stats, preparedObstacleCount: this.obstacleIndex, padContactCount: this.padContacts.length, lastPreparedObstacleBatchCount: a2 }, this.obstacleIndex === e33.srj.obstacles.length && (this.MAX_ITERATIONS = this.iterations + V_ * Math.max(1, Math.ceil((this.pairs.length + this.padContacts.length) / 4096)) + 2, this.phase = "sweeps");
}
project(e33, t2, n2, o2, i2) {
const r2 = this.viaPadConstraints, s2 = new Map;
for (const [t3, n3] of e33)
t3.locked || s2.set(t3, (s2.get(t3) ?? 0) + n3);
const a2 = [...s2.values()].reduce((e34, t3) => e34 + t3 * t3, 0);
if (a2 < 0.000000000000001)
return;
const c2 = Math.min(0.05, 0.7 * o2) / a2;
for (const [e34, o3] of s2) {
let s3 = Math.max(e34.bounds.minX, e34.original.x - H_, Math.min(e34.bounds.maxX, e34.original.x + H_, e34.x + t2 * c2 * o3)), a3 = Math.max(e34.bounds.minY, e34.original.y - H_, Math.min(e34.bounds.maxY, e34.original.y + H_, e34.y + n2 * c2 * o3));
const l2 = r2.get(e34);
if (l2?.some((e35) => this.getViaPadDistance({ x: s3, y: a3 }, e35) < e35.clearance)) {
if (!i2)
continue;
const t3 = this.constrainViaDisplacement(e34, { x: s3, y: a3 }, l2);
s3 = t3.x, a3 = t3.y;
}
l2?.some((e35) => this.getViaPadDistance({ x: s3, y: a3 }, e35) < e35.clearance) || (e34.x === s3 && e34.y === a3 || e34.revision++, e34.x = s3, e34.y = a3);
}
}
getViaPadDistance(e33, t2) {
const n2 = e33.x - t2.center.x, o2 = e33.y - t2.center.y, i2 = { x: n2 * t2.cosine + o2 * t2.sine, y: -n2 * t2.sine + o2 * t2.cosine };
return b_(i2, i2, t2.shape);
}
constrainViaDisplacement(e33, t2, n2) {
const o2 = t2.x - e33.x, i2 = t2.y - e33.y, r2 = [];
for (const o3 of n2) {
if (this.getViaPadDistance(t2, o3) >= o3.clearance)
continue;
const n3 = e33.x - o3.center.x, i3 = e33.y - o3.center.y, s3 = { x: n3 * o3.cosine + i3 * o3.sine, y: -n3 * o3.sine + i3 * o3.cosine };
let a3;
if (o3.shape.type === "rect") {
const e34 = o3.shape.bounds;
a3 = { x: Math.max(e34.minX, Math.min(e34.maxX, s3.x)), y: Math.max(e34.minY, Math.min(e34.maxY, s3.y)) };
} else {
const { a: e34, b: t3 } = o3.shape, n4 = t3.x - e34.x, i4 = t3.y - e34.y, r3 = n4 * n4 + i4 * i4, c3 = r3 > 0 ? Math.max(0, Math.min(1, ((s3.x - e34.x) * n4 + (s3.y - e34.y) * i4) / r3)) : 0;
a3 = { x: e34.x + c3 * n4, y: e34.y + c3 * i4 };
}
const c2 = s3.x - a3.x, l2 = s3.y - a3.y, h2 = { x: c2 * o3.cosine - l2 * o3.sine, y: c2 * o3.sine + l2 * o3.cosine };
h2.x * h2.x + h2.y * h2.y > 0.00000000000000000001 && r2.push(h2);
}
let s2 = { x: 0, y: 0 }, a2 = o2 * o2 + i2 * i2;
for (const t3 of r2) {
const n3 = o2 * t3.x + i2 * t3.y, c2 = t3.x * t3.x + t3.y * t3.y, l2 = this.shortenDisplacement(e33, { x: o2 - t3.x * n3 / c2, y: i2 - t3.y * n3 / c2 });
if (r2.some((e34) => l2.x * e34.x + l2.y * e34.y < -1e-15))
continue;
const h2 = (l2.x - o2) ** 2 + (l2.y - i2) ** 2;
h2 < a2 && (s2 = l2, a2 = h2);
}
return this.compensateTangentRounding(e33, s2, n2, r2);
}
shortenDisplacement(e33, t2) {
const n2 = Math.max(e33.bounds.minX, e33.original.x - H_), o2 = Math.min(e33.bounds.maxX, e33.original.x + H_), i2 = Math.max(e33.bounds.minY, e33.original.y - H_), r2 = Math.min(e33.bounds.maxY, e33.original.y + H_);
let s2 = 1;
return t2.x > 0 && (s2 = Math.min(s2, (o2 - e33.x) / t2.x)), t2.x < 0 && (s2 = Math.min(s2, (n2 - e33.x) / t2.x)), t2.y > 0 && (s2 = Math.min(s2, (r2 - e33.y) / t2.y)), t2.y < 0 && (s2 = Math.min(s2, (i2 - e33.y) / t2.y)), { x: Math.max(n2, Math.min(o2, e33.x + t2.x * s2)) - e33.x, y: Math.max(i2, Math.min(r2, e33.y + t2.y * s2)) - e33.y };
}
compensateTangentRounding(e33, t2, n2, o2) {
const i2 = { x: e33.x + t2.x, y: e33.y + t2.y }, r2 = n2.reduce((e34, t3) => Math.max(e34, Math.abs(t3.center.x), Math.abs(t3.center.y), t3.clearance), Math.max(1, Math.abs(e33.x), Math.abs(e33.y), Math.abs(i2.x), Math.abs(i2.y))), s2 = 32 * Number.EPSILON * r2, a2 = n2.map((e34) => this.getViaPadDistance(i2, e34));
if (a2.every((e34, t3) => e34 >= n2[t3].clearance) || a2.some((e34, t3) => e34 < n2[t3].clearance - s2))
return i2;
const c2 = o2.map((e34) => {
const t3 = Math.hypot(e34.x, e34.y);
return { x: e34.x / t3, y: e34.y / t3 };
}), l2 = { x: 0, y: 0 };
for (const e34 of c2)
for (const t3 of [e34, { x: -e34.y, y: e34.x }, { x: e34.y, y: -e34.x }])
c2.some((e35) => t3.x * e35.x + t3.y * e35.y < -1e-15) || (l2.x += t3.x, l2.y += t3.y);
const h2 = Math.hypot(l2.x, l2.y);
if (h2 < 0.000000000000001)
return i2;
const d2 = this.shortenDisplacement(e33, { x: t2.x + l2.x * s2 / h2, y: t2.y + l2.y * s2 / h2 }), u2 = { x: e33.x + d2.x, y: e33.y + d2.y };
return n2.every((e34) => this.getViaPadDistance(u2, e34) >= e34.clearance) ? u2 : i2;
}
projectPair(e33) {
const { a: t2, b: n2, revisions: o2 } = e33;
t2.a.revision === o2[0] && t2.b.revision === o2[1] && n2.a.revision === o2[2] && n2.b.revision === o2[3] || (e33.contact = G_(t2.a, t2.b, n2.a, n2.b), o2[0] = t2.a.revision, o2[1] = t2.b.revision, o2[2] = n2.a.revision, o2[3] = n2.b.revision);
const i2 = e33.contact, r2 = t2.radius + n2.radius + (t2.via && n2.via ? this.viaClearance : this.traceClearance);
i2.distance >= r2 || i2.distance < 0.0000000001 || this.project([[t2.a, 1 - i2.s], [t2.b, i2.s], [n2.a, i2.t - 1], [n2.b, -i2.t]], i2.x / i2.distance, i2.y / i2.distance, r2 - i2.distance, t2.via && n2.via);
}
projectPad(e33) {
const { segment: t2, corners: n2, required: o2 } = e33, i2 = t2.a === t2.b ? 1 : 2;
for (let e34 = 0;e34 < i2; e34++) {
const i3 = e34 === 0 ? t2.a : t2.b, r3 = U_(i3, n2);
r3 && this.project([[i3, 1]], r3.x, r3.y, o2 + r3.depth, false);
}
if (t2.a.revision !== e33.revisions[0] || t2.b.revision !== e33.revisions[1]) {
let o3 = G_(t2.a, t2.b, n2[0], n2[1]);
for (let e34 = 1;e34 < n2.length; e34++) {
const i3 = G_(t2.a, t2.b, n2[e34], n2[(e34 + 1) % n2.length]);
o3 = o3.distance < i3.distance ? o3 : i3;
}
e33.contact = o3, e33.revisions[0] = t2.a.revision, e33.revisions[1] = t2.b.revision;
}
const r2 = e33.contact;
r2.distance < 0.0000000001 || r2.distance >= o2 || this.project([[t2.a, 1 - r2.s], [t2.b, r2.s]], r2.x / r2.distance, r2.y / r2.distance, o2 - r2.distance, false);
}
stepSweep() {
let e33 = 0;
for (;e33 < 4096 && this.sweepPairIndex < this.pairs.length; )
this.projectPair(this.pairs[this.sweepPairIndex++]), e33++;
for (;e33 < 4096 && this.sweepPairIndex === this.pairs.length && this.sweepPadIndex < this.padContacts.length; )
this.projectPad(this.padContacts[this.sweepPadIndex++]), e33++;
this.projectedConstraintCount += e33, this.sweepPairIndex === this.pairs.length && this.sweepPadIndex === this.padContacts.length && (this.sweepIndex++, this.sweepPairIndex = 0, this.sweepPadIndex = 0, this.sweepIndex === V_ && (this.phase = "finalize")), this.progress = this.sweepIndex / 257, this.stats = { ...this.stats, sweepCount: this.sweepIndex, projectedConstraintCount: this.projectedConstraintCount, lastProjectedConstraintBatchCount: e33 };
}
finalizeRoutes() {
const { vertices: e33, routes: t2 } = this;
for (const t3 of e33.values())
for (const e34 of t3.points)
e34.x = t3.x, e34.y = t3.y;
for (const e34 of t2) {
e34.vias = [];
for (let t3 = 1;t3 < e34.route.length; t3++) {
const n2 = e34.route[t3 - 1], o2 = e34.route[t3];
n2.z === o2.z || n2.toNextSegmentType === "through_obstacle" || e34.vias.some((e35) => e35.x === o2.x && e35.y === o2.y) || e34.vias.push({ x: o2.x, y: o2.y });
}
}
this.solved = true, this.progress = 1;
}
_step() {
switch (this.phase) {
case "geometry":
return this.prepareGeometry();
case "pairs":
return this.preparePairs();
case "obstacles":
return this.prepareObstacles();
case "sweeps":
return this.stepSweep();
case "finalize":
return this.finalizeRoutes();
}
}
getOutput() {
if (!this.solved || this.failed)
throw new Error("Trace clearance projection is not complete");
return this.routes;
}
getResult() {
return this.getOutput();
}
};
var q_ = {};
a(q_, { all_layers: () => Yb, any_circuit_element: () => pC, any_soup_element: () => mC, any_source_component: () => Ob, asset: () => wy, base_circuit_json_error: () => Xy, battery_capacity: () => yy, brep_shape: () => Xx, cadModelDefaultDirectionMap: () => RS, cad_component: () => ES, cad_model_axis_directions: () => TS, cad_model_formats: () => NS, capacitance: () => sy, circuit_json_footprint_load_error: () => JI, current: () => uy, distance: () => dy, duration_ms: () => py, experiment_type: () => XS, external_footprint_load_error: () => qI, frequency: () => hy, getRotationBetweenPcbPin1Locations: () => Zx, getZodPrefixedIdWithDefault: () => Cy, inductance: () => ay, insertionDirectionToCanonical: () => Wx, insertionDirectionToVector: () => Vx, insertion_direction: () => Hx, kicadAt: () => Ny, kicadEffects: () => Ry, kicadFont: () => Ty, kicadFootprintAttributes: () => Oy, kicadFootprintMetadata: () => Ly, kicadFootprintModel: () => Dy, kicadFootprintPad: () => ky, kicadFootprintProperties: () => Ay, kicadProperty: () => Ey, kicadSymbolEffects: () => Fy, kicadSymbolMetadata: () => Yy, kicadSymbolPinNames: () => By, kicadSymbolPinNumbers: () => zy, kicadSymbolProperties: () => $y, kicadSymbolProperty: () => jy, layer_ref: () => Wb, layer_string: () => Xb, length: () => ly, manufacturing_drc_properties: () => Kx, ms: () => gy, ninePointAnchor: () => Py, parseAndConvertSiUnit: () => oy, pcbRenderLayer: () => My, pcb_autorouting_error: () => KI, pcb_bend: () => aI, pcb_board: () => rI, pcb_breakout_point: () => aS, pcb_bus_length_skew_error: () => qv, pcb_component: () => ev, pcb_component_invalid_layer_error: () => yS, pcb_component_missing_courtyard_warning: () => iS, pcb_component_not_on_board_edge_error: () => _S, pcb_component_outside_board_error: () => fS, pcb_connector_not_in_accessible_orientation_warning: () => oS, pcb_copper_pour: () => gS, pcb_copper_pour_brep: () => pS, pcb_copper_pour_polygon: () => mS, pcb_copper_pour_rect: () => uS, pcb_copper_text: () => II, pcb_courtyard_circle: () => MS, pcb_courtyard_outline: () => CS, pcb_courtyard_overlap_error: () => FI, pcb_courtyard_pill: () => wS, pcb_courtyard_polygon: () => PS, pcb_courtyard_rect: () => SS, pcb_cutout: () => UI, pcb_cutout_circle: () => VI, pcb_cutout_path: () => GI, pcb_cutout_polygon: () => HI, pcb_cutout_rect: () => WI, pcb_debug_line: () => ov, pcb_debug_object: () => rv, pcb_debug_object_base: () => tv, pcb_debug_point: () => iv, pcb_debug_rect: () => nv, pcb_fabrication_note_dimension: () => AI, pcb_fabrication_note_path: () => RI, pcb_fabrication_note_rect: () => EI, pcb_fabrication_note_text: () => TI, pcb_fabricator_extra_charge_warning: () => sS, pcb_footprint_overlap_error: () => BI, pcb_ground_plane: () => cS, pcb_ground_plane_region: () => lS, pcb_group: () => QI, pcb_hole: () => yv, pcb_hole_circle_or_square_shape: () => dv, pcb_hole_circle_shape: () => av, pcb_hole_oval_shape: () => pv, pcb_hole_pill_shape: () => gv, pcb_hole_rect_shape: () => lv, pcb_hole_rotated_pill_shape: () => _v, pcb_keepout: () => $I, pcb_keepout_outline: () => jI, pcb_keepout_overlap_warning: () => YI, pcb_manual_edit_conflict_warning: () => tS, pcb_missing_footprint_error: () => ZI, pcb_net: () => oI, pcb_note_dimension: () => zI, pcb_note_line: () => LI, pcb_note_path: () => DI, pcb_note_rect: () => kI, pcb_note_text: () => OI, pcb_packing_error: () => fI, pcb_pad_pad_clearance_error: () => vS, pcb_pad_trace_clearance_error: () => IS, pcb_panel: () => mI, pcb_panelization_placement_error: () => _I, pcb_pin1_location: () => Gx, pcb_placement_error: () => gI, pcb_plated_hole: () => Pv, pcb_port: () => Mv, pcb_port_not_connected_error: () => nI, pcb_port_not_matched_error: () => tI, pcb_preflight_routing_error: () => eS, pcb_route_hint: () => qx, pcb_route_hints: () => Jx, pcb_silkscreen_circle: () => CI, pcb_silkscreen_graphic: () => wI, pcb_silkscreen_graphic_brep: () => MI, pcb_silkscreen_line: () => bI, pcb_silkscreen_oval: () => PI, pcb_silkscreen_path: () => xI, pcb_silkscreen_pill: () => NI, pcb_silkscreen_rect: () => SI, pcb_silkscreen_text: () => vI, pcb_smtpad: () => Ov, pcb_smtpad_pill: () => Rv, pcb_solder_paste: () => jv, pcb_stiffener: () => pI, pcb_stiffener_polygon: () => uI, pcb_stiffener_rect: () => dI, pcb_text: () => $v, pcb_thermal_spoke: () => hS, pcb_trace: () => Gv, pcb_trace_error: () => Kv, pcb_trace_hint: () => yI, pcb_trace_missing_error: () => eI, pcb_trace_route_point: () => Hv, pcb_trace_route_point_through_pad: () => Vv, pcb_trace_route_point_via: () => Wv, pcb_trace_route_point_wire: () => Xv, pcb_trace_too_long_error: () => Zv, pcb_trace_too_long_warning: () => Jv, pcb_trace_too_many_vias_warning: () => Qv, pcb_trace_warning: () => Uv, pcb_via: () => iI, pcb_via_clearance_error: () => bS, pcb_via_trace_clearance_error: () => xS, point: () => by, point3: () => vy, point_with_bulge: () => $x, port_arrangement: () => ax, position: () => xy, position3: () => Iy, resistance: () => ry, ring: () => Yx, rotation: () => _y, route_hint_point: () => Qx, schematic_arc: () => mx, schematic_box: () => nx, schematic_circle: () => px, schematic_component: () => cx, schematic_component_overlap_warning: () => Rx, schematic_component_port_arrangement_by_sides: () => sx, schematic_component_port_arrangement_by_size: () => rx, schematic_component_styling_warning: () => Ex, schematic_debug_line: () => Px, schematic_debug_object: () => wx, schematic_debug_object_base: () => Sx, schematic_debug_point: () => Mx, schematic_debug_rect: () => Cx, schematic_element_outside_sheet_warning: () => Ax, schematic_error: () => vx, schematic_graphic: () => kx, schematic_group: () => Dx, schematic_layout_error: () => Ix, schematic_line: () => dx, schematic_manual_edit_conflict_warning: () => Tx, schematic_missing_sheet_warning: () => jx, schematic_net_label: () => xx, schematic_path: () => ox, schematic_pin_styles: () => ix, schematic_port: () => bx, schematic_rect: () => ux, schematic_sheet: () => Fx, schematic_sheet_size: () => Bx, schematic_symbol: () => hx, schematic_table: () => Lx, schematic_table_cell: () => zx, schematic_text: () => yx, schematic_text_part: () => _x, schematic_trace: () => gx, schematic_voltage_probe: () => Nx, simulation_ac_current_source: () => FS, simulation_ac_sweep_current_graph: () => cC, simulation_ac_sweep_voltage_graph: () => aC, simulation_ac_voltage_source: () => DS, simulation_complex_sample: () => sC, simulation_current_probe: () => JS, simulation_current_source: () => jS, simulation_dc_current_source: () => BS, simulation_dc_operating_point_current: () => oC, simulation_dc_operating_point_voltage: () => nC, simulation_dc_sweep_current_graph: () => rC, simulation_dc_sweep_unit: () => $S, simulation_dc_sweep_voltage_graph: () => iC, simulation_dc_voltage_source: () => kS, simulation_experiment: () => VS, simulation_op_amp: () => lC, simulation_oscilloscope_trace: () => uC, simulation_parameter_sweep: () => tC, simulation_parameter_sweep_coordinate: () => HS, simulation_parameter_type: () => KS, simulation_parameter_unit: () => YS, simulation_spice_subcircuit: () => hC, simulation_switch: () => ZS, simulation_transient_current_graph: () => US, simulation_transient_voltage_graph: () => GS, simulation_unknown_experiment_error: () => QS, simulation_voltage_probe: () => qS, simulation_voltage_source: () => LS, size: () => Sy, source_ambiguous_port_reference: () => jb, source_board: () => Fb, source_bus: () => tx, source_component_base: () => Vy, source_component_internal_connection: () => Db, source_component_misconfigured_error: () => Eb, source_component_pins_underspecified_warning: () => qb, source_confusing_net_name_warning: () => ex, source_failed_to_create_component_error: () => vb, source_group: () => zb, source_i2c_misconfigured_error: () => Rb, source_interconnect: () => Tb, source_invalid_component_property_error: () => Ib, source_manually_placed_via: () => Hb, source_missing_manufacturer_part_number_warning: () => Mb, source_missing_property_error: () => xb, source_net: () => Bb, source_no_ground_pin_defined_warning: () => Zb, source_no_power_pin_defined_warning: () => Ub, source_part_not_found_warning: () => Kb, source_pcb_ground_plane: () => $b, source_pin_attributes: () => ob, source_pin_missing_trace_warning: () => Pb, source_pin_must_be_connected_error: () => Jb, source_port: () => kb, source_project_metadata: () => bb, source_property_ignored_warning: () => Cb, source_refdes_convention_warning: () => wb, source_simple_ammeter: () => nb, source_simple_battery: () => ib, source_simple_capacitor: () => Hy, source_simple_chip: () => Qy, source_simple_connector: () => db, source_simple_connector_standards: () => hb, source_simple_crystal: () => cb, source_simple_current_source: () => eb, source_simple_diode: () => Uy, source_simple_fiducial: () => Zy, source_simple_fuse: () => tb, source_simple_ground: () => Jy, source_simple_inductor: () => rb, source_simple_led: () => qy, source_simple_mosfet: () => fb, source_simple_op_amp: () => _b, source_simple_pin_header: () => lb, source_simple_pinout: () => ub, source_simple_potentiometer: () => ab, source_simple_power_source: () => Ky, source_simple_push_button: () => sb, source_simple_resistor: () => Gy, source_simple_resonator: () => pb, source_simple_switch: () => yb, source_simple_test_point: () => gb, source_simple_transistor: () => mb, source_simple_voltage_probe: () => Nb, source_simple_voltage_source: () => Ab, source_trace: () => Lb, source_trace_not_connected_error: () => Sb, source_unnamed_trace_warning: () => Gb, spice_simulation_options: () => WS, supplier_footprint_mismatch_warning: () => rS, supplier_name: () => Wy, time: () => my, timestamp: () => fy, unknown_error_finding_part: () => Qb, visible_layer: () => Vb, voltage: () => cy, wave_shape: () => AS });
var J_ = (e33) => {
const t2 = Math.round(1000 * e33) / 1000;
return `${Number(t2.toFixed(3))}mm`;
};
var Q_ = new Map([["T", 1000000000000], ["G", 1e9], ["M", 1e6], ["K", 1000], ["k", 1000], ["", 1], ["m", 0.001], ["µ", 0.000001], ["μ", 0.000001], ["u", 0.000001], ["n", 0.000000001], ["p", 0.000000000001], ["f", 0.000000000000001]]);
var K_ = [...Q_.keys()];
function ey(e33) {
return Q_.get(e33);
}
var ty = { Hz: { baseUnit: "Hz", variants: { MHz: 1e6, kHz: 1000, Hz: 1 } }, g: { baseUnit: "g", variants: { kg: 1000, g: 1 } }, "Ω": { baseUnit: "Ω", variants: { "mΩ": 0.001, mohm: 0.001, mOhm: 0.001, milliohm: 0.001, "Ω": 1, ohm: 1, Ohm: 1, "kΩ": 1000, "KΩ": 1000, kohm: 1000, kOhm: 1000, KOhm: 1000, Kohm: 1000, "MΩ": 1e6, Mohm: 1e6, MOhm: 1e6, megohm: 1e6, Megohm: 1e6, "GΩ": 1e9, Gohm: 1e9, GOhm: 1e9, "TΩ": 1000000000000, Tohm: 1000000000000, TOhm: 1000000000000 } }, V: { baseUnit: "V", variants: { mV: 0.001, V: 1, kV: 1000, KV: 1000, MV: 1e6, GV: 1e9, TV: 1000000000000 } }, A: { baseUnit: "A", variants: { "µA": 0.000001, "μA": 0.000001, mA: 0.001, ma: 0.001, A: 1, kA: 1000, MA: 1e6 } }, F: { baseUnit: "F", variants: { pF: 0.000000000001, nF: 0.000000001, "µF": 0.000001, "μF": 0.000001, uF: 0.000001, mF: 0.001, F: 1, kF: 1000, KF: 1000, MF: 1e6 } }, H: { baseUnit: "H", variants: { pH: 0.000000000001, nH: 0.000000001, "µH": 0.000001, "μH": 0.000001, uH: 0.000001, mH: 0.001, H: 1, kH: 1000, KH: 1000, MH: 1e6 } }, ml: { baseUnit: "ml", variants: { ml: 1, mL: 1, l: 1000, L: 1000 } }, deg: { baseUnit: "deg", variants: { rad: 180 / Math.PI } }, ms: { baseUnit: "ms", variants: { fs: 0.000000000001, ps: 0.000000001, ns: 0.000001, us: 0.001, "µs": 0.001, "μs": 0.001, ms: 1, s: 1000 } }, mm: { baseUnit: "mm", variants: { nm: 0.000001, "µm": 0.001, "μm": 0.001, um: 0.001, mm: 1, cm: 10, dm: 100, m: 1000, km: 1e6, in: 25.4, ft: 304.8, IN: 25.4, FT: 304.8, yd: 914.4, mi: 1609344, mil: 0.0254 } } };
var ny = new Set;
for (const [e33, t2] of Object.entries(ty)) {
ny.add(e33);
for (const e34 of Object.keys(t2.variants))
ny.add(e34);
}
function oy(e33, t2) {
if (e33 == null)
return { parsedUnit: null, unitOfValue: null, value: null };
if (typeof e33 == "string" && e33.match(/^-?[\d.]+$/))
return { value: Number.parseFloat(e33), parsedUnit: null, unitOfValue: null };
if (typeof e33 == "number")
return { value: e33, parsedUnit: null, unitOfValue: null };
if (typeof e33 == "object" && "x" in e33 && "y" in e33) {
const n3 = oy(e33.x, t2), o3 = oy(e33.x, t2), i3 = oy(e33.y, t2);
return o3.value === null || i3.value === null ? { parsedUnit: null, unitOfValue: null, value: null } : { parsedUnit: n3.parsedUnit, unitOfValue: n3.unitOfValue, value: { x: o3.value, y: i3.value } };
}
const n2 = e33.toString().split("").reverse().join(""), o2 = n2.match(/[^\d\s]+/)?.[0];
if (!o2)
throw new Error(`Could not determine unit: "${e33}"`);
const i2 = o2.split("").reverse().join(""), r2 = e33.slice(0, -i2.length), s2 = ey(i2);
if (t2 && s2 != null)
return { parsedUnit: null, unitOfValue: t2, value: Number.parseFloat(r2) * s2 };
if (s2 != null && !ny.has(i2))
return { parsedUnit: null, unitOfValue: null, value: Number.parseFloat(r2) * s2 };
const { baseUnit: a2, conversionFactor: c2 } = function(e34) {
for (const t3 of Object.values(ty)) {
if (e34 in t3.variants)
return { baseUnit: t3.baseUnit, conversionFactor: t3.variants[e34] };
for (const [n3, o3] of Object.entries(t3.variants)) {
if (!e34.endsWith(n3))
continue;
const i3 = ey(e34.slice(0, -n3.length));
if (i3 != null)
return { baseUnit: t3.baseUnit, conversionFactor: i3 * o3 };
}
}
return { baseUnit: e34, conversionFactor: 1 };
}(i2);
return { parsedUnit: i2, unitOfValue: a2, value: c2 * Number.parseFloat(r2) };
}
K_.filter((e33) => e33 !== "").sort((e33, t2) => t2.length - e33.length).map((e33) => e33.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
var ry = (ha.string().or(ha.number()).transform((e33) => oy(e33, "Ω").value));
var sy = ha.string().or(ha.number()).transform((e33) => oy(e33, "F").value).transform((e33) => Number.parseFloat(e33.toPrecision(12)));
var ay = ha.string().or(ha.number()).transform((e33) => oy(e33, "H").value);
var cy = ha.string().or(ha.number()).transform((e33) => oy(e33, "V").value);
var ly = ha.string().or(ha.number()).transform((e33) => oy(e33).value);
var hy = ha.string().or(ha.number()).transform((e33) => oy(e33, "Hz").value);
var dy = ly;
var uy = ha.string().or(ha.number()).transform((e33) => oy(e33, "A").value);
var py = ha.string().or(ha.number()).transform((e33) => oy(e33).value);
var my = py;
var gy = py;
var fy = ha.string().datetime();
var _y = ha.string().or(ha.number()).transform((e33) => typeof e33 == "number" ? e33 : e33.endsWith("deg") ? Number.parseFloat(e33.split("deg")[0]) : e33.endsWith("rad") ? 180 * Number.parseFloat(e33.split("rad")[0]) / Math.PI : Number.parseFloat(e33));
var yy = ha.number().or(ha.string().endsWith("mAh")).transform((e33) => {
if (typeof e33 == "string") {
const t2 = e33.replace("mAh", ""), n2 = Number.parseFloat(t2);
if (Number.isNaN(n2))
throw new Error("Invalid capacity");
return n2;
}
return e33;
}).describe("Battery capacity in mAh");
var by = ha.object({ x: dy, y: dy });
var xy = by;
var vy = ha.object({ x: dy, y: dy, z: dy });
var Iy = vy;
var Sy = ha.object({ width: ha.number(), height: ha.number() });
var Cy = (e33) => ha.string().optional().default(() => `${e33}_${((e34) => {
const t2 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return Array.from({ length: e34 }, () => t2[Math.floor(62 * Math.random())]).join("");
})(10)}`);
var Py = ha.enum(["top_left", "top_center", "top_right", "center_left", "center", "center_right", "bottom_left", "bottom_center", "bottom_right"]);
var My = ha.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"]);
var wy = ha.object({ project_relative_path: ha.string(), url: ha.string(), mimetype: ha.string() });
var Ny = by.extend({ rotation: _y.optional() });
var Ty = ha.object({ size: by.optional(), thickness: dy.optional() });
var Ry = ha.object({ font: Ty.optional() });
var Ey = ha.object({ value: ha.string(), at: Ny.optional(), layer: ha.string().optional(), uuid: ha.string().optional(), hide: ha.boolean().optional(), effects: Ry.optional() });
var Ay = ha.object({ Reference: Ey.optional(), Value: Ey.optional(), Datasheet: Ey.optional(), Description: Ey.optional() });
var Oy = ha.object({ through_hole: ha.boolean().optional(), smd: ha.boolean().optional(), exclude_from_pos_files: ha.boolean().optional(), exclude_from_bom: ha.boolean().optional() });
var ky = ha.object({ name: ha.string(), type: ha.string(), shape: ha.string().optional(), at: Ny.optional(), size: by.optional(), drill: dy.optional(), layers: ha.array(ha.string()).optional(), removeUnusedLayers: ha.boolean().optional(), uuid: ha.string().optional() });
var Dy = ha.object({ path: ha.string(), offset: vy.optional(), scale: vy.optional(), rotate: vy.optional() });
var Ly = ha.object({ footprintName: ha.string().optional(), version: ha.union([ha.number(), ha.string()]).optional(), generator: ha.string().optional(), generatorVersion: ha.union([ha.number(), ha.string()]).optional(), layer: ha.string().optional(), properties: Ay.optional(), attributes: Oy.optional(), pads: ha.array(ky).optional(), embeddedFonts: ha.boolean().optional(), model: Dy.optional() });
var zy = ha.object({ hide: ha.boolean().optional() });
var By = ha.object({ offset: dy.optional(), hide: ha.boolean().optional() });
var Fy = ha.object({ font: Ty.optional(), justify: ha.union([ha.string(), ha.array(ha.string())]).optional(), hide: ha.boolean().optional() });
var jy = ha.object({ value: ha.string(), id: ha.union([ha.number(), ha.string()]).optional(), at: Ny.optional(), effects: Fy.optional() });
var $y = ha.object({ Reference: jy.optional(), Value: jy.optional(), Footprint: jy.optional(), Datasheet: jy.optional(), Description: jy.optional(), ki_keywords: jy.optional(), ki_fp_filters: jy.optional() });
var Yy = ha.object({ symbolName: ha.string().optional(), extends: ha.string().optional(), pinNumbers: zy.optional(), pinNames: By.optional(), excludeFromSim: ha.boolean().optional(), inBom: ha.boolean().optional(), onBoard: ha.boolean().optional(), properties: $y.optional(), embeddedFonts: ha.boolean().optional() });
var Xy = ha.object({ error_type: ha.string(), message: ha.string(), is_fatal: ha.boolean().optional() });
var Wy = ha.enum(["jlcpcb", "macrofab", "pcbway", "digikey", "mouser", "lcsc"]);
var Vy = ha.object({ type: ha.literal("source_component"), ftype: ha.string().optional(), source_component_id: ha.string(), name: ha.string(), manufacturer_part_number: ha.string().optional(), supplier_part_numbers: ha.record(Wy, ha.array(ha.string())).optional(), display_value: ha.string().optional(), display_name: ha.string().optional(), are_pins_interchangeable: ha.boolean().optional(), internally_connected_source_port_ids: ha.array(ha.array(ha.string())).optional(), source_group_id: ha.string().optional(), subcircuit_id: ha.string().optional() });
var Hy = Vy.extend({ ftype: ha.literal("simple_capacitor"), capacitance: sy, max_voltage_rating: cy.optional(), display_capacitance: ha.string().optional(), max_decoupling_trace_length: dy.optional() });
var Gy = Vy.extend({ ftype: ha.literal("simple_resistor"), resistance: ry, display_resistance: ha.string().optional() });
var Uy = Vy.extend({ ftype: ha.literal("simple_diode") });
var Zy = Vy.extend({ ftype: ha.literal("simple_fiducial") });
var qy = Uy.extend({ ftype: ha.literal("simple_led"), color: ha.string().optional(), wavelength: ha.string().optional() });
var Jy = Vy.extend({ ftype: ha.literal("simple_ground") });
var Qy = Vy.extend({ ftype: ha.literal("simple_chip") });
var Ky = Vy.extend({ ftype: ha.literal("simple_power_source"), voltage: cy });
var eb = Vy.extend({ ftype: ha.literal("simple_current_source"), current: uy, frequency: hy.optional(), peak_to_peak_current: uy.optional(), wave_shape: ha.enum(["sine", "square", "triangle", "sawtooth", "dc"]).optional().default("dc"), phase: ha.number().optional(), duty_cycle: ha.number().min(0).max(1).optional() });
var tb = Vy.extend({ ftype: ha.literal("simple_fuse"), current_rating_amps: ha.number().describe("Nominal current in amps the fuse is rated for"), voltage_rating_volts: ha.number().describe("Voltage rating in volts, e.g. ±5V would be 5") });
var nb = Vy.extend({ ftype: ha.literal("simple_ammeter") });
var ob = ha.object({ must_be_connected: ha.boolean().optional(), provides_power: ha.boolean().optional(), requires_power: ha.boolean().optional(), provides_ground: ha.boolean().optional(), requires_ground: ha.boolean().optional(), provides_voltage: ha.union([ha.string(), ha.number()]).optional(), requires_voltage: ha.union([ha.string(), ha.number()]).optional(), do_not_connect: ha.boolean().optional(), include_in_board_pinout: ha.boolean().optional(), can_use_internal_pullup: ha.boolean().optional(), is_using_internal_pullup: ha.boolean().optional(), needs_external_pullup: ha.boolean().optional(), can_use_internal_pulldown: ha.boolean().optional(), is_using_internal_pulldown: ha.boolean().optional(), needs_external_pulldown: ha.boolean().optional(), can_use_open_drain: ha.boolean().optional(), is_using_open_drain: ha.boolean().optional(), can_use_push_pull: ha.boolean().optional(), is_using_push_pull: ha.boolean().optional(), should_have_decoupling_capacitor: ha.boolean().optional(), recommended_decoupling_capacitor_capacitance: ha.union([ha.string(), ha.number()]).optional(), is_configured_for_i2c_sda: ha.boolean().optional(), is_configured_for_i2c_scl: ha.boolean().optional(), is_configured_for_spi_mosi: ha.boolean().optional(), is_configured_for_spi_miso: ha.boolean().optional(), is_configured_for_spi_sck: ha.boolean().optional(), is_configured_for_spi_cs: ha.boolean().optional(), is_configured_for_uart_tx: ha.boolean().optional(), is_configured_for_uart_rx: ha.boolean().optional(), supports_i2c_sda: ha.boolean().optional(), supports_i2c_scl: ha.boolean().optional(), supports_spi_mosi: ha.boolean().optional(), supports_spi_miso: ha.boolean().optional(), supports_spi_sck: ha.boolean().optional(), supports_spi_cs: ha.boolean().optional(), supports_uart_tx: ha.boolean().optional(), supports_uart_rx: ha.boolean().optional() });
var ib = Vy.extend({ ftype: ha.literal("simple_battery"), capacity: yy });
var rb = Vy.extend({ ftype: ha.literal("simple_inductor"), inductance: ay, display_inductance: ha.string().optional(), max_current_rating: ha.number().optional() });
var sb = Vy.extend({ ftype: ha.literal("simple_push_button") });
var ab = Vy.extend({ ftype: ha.literal("simple_potentiometer"), max_resistance: ry, display_max_resistance: ha.string().optional() });
var cb = Vy.extend({ ftype: ha.literal("simple_crystal"), frequency: ha.number().describe("Frequency in Hz"), load_capacitance: ha.number().optional().describe("Load capacitance in pF"), pin_variant: ha.enum(["two_pin", "four_pin"]).optional() });
var lb = Vy.extend({ ftype: ha.literal("simple_pin_header"), pin_count: ha.number(), gender: ha.enum(["male", "female"]).optional().default("male") });
var hb = ["usb_c", "m2", "jst_sh", "jst_gh", "jst_zh", "jst_ph", "jst_xh", "jst_vh"];
var db = Vy.extend({ ftype: ha.literal("simple_connector"), standard: ha.enum(hb).optional(), pin_count: ha.number().int().positive().optional() });
var ub = Vy.extend({ ftype: ha.literal("simple_pinout") });
var pb = Vy.extend({ ftype: ha.literal("simple_resonator"), load_capacitance: sy, equivalent_series_resistance: ry.optional(), frequency: hy });
var mb = Vy.extend({ ftype: ha.literal("simple_transistor"), transistor_type: ha.enum(["npn", "pnp"]) });
var gb = Vy.extend({ ftype: ha.literal("simple_test_point"), footprint_variant: ha.enum(["pad", "through_hole"]).optional(), pad_shape: ha.enum(["rect", "circle"]).optional(), pad_diameter: ha.union([ha.number(), ha.string()]).optional(), hole_diameter: ha.union([ha.number(), ha.string()]).optional(), width: ha.union([ha.number(), ha.string()]).optional(), height: ha.union([ha.number(), ha.string()]).optional() });
var fb = Vy.extend({ ftype: ha.literal("simple_mosfet"), channel_type: ha.enum(["n", "p"]), mosfet_mode: ha.enum(["enhancement", "depletion"]) });
var _b = Vy.extend({ ftype: ha.literal("simple_op_amp") });
var yb = Vy.extend({ ftype: ha.literal("simple_switch") });
var bb = ha.object({ type: ha.literal("source_project_metadata"), name: ha.string().optional(), software_used_string: ha.string().optional(), project_url: ha.string().optional(), source_filesystem_md5_hash: ha.string().optional(), created_at: fy.optional() });
var xb = Xy.extend({ type: ha.literal("source_missing_property_error"), source_missing_property_error_id: Cy("source_missing_property_error"), source_component_id: ha.string(), property_name: ha.string(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_missing_property_error").default("source_missing_property_error") }).describe("The source code is missing a property");
var vb = Xy.extend({ type: ha.literal("source_failed_to_create_component_error"), source_failed_to_create_component_error_id: Cy("source_failed_to_create_component_error"), error_type: ha.literal("source_failed_to_create_component_error").default("source_failed_to_create_component_error"), component_name: ha.string().optional(), subcircuit_id: ha.string().optional(), parent_source_component_id: ha.string().optional(), pcb_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), schematic_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional() }).describe("Error emitted when a component fails to be constructed");
var Ib = Xy.extend({ type: ha.literal("source_invalid_component_property_error"), source_invalid_component_property_error_id: Cy("source_invalid_component_property_error"), source_component_id: ha.string(), property_name: ha.string(), property_value: ha.unknown().optional(), expected_format: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_invalid_component_property_error").default("source_invalid_component_property_error") }).describe("The source component property is invalid");
var Sb = Xy.extend({ type: ha.literal("source_trace_not_connected_error"), source_trace_not_connected_error_id: Cy("source_trace_not_connected_error"), error_type: ha.literal("source_trace_not_connected_error").default("source_trace_not_connected_error"), subcircuit_id: ha.string().optional(), source_group_id: ha.string().optional(), source_trace_id: ha.string().optional(), connected_source_port_ids: ha.array(ha.string()).optional(), selectors_not_found: ha.array(ha.string()).optional() }).describe("Occurs when a source trace selector does not match any ports");
var Cb = ha.object({ type: ha.literal("source_property_ignored_warning"), source_property_ignored_warning_id: Cy("source_property_ignored_warning"), source_component_id: ha.string(), property_name: ha.string(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_property_ignored_warning").default("source_property_ignored_warning"), message: ha.string() }).describe("The source property was ignored");
var Pb = ha.object({ type: ha.literal("source_pin_missing_trace_warning"), source_pin_missing_trace_warning_id: Cy("source_pin_missing_trace_warning"), warning_type: ha.literal("source_pin_missing_trace_warning").default("source_pin_missing_trace_warning"), message: ha.string(), source_component_id: ha.string(), source_port_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a source component pin is missing a trace connection");
var Mb = ha.object({ type: ha.literal("source_missing_manufacturer_part_number_warning"), source_missing_manufacturer_part_number_warning_id: Cy("source_missing_manufacturer_part_number_warning"), warning_type: ha.literal("source_missing_manufacturer_part_number_warning").default("source_missing_manufacturer_part_number_warning"), message: ha.string(), source_component_id: ha.string(), standard: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a standard connector is missing manufacturer part number");
var wb = ha.object({ type: ha.literal("source_refdes_convention_warning"), source_refdes_convention_warning_id: Cy("source_refdes_convention_warning"), warning_type: ha.literal("source_refdes_convention_warning").default("source_refdes_convention_warning"), message: ha.string(), source_component_id: ha.string(), refdes: ha.string(), source_component_ftype: ha.string(), expected_prefixes: ha.array(ha.string()), actual_prefix: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a source component reference designator does not match the component type convention");
var Nb = Vy.extend({ ftype: ha.literal("simple_voltage_probe") });
var Tb = Vy.extend({ ftype: ha.literal("interconnect") });
var Rb = Xy.extend({ type: ha.literal("source_i2c_misconfigured_error"), source_i2c_misconfigured_error_id: Cy("source_i2c_misconfigured_error"), error_type: ha.literal("source_i2c_misconfigured_error").default("source_i2c_misconfigured_error"), source_port_ids: ha.array(ha.string()) }).describe("Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net");
var Eb = Xy.extend({ type: ha.literal("source_component_misconfigured_error"), source_component_misconfigured_error_id: Cy("source_component_misconfigured_error"), error_type: ha.literal("source_component_misconfigured_error").default("source_component_misconfigured_error"), source_component_ids: ha.array(ha.string()), source_port_ids: ha.array(ha.string()).optional() }).describe("Error emitted when one or more source components have an invalid or conflicting configuration");
var Ab = Vy.extend({ ftype: ha.literal("simple_voltage_source"), voltage: cy, frequency: hy.optional(), peak_to_peak_voltage: cy.optional(), wave_shape: ha.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(), phase: _y.optional(), duty_cycle: ha.number().optional().describe("Duty cycle as a fraction (0 to 1)"), pulse_delay: gy.optional(), rise_time: gy.optional(), fall_time: gy.optional(), pulse_width: gy.optional(), period: gy.optional() });
var Ob = ha.union([Gy, Hy, Uy, Zy, qy, Jy, Qy, Ky, eb, nb, ib, rb, sb, ab, cb, lb, db, ub, pb, yb, mb, gb, fb, _b, tb, Nb, Tb, Ab, bb, xb, Ib, vb, Sb, Cb, Pb, Mb, wb, Rb, Eb]);
var kb = ha.object({ type: ha.literal("source_port"), pin_number: ha.number().optional(), port_hints: ha.array(ha.string()).optional(), name: ha.string(), source_port_id: ha.string(), source_component_id: ha.string().optional(), source_group_id: ha.string().optional(), most_frequently_referenced_by_name: ha.string().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() }).merge(ob);
var Db = ha.object({ type: ha.literal("source_component_internal_connection"), source_component_internal_connection_id: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() });
var Lb = ha.object({ type: ha.literal("source_trace"), source_trace_id: ha.string(), connected_source_port_ids: ha.array(ha.string()), connected_source_net_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), max_length: ha.number().optional(), max_via_count: ha.number().int().nonnegative().optional(), name: ha.string().optional(), min_trace_thickness: ha.number().optional(), display_name: ha.string().optional() });
var zb = ha.object({ type: ha.literal("source_group"), source_group_id: ha.string(), subcircuit_id: ha.string().optional(), parent_subcircuit_id: ha.string().optional(), parent_source_group_id: ha.string().optional(), is_subcircuit: ha.boolean().optional(), show_as_schematic_box: ha.boolean().optional(), name: ha.string().optional(), was_automatically_named: ha.boolean().optional() });
var Bb = ha.object({ type: ha.literal("source_net"), source_net_id: ha.string(), name: ha.string(), member_source_group_ids: ha.array(ha.string()), is_power: ha.boolean().optional(), is_ground: ha.boolean().optional(), is_digital_signal: ha.boolean().optional(), is_analog_signal: ha.boolean().optional(), is_positive_voltage_source: ha.boolean().optional(), trace_width: ha.number().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() });
var Fb = ha.object({ type: ha.literal("source_board"), source_board_id: ha.string(), source_group_id: ha.string(), title: ha.string().optional() }).describe("Defines a board in the source domain");
var jb = Xy.extend({ type: ha.literal("source_ambiguous_port_reference"), source_ambiguous_port_reference_id: Cy("source_ambiguous_port_reference"), error_type: ha.literal("source_ambiguous_port_reference").default("source_ambiguous_port_reference"), source_port_id: ha.string().optional(), source_component_id: ha.string().optional() }).describe("Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous");
var $b = ha.object({ type: ha.literal("source_pcb_ground_plane"), source_pcb_ground_plane_id: ha.string(), source_group_id: ha.string(), source_net_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Defines a ground plane in the source domain");
var Yb = ["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"];
var Xb = ha.enum(Yb);
var Wb = Xb.or(ha.object({ name: Xb })).transform((e33) => typeof e33 == "string" ? e33 : e33.name);
var Vb = ha.enum(["top", "bottom"]);
var Hb = ha.object({ type: ha.literal("source_manually_placed_via"), source_manually_placed_via_id: ha.string(), source_group_id: ha.string(), source_net_id: ha.string().min(1).optional(), subcircuit_id: ha.string().optional(), source_trace_id: ha.string().optional() }).describe("Defines a via that is manually placed in the source domain");
var Gb = ha.object({ type: ha.literal("source_unnamed_trace_warning"), source_unnamed_trace_warning_id: Cy("source_unnamed_trace_warning"), warning_type: ha.literal("source_unnamed_trace_warning").default("source_unnamed_trace_warning"), message: ha.string(), source_trace_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a source trace is missing a name");
var Ub = ha.object({ type: ha.literal("source_no_power_pin_defined_warning"), source_no_power_pin_defined_warning_id: Cy("source_no_power_pin_defined_warning"), warning_type: ha.literal("source_no_power_pin_defined_warning").default("source_no_power_pin_defined_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a chip has no source ports with requires_power=true");
var Zb = ha.object({ type: ha.literal("source_no_ground_pin_defined_warning"), source_no_ground_pin_defined_warning_id: Cy("source_no_ground_pin_defined_warning"), warning_type: ha.literal("source_no_ground_pin_defined_warning").default("source_no_ground_pin_defined_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a chip has no source ports marked as ground pins");
var qb = ha.object({ type: ha.literal("source_component_pins_underspecified_warning"), source_component_pins_underspecified_warning_id: Cy("source_component_pins_underspecified_warning"), warning_type: ha.literal("source_component_pins_underspecified_warning").default("source_component_pins_underspecified_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when all ports on a source component are underspecified");
var Jb = Xy.extend({ type: ha.literal("source_pin_must_be_connected_error"), source_pin_must_be_connected_error_id: Cy("source_pin_must_be_connected_error"), error_type: ha.literal("source_pin_must_be_connected_error").default("source_pin_must_be_connected_error"), source_component_id: ha.string(), source_port_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a pin with mustBeConnected attribute is not connected to any trace");
var Qb = Xy.extend({ type: ha.literal("unknown_error_finding_part"), unknown_error_finding_part_id: Cy("unknown_error_finding_part"), error_type: ha.literal("unknown_error_finding_part").default("unknown_error_finding_part"), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when an unexpected error occurs while finding a part");
var Kb = ha.object({ type: ha.literal("source_part_not_found_warning"), source_part_not_found_warning_id: Cy("source_part_not_found_warning"), warning_type: ha.literal("source_part_not_found_warning").default("source_part_not_found_warning"), message: ha.string(), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional(), supplier_name: Wy.optional(), manufacturer_part_number: ha.string().optional(), supplier_part_number: ha.string().optional(), part_name: ha.string().optional() }).describe("Warning emitted when a requested part can not be found");
var ex = ha.object({ type: ha.literal("source_confusing_net_name_warning"), source_confusing_net_name_warning_id: Cy("source_confusing_net_name_warning"), warning_type: ha.literal("source_confusing_net_name_warning").default("source_confusing_net_name_warning"), message: ha.string(), source_net_ids: ha.array(ha.string()).min(2), net_name: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when electrically disconnected source nets share a name");
var tx = ha.object({ type: ha.literal("source_bus"), source_bus_id: ha.string(), name: ha.string().optional(), source_trace_ids: ha.array(ha.string()).min(1), max_length_skew: ha.number().nonnegative().finite().optional(), subcircuit_id: ha.string().optional() });
var nx = ha.object({ type: ha.literal("schematic_box"), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), width: dy, height: dy, is_dashed: ha.boolean().default(false), x: dy, y: dy, subcircuit_id: ha.string().optional() }).describe("Draws a box on the schematic");
var ox = ha.object({ type: ha.literal("schematic_path"), schematic_path_id: Cy("schematic_path"), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), fill_color: ha.string().optional(), is_filled: ha.boolean().optional(), is_dashed: ha.boolean().default(false), stroke_width: dy.nullable().optional(), stroke_color: ha.string().optional(), dash_length: dy.optional(), dash_gap: dy.optional(), points: ha.array(by), subcircuit_id: ha.string().optional() });
var ix = ha.record(ha.object({ left_margin: ly.optional(), right_margin: ly.optional(), top_margin: ly.optional(), bottom_margin: ly.optional() }));
var rx = ha.object({ left_size: ha.number(), right_size: ha.number(), top_size: ha.number().optional(), bottom_size: ha.number().optional() });
var sx = ha.object({ left_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["top-to-bottom", "bottom-to-top"]).optional() }).optional(), right_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["top-to-bottom", "bottom-to-top"]).optional() }).optional(), top_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["left-to-right", "right-to-left"]).optional() }).optional(), bottom_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["left-to-right", "right-to-left"]).optional() }).optional() });
var ax = ha.union([rx, sx]);
var cx = ha.object({ type: ha.literal("schematic_component"), size: Sy, center: by, source_component_id: ha.string().optional(), schematic_component_id: ha.string(), schematic_sheet_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), pin_spacing: ly.optional(), pin_styles: ix.optional(), box_width: ly.optional(), symbol_name: ha.string().optional(), port_arrangement: ax.optional(), port_labels: ha.record(ha.string()).optional(), symbol_display_value: ha.string().optional(), subcircuit_id: ha.string().optional(), schematic_group_id: ha.string().optional(), is_schematic_group: ha.boolean().optional(), source_group_id: ha.string().optional(), is_box_with_pins: ha.boolean().optional().default(true) });
var lx = ha.object({ kicad_symbol: Yy.optional() }).catchall(ha.unknown());
var hx = ha.object({ type: ha.literal("schematic_symbol"), schematic_symbol_id: ha.string(), name: ha.string().optional(), metadata: lx.optional() }).describe("Defines a named schematic symbol that can be referenced by components.");
var dx = ha.object({ type: ha.literal("schematic_line"), schematic_line_id: Cy("schematic_line"), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), x1: dy, y1: dy, x2: dy, y2: dy, stroke_width: dy.nullable().optional(), color: ha.string().default("#000000"), is_dashed: ha.boolean().default(false), dash_length: dy.optional(), dash_gap: dy.optional(), subcircuit_id: ha.string().optional() }).describe("Draws a styled line on the schematic");
var ux = ha.object({ type: ha.literal("schematic_rect"), schematic_rect_id: Cy("schematic_rect"), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: by, width: dy, height: dy, rotation: _y.default(0), stroke_width: dy.nullable().optional(), color: ha.string().default("#000000"), is_filled: ha.boolean().default(false), fill_color: ha.string().optional(), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled rectangle on the schematic");
var px = ha.object({ type: ha.literal("schematic_circle"), schematic_circle_id: Cy("schematic_circle"), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: by, radius: dy, stroke_width: dy.nullable().optional(), color: ha.string().default("#000000"), is_filled: ha.boolean().default(false), fill_color: ha.string().optional(), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled circle on the schematic");
var mx = ha.object({ type: ha.literal("schematic_arc"), schematic_arc_id: Cy("schematic_arc"), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: by, radius: dy, start_angle_degrees: _y, end_angle_degrees: _y, direction: ha.enum(["clockwise", "counterclockwise"]).default("counterclockwise"), stroke_width: dy.nullable().optional(), color: ha.string().default("#000000"), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled arc on the schematic");
var gx = ha.object({ type: ha.literal("schematic_trace"), schematic_trace_id: ha.string(), schematic_sheet_id: ha.string().optional(), source_trace_id: ha.string().optional(), junctions: ha.array(ha.object({ x: ha.number(), y: ha.number() })), edges: ha.array(ha.object({ from: ha.object({ x: ha.number(), y: ha.number() }), to: ha.object({ x: ha.number(), y: ha.number() }), is_crossing: ha.boolean().optional(), from_schematic_port_id: ha.string().optional(), to_schematic_port_id: ha.string().optional() })), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() });
var fx = ha.enum(["center", "left", "right", "top", "bottom"]);
var _x = ha.object({ text: ha.string(), is_overlined: ha.boolean().optional() });
var yx = ha.object({ type: ha.literal("schematic_text"), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), schematic_text_id: ha.string(), source_trace_id: ha.string().optional(), text: ha.string(), text_parts: ha.array(_x).min(1).optional(), display_superscript: ha.string().optional(), font_size: ha.number().default(0.18), position: ha.object({ x: dy, y: dy }), rotation: ha.number().default(0), anchor: ha.union([fx.describe("legacy"), Py]).default("center"), color: ha.string().default("#000000"), subcircuit_id: ha.string().optional() });
var bx = ha.object({ type: ha.literal("schematic_port"), schematic_port_id: ha.string(), source_port_id: ha.string(), schematic_sheet_id: ha.string().optional(), schematic_component_id: ha.string().optional(), center: by, facing_direction: ha.enum(["up", "down", "left", "right"]).optional(), distance_from_component_edge: ha.number().optional(), side_of_component: ha.enum(["top", "bottom", "left", "right"]).optional(), true_ccw_index: ha.number().optional(), pin_number: ha.number().optional(), display_pin_label: ha.string().optional(), display_pin_label_text_parts: ha.array(_x).min(1).optional(), display_pin_label_font_size: ha.number().positive().finite().optional(), subcircuit_id: ha.string().optional(), is_connected: ha.boolean().optional(), is_internal_circuit_port: ha.boolean().optional(), is_overlapping_internal_circuit_port: ha.boolean().optional(), has_input_arrow: ha.boolean().optional(), has_output_arrow: ha.boolean().optional(), is_drawn_with_inversion_circle: ha.boolean().optional() }).describe("Defines a port on a schematic component");
var xx = ha.object({ type: ha.literal("schematic_net_label"), schematic_net_label_id: Cy("schematic_net_label"), schematic_sheet_id: ha.string().optional(), schematic_trace_id: ha.string().optional(), source_trace_id: ha.string().optional(), source_net_id: ha.string(), center: by, anchor_position: by.optional(), anchor_side: ha.enum(["top", "bottom", "left", "right"]), text: ha.string(), display_superscript: ha.string().optional(), symbol_name: ha.string().optional(), is_movable: ha.boolean().optional(), subcircuit_id: ha.string().optional() });
var vx = Xy.extend({ type: ha.literal("schematic_error"), schematic_error_id: ha.string(), error_type: ha.literal("schematic_port_not_found").default("schematic_port_not_found"), subcircuit_id: ha.string().optional() }).describe("Defines a schematic error on the schematic");
var Ix = Xy.extend({ type: ha.literal("schematic_layout_error"), schematic_layout_error_id: Cy("schematic_layout_error"), error_type: ha.literal("schematic_layout_error").default("schematic_layout_error"), source_group_id: ha.string(), schematic_group_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Error emitted when schematic layout fails for a group");
var Sx = ha.object({ type: ha.literal("schematic_debug_object"), label: ha.string().optional(), subcircuit_id: ha.string().optional() });
var Cx = Sx.extend({ shape: ha.literal("rect"), center: by, size: Sy });
var Px = Sx.extend({ shape: ha.literal("line"), start: by, end: by });
var Mx = Sx.extend({ shape: ha.literal("point"), center: by });
var wx = ha.discriminatedUnion("shape", [Cx, Px, Mx]);
var Nx = ha.object({ type: ha.literal("schematic_voltage_probe"), schematic_voltage_probe_id: ha.string(), schematic_sheet_id: ha.string().optional(), source_component_id: ha.string().optional(), name: ha.string().optional(), position: by, schematic_trace_id: ha.string(), voltage: cy.optional(), subcircuit_id: ha.string().optional(), color: ha.string().optional(), label_alignment: Py.optional() }).describe("Defines a voltage probe measurement point on a schematic trace");
var Tx = ha.object({ type: ha.literal("schematic_manual_edit_conflict_warning"), schematic_manual_edit_conflict_warning_id: Cy("schematic_manual_edit_conflict_warning"), warning_type: ha.literal("schematic_manual_edit_conflict_warning").default("schematic_manual_edit_conflict_warning"), message: ha.string(), schematic_component_id: ha.string(), schematic_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_component_id: ha.string() }).describe("Warning emitted when a component has both manual placement and explicit schX/schY coordinates");
var Rx = ha.object({ type: ha.literal("schematic_component_overlap_warning"), schematic_component_overlap_warning_id: Cy("schematic_component_overlap_warning"), warning_type: ha.literal("schematic_component_overlap_warning").default("schematic_component_overlap_warning"), message: ha.string(), schematic_component_ids: ha.tuple([ha.string(), ha.string()]), schematic_sheet_id: ha.string().optional() }).describe("Warning emitted when the rendered bounds of two schematic components overlap");
var Ex = ha.object({ type: ha.literal("schematic_component_styling_warning"), schematic_component_styling_warning_id: Cy("schematic_component_styling_warning"), warning_type: ha.literal("schematic_component_styling_warning").default("schematic_component_styling_warning"), message: ha.string(), schematic_component_id: ha.string(), styling_issue_type: ha.string(), schematic_port_ids: ha.array(ha.string()).optional(), source_component_id: ha.string().optional(), schematic_sheet_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a schematic component has a visual styling issue");
var Ax = ha.object({ type: ha.literal("schematic_element_outside_sheet_warning"), schematic_element_outside_sheet_warning_id: Cy("schematic_element_outside_sheet_warning"), warning_type: ha.literal("schematic_element_outside_sheet_warning").default("schematic_element_outside_sheet_warning"), message: ha.string(), schematic_sheet_id: ha.string(), schematic_element_type: ha.enum(["schematic_component", "schematic_net_label", "schematic_trace"]), schematic_element_id: ha.string() }).describe("Warning emitted when a schematic component, net label, or trace extends outside its schematic sheet");
var Ox = dy.pipe(ha.number().positive().finite());
var kx = ha.object({ type: ha.literal("schematic_graphic"), schematic_graphic_id: Cy("schematic_graphic"), schematic_sheet_id: ha.string().optional(), asset: wy.optional(), svg_content: ha.string().optional(), width: Ox.optional(), height: Ox.optional() }).describe("References a graphic asset or inline SVG content with optional centered layout bounds on a schematic sheet").superRefine(({ asset: e33, svg_content: t2 }, n2) => {
e33 === undefined && t2 === undefined && n2.addIssue({ code: ha.ZodIssueCode.custom, message: "At least one of asset or svg_content is required" });
});
var Dx = ha.object({ type: ha.literal("schematic_group"), schematic_group_id: Cy("schematic_group"), schematic_sheet_id: ha.string().optional(), source_group_id: ha.string(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), width: ly, height: ly, center: by, schematic_component_ids: ha.array(ha.string()), show_as_schematic_box: ha.boolean().optional(), name: ha.string().optional(), description: ha.string().optional() }).describe("Defines a group of components on the schematic");
var Lx = ha.object({ type: ha.literal("schematic_table"), schematic_table_id: Cy("schematic_table"), schematic_sheet_id: ha.string().optional(), anchor_position: by, column_widths: ha.array(dy), row_heights: ha.array(dy), cell_padding: dy.optional(), border_width: dy.optional(), subcircuit_id: ha.string().optional(), schematic_component_id: ha.string().optional(), anchor: Py.optional() }).describe("Defines a table on the schematic");
var zx = ha.object({ type: ha.literal("schematic_table_cell"), schematic_table_cell_id: Cy("schematic_table_cell"), schematic_sheet_id: ha.string().optional(), schematic_table_id: ha.string(), start_row_index: ha.number(), end_row_index: ha.number(), start_column_index: ha.number(), end_column_index: ha.number(), text: ha.string().optional(), center: by, width: dy, height: dy, horizontal_align: ha.enum(["left", "center", "right"]).optional(), vertical_align: ha.enum(["top", "middle", "bottom"]).optional(), font_size: dy.optional(), subcircuit_id: ha.string().optional() }).describe("Defines a cell within a schematic_table");
var Bx = ha.enum(["a4", "ansi_b"]);
var Fx = ha.object({ type: ha.literal("schematic_sheet"), schematic_sheet_id: Cy("schematic_sheet"), name: ha.string().optional(), sheet_index: ha.number().optional(), sheet_size: Bx.optional(), sheet_width: ha.number().positive().optional(), sheet_height: ha.number().positive().optional(), subcircuit_id: ha.string().optional(), outline_color: ha.string().optional() }).describe("Defines a schematic sheet or page that components can be placed on");
var jx = ha.object({ type: ha.literal("schematic_missing_sheet_warning"), schematic_missing_sheet_warning_id: Cy("schematic_missing_sheet_warning"), warning_type: ha.literal("schematic_missing_sheet_warning").default("schematic_missing_sheet_warning"), message: ha.string() }).describe("Circuit-wide warning emitted when a schematic has no schematic sheet. Display as a banner without attaching it to a component or drawing a target outline or leader line.");
var $x = ha.object({ x: dy, y: dy, bulge: ha.number().optional() });
var Yx = ha.object({ vertices: ha.array($x) });
var Xx = ha.object({ outer_ring: Yx, inner_rings: ha.array(Yx).default([]) });
var Wx = { from_left: "from_left", from_right: "from_right", from_top: "from_top", from_bottom: "from_bottom", from_above: "from_above", from_below: "from_below", from_x_neg: "from_left", from_x_pos: "from_right", from_y_pos: "from_top", from_y_neg: "from_bottom", from_z_pos: "from_above", from_z_neg: "from_below", from_front: "from_top", from_back: "from_bottom" };
var Vx = { from_left: { x: -1, y: 0, z: 0 }, from_right: { x: 1, y: 0, z: 0 }, from_top: { x: 0, y: 1, z: 0 }, from_bottom: { x: 0, y: -1, z: 0 }, from_above: { x: 0, y: 0, z: 1 }, from_below: { x: 0, y: 0, z: -1 } };
var Hx = ha.enum(["from_left", "from_right", "from_top", "from_bottom", "from_above", "from_below", "from_x_neg", "from_x_pos", "from_y_pos", "from_y_neg", "from_z_pos", "from_z_neg", "from_front", "from_back"]).transform((e33) => Wx[e33]).describe('The side exposing the receptacle where the cable or mating part is attached, following the 2D PCB diagram convention, not a 3D viewport frame. In project coordinate space, "from_top" is +Y, "from_bottom" -Y, "from_left" -X, "from_right" +X, "from_above" +Z and "from_below" -Z. A receptacle on the +Y edge is "from_top" even though the plug moves in -Y as it seats. Cartesian spellings such as "from_y_pos" are accepted and normalized to the named values, as are the deprecated "from_front" (now "from_top") and "from_back" (now "from_bottom").');
var Gx = ha.enum(["leftside_top", "leftside_bottom", "rightside_top", "rightside_bottom", "topside_left", "topside_right", "bottomside_left", "bottomside_right"]);
var Ux = [["leftside_top", "bottomside_left", "rightside_bottom", "topside_right"], ["leftside_bottom", "bottomside_right", "rightside_top", "topside_left"]];
var Zx = (e33, t2) => {
for (const n2 of Ux) {
const o2 = n2.indexOf(e33), i2 = n2.indexOf(t2);
if (o2 !== -1 && i2 !== -1)
return (i2 - o2 + n2.length) % n2.length * 90;
}
return null;
};
var qx = ha.object({ x: dy, y: dy, via: ha.boolean().optional(), via_to_layer: Wb.optional() });
var Jx = ha.array(qx);
var Qx = ha.object({ x: dy, y: dy, via: ha.boolean().optional(), to_layer: Wb.optional(), trace_width: dy.optional() });
var Kx = ha.object({ min_trace_width: ly.optional(), min_board_edge_clearance: ly.optional(), min_via_hole_edge_to_via_hole_edge_clearance: ly.optional(), min_plated_hole_drill_edge_to_drill_edge_clearance: ly.optional(), min_trace_to_pad_edge_clearance: ly.optional(), min_trace_to_hole_edge_clearance: ly.optional().describe("Minimum distance from a trace copper edge to a non-plated hole edge, in mm. No default is applied when omitted."), min_pad_edge_to_pad_edge_clearance: ly.optional(), min_same_net_trace_edge_to_trace_edge_clearance: ly.optional(), min_different_net_trace_edge_to_trace_edge_clearance: ly.optional(), min_via_edge_to_pad_edge_clearance: ly.optional(), min_via_hole_diameter: ly.optional(), min_via_pad_diameter: ly.optional() });
var ev = ha.object({ type: ha.literal("pcb_component"), pcb_component_id: Cy("pcb_component"), source_component_id: ha.string(), center: by, layer: Wb, rotation: _y, display_offset_x: ha.string().optional().describe("How to display the x offset for this part, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this part, usually corresponding with how the user specified it"), width: ly, height: ly, do_not_place: ha.boolean().optional(), is_allowed_to_be_off_board: ha.boolean().optional(), subcircuit_id: ha.string().optional(), pcb_group_id: ha.string().optional(), position_mode: ha.enum(["packed", "relative_to_group_anchor", "relative_to_another_component", "none"]).optional(), anchor_position: by.optional(), anchor_alignment: Py.optional(), positioned_relative_to_pcb_group_id: ha.string().optional(), positioned_relative_to_pcb_board_id: ha.string().optional(), cable_insertion_center: by.optional(), insertion_direction: Hx.optional(), pin1_location: Gx.optional().describe("Location of pin 1 on the unrotated, top-view component footprint"), supplier_pin1_location_map: ha.record(Wy, Gx).optional().describe("Pin 1 location for each supplier's unrotated, top-view footprint"), metadata: ha.object({ kicad_footprint: Ly.optional() }).optional(), obstructs_within_bounds: ha.boolean().default(true).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");
var tv = ha.object({ type: ha.literal("pcb_debug_object"), pcb_debug_object_id: Cy("pcb_debug_object"), label: ha.string().optional(), subcircuit_id: ha.string().optional() });
var nv = tv.extend({ shape: ha.literal("rect"), center: by, size: Sy });
var ov = tv.extend({ shape: ha.literal("line"), start: by, end: by });
var iv = tv.extend({ shape: ha.literal("point"), center: by });
var rv = ha.discriminatedUnion("shape", [nv, ov, iv]);
var sv = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: Cy("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("circle"), hole_diameter: ha.number(), x: dy, y: dy, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var av = sv.describe("Defines a circular hole on the PCB");
var cv = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: Cy("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), x: dy, y: dy, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var lv = cv.describe("Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.");
var hv = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: Cy("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.enum(["circle", "square"]), hole_diameter: ha.number(), x: dy, y: dy, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var dv = hv.describe("Defines a circular or square hole on the PCB");
var uv = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: Cy("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("oval"), hole_width: ha.number(), hole_height: ha.number(), x: dy, y: dy, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var pv = uv.describe("Defines an oval hole on the PCB");
var mv = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: Cy("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("pill"), hole_width: ha.number(), hole_height: ha.number(), x: dy, y: dy, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var gv = mv.describe("Defines a pill-shaped hole on the PCB");
var fv = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: Cy("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("rotated_pill"), hole_width: ha.number(), hole_height: ha.number(), x: dy, y: dy, ccw_rotation: _y, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var _v = fv.describe("Defines a rotated pill-shaped hole on the PCB");
var yv = hv.or(uv).or(mv).or(fv).or(sv).or(cv);
var bv = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("circle"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), outer_diameter: ha.number(), hole_diameter: ha.number(), is_covered_with_solder_mask: ha.boolean().optional(), x: dy, y: dy, layers: ha.array(Wb), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: Cy("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var xv = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.enum(["oval", "pill"]), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), outer_width: ha.number(), outer_height: ha.number(), hole_width: ha.number(), hole_height: ha.number(), is_covered_with_solder_mask: ha.boolean().optional(), x: dy, y: dy, ccw_rotation: _y, layers: ha.array(Wb), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: Cy("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var vv = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("circular_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("circle"), pad_shape: ha.literal("rect"), hole_diameter: ha.number(), rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), hole_offset_x: dy.default(0), hole_offset_y: dy.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: dy, y: dy, layers: ha.array(Wb), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: Cy("pcb_plated_hole"), soldermask_margin: ha.number().optional(), rect_ccw_rotation: _y.optional() });
var Iv = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("pill_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("pill"), pad_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), hole_offset_x: dy.default(0), hole_offset_y: dy.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: dy, y: dy, layers: ha.array(Wb), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: Cy("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var Sv = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("rotated_pill_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("rotated_pill"), pad_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), hole_ccw_rotation: _y, rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), rect_ccw_rotation: _y, hole_offset_x: dy.default(0), hole_offset_y: dy.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: dy, y: dy, layers: ha.array(Wb), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: Cy("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var Cv = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("hole_with_polygon_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.enum(["circle", "oval", "pill", "rotated_pill"]), hole_diameter: ha.number().optional(), hole_width: ha.number().optional(), hole_height: ha.number().optional(), pad_outline: ha.array(ha.object({ x: dy, y: dy })).min(3), hole_offset_x: dy.default(0), hole_offset_y: dy.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: dy, y: dy, layers: ha.array(Wb), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: Cy("pcb_plated_hole"), soldermask_margin: ha.number().optional(), ccw_rotation: _y.optional() });
var Pv = ha.union([bv, xv, vv, Iv, Sv, Cv]);
var Mv = ha.object({ type: ha.literal("pcb_port"), pcb_port_id: Cy("pcb_port"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_port_id: ha.string(), pcb_component_id: ha.string().optional(), x: dy, y: dy, layers: ha.array(Wb), is_board_pinout: ha.boolean().optional() }).describe("Defines a port on the PCB");
var wv = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("circle"), pcb_smtpad_id: Cy("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, radius: ha.number(), layer: Wb, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), solderpaste_margin: ha.number().optional() });
var Nv = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rect"), pcb_smtpad_id: Cy("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), rect_border_radius: ha.number().optional(), corner_radius: ha.number().optional(), layer: Wb, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), soldermask_margin_left: ha.number().optional(), soldermask_margin_top: ha.number().optional(), soldermask_margin_right: ha.number().optional(), soldermask_margin_bottom: ha.number().optional(), solderpaste_margin: ha.number().optional() });
var Tv = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rotated_rect"), pcb_smtpad_id: Cy("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), rect_border_radius: ha.number().optional(), corner_radius: ha.number().optional(), ccw_rotation: _y, layer: Wb, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), soldermask_margin_left: ha.number().optional(), soldermask_margin_top: ha.number().optional(), soldermask_margin_right: ha.number().optional(), soldermask_margin_bottom: ha.number().optional(), solderpaste_margin: ha.number().optional() });
var Rv = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("pill"), pcb_smtpad_id: Cy("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), radius: ha.number(), layer: Wb, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), solderpaste_margin: ha.number().optional() });
var Ev = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rotated_pill"), pcb_smtpad_id: Cy("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), radius: ha.number(), ccw_rotation: _y, layer: Wb, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), solderpaste_margin: ha.number().optional() });
var Av = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("polygon"), pcb_smtpad_id: Cy("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), points: ha.array(by), layer: Wb, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), solderpaste_margin: ha.number().optional() });
var Ov = ha.discriminatedUnion("shape", [wv, Nv, Tv, Ev, Rv, Av]).describe("Defines an SMT pad on the PCB");
var kv = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("circle"), pcb_solder_paste_id: Cy("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, radius: ha.number(), layer: Wb, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Dv = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("rect"), pcb_solder_paste_id: Cy("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), layer: Wb, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Lv = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("pill"), pcb_solder_paste_id: Cy("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), radius: ha.number(), layer: Wb, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var zv = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("rotated_rect"), pcb_solder_paste_id: Cy("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), ccw_rotation: dy, layer: Wb, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Bv = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("rotated_pill"), pcb_solder_paste_id: Cy("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), radius: ha.number(), ccw_rotation: _y, layer: Wb, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var Fv = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("oval"), pcb_solder_paste_id: Cy("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: dy, y: dy, width: ha.number(), height: ha.number(), layer: Wb, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var jv = ha.union([kv, Dv, Lv, zv, Bv, Fv]).describe("Defines solderpaste on the PCB");
var $v = ha.object({ type: ha.literal("pcb_text"), pcb_text_id: Cy("pcb_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), text: ha.string(), center: by, layer: Wb, width: ly, height: ly, lines: ha.number(), align: ha.enum(["bottom-left"]) }).describe("Defines text on the PCB");
var Yv = dy.pipe(ha.number().finite().positive());
var Xv = ha.object({ route_type: ha.literal("wire"), x: dy, y: dy, width: dy, start_width: Yv.optional(), end_width: Yv.optional(), width_interpolation_mode: ha.enum(["linear", "quadratic"]).optional(), copper_pour_id: ha.string().optional(), is_inside_copper_pour: ha.boolean().optional(), start_pcb_port_id: ha.string().optional(), end_pcb_port_id: ha.string().optional(), layer: Wb }).superRefine((e33, t2) => {
const n2 = [e33.start_width, e33.end_width, e33.width_interpolation_mode].filter((e34) => e34 !== undefined).length;
n2 !== 0 && (n2 !== 3 && t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Wire taper requires start_width, end_width and width_interpolation_mode together" }), e33.width !== e33.start_width && t2.addIssue({ code: ha.ZodIssueCode.custom, path: ["start_width"], message: "start_width must equal width" }), Number.isFinite(e33.x) && Number.isFinite(e33.y) || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Tapered wire coordinates must be finite" }));
});
var Wv = ha.object({ route_type: ha.literal("via"), x: dy, y: dy, copper_pour_id: ha.string().optional(), is_inside_copper_pour: ha.boolean().optional(), hole_diameter: dy.optional(), outer_diameter: dy.optional(), tented_on_top: ha.boolean().optional(), tented_on_bottom: ha.boolean().optional(), from_layer: Wb, to_layer: Wb });
var Vv = ha.object({ route_type: ha.literal("through_pad"), start: by, end: by, width: dy, start_layer: Wb, end_layer: Wb, pcb_smtpad_id: ha.string().optional(), pcb_plated_hole_id: ha.string().optional() });
var Hv = ha.union([Xv, Wv, Vv]);
var Gv = ha.object({ type: ha.literal("pcb_trace"), source_trace_id: ha.string().optional(), pcb_component_id: ha.string().optional(), pcb_trace_id: Cy("pcb_trace"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), route_thickness_mode: ha.enum(["constant", "interpolated"]).default("constant").optional(), route_order_index: ha.number().optional(), should_round_corners: ha.boolean().optional(), trace_length: ha.number().optional(), is_antenna_trace: ha.boolean().optional(), highlight_color: ha.string().optional(), route: ha.array(Hv).superRefine((e33, t2) => {
for (const [n2, o2] of e33.entries()) {
if (o2.route_type !== "wire" || o2.width_interpolation_mode === undefined)
continue;
const i2 = e33[n2 + 1], r2 = i2?.route_type === "through_pad" ? i2.start : i2, s2 = i2?.route_type === "wire" ? i2.layer : i2?.route_type === "via" ? i2.from_layer : i2?.start_layer, a2 = r2 ? Math.hypot(r2.x - o2.x, r2.y - o2.y) : NaN;
(!Number.isFinite(a2) || a2 <= 0 || s2 !== o2.layer) && t2.addIssue({ code: ha.ZodIssueCode.custom, path: [n2], message: "Tapered wire must lead to a distinct finite next point on the same layer" });
}
}) }).describe("Defines a trace on the PCB");
var Uv = ha.object({ type: ha.literal("pcb_trace_warning"), pcb_trace_warning_id: Cy("pcb_trace_warning"), warning_type: ha.literal("pcb_trace_warning").default("pcb_trace_warning"), message: ha.string(), center: by.optional(), pcb_trace_id: ha.string(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace warning on the PCB");
var Zv = ha.object({ type: ha.literal("pcb_trace_too_long_error"), pcb_trace_too_long_error_id: Cy("pcb_trace_too_long_error"), error_type: ha.literal("pcb_trace_too_long_error").default("pcb_trace_too_long_error"), message: ha.string(), pcb_trace_id: ha.string(), source_net_id: ha.string().optional(), source_trace_id: ha.string().optional(), actual_trace_length: dy, maximum_trace_length: dy, subcircuit_id: ha.string().optional() }).describe("Error emitted when a PCB trace is longer than its maximum allowed length");
var qv = Xy.extend({ type: ha.literal("pcb_bus_length_skew_error"), pcb_bus_length_skew_error_id: Cy("pcb_bus_length_skew_error"), error_type: ha.literal("pcb_bus_length_skew_error").default("pcb_bus_length_skew_error"), source_bus_id: ha.string(), source_trace_ids: ha.array(ha.string()), pcb_trace_ids: ha.array(ha.string()), actual_length_skew: ha.number().nonnegative().finite(), maximum_length_skew: ha.number().nonnegative().finite(), subcircuit_id: ha.string().optional() });
var Jv = ha.object({ type: ha.literal("pcb_trace_too_long_warning"), pcb_trace_too_long_warning_id: Cy("pcb_trace_too_long_warning"), warning_type: ha.literal("pcb_trace_too_long_warning").default("pcb_trace_too_long_warning"), message: ha.string(), pcb_trace_id: ha.string(), source_net_id: ha.string().optional(), source_trace_id: ha.string().optional(), actual_trace_length: dy, maximum_trace_length: dy, subcircuit_id: ha.string().optional() }).describe("Warning emitted when a PCB trace is longer than its maximum allowed length");
var Qv = ha.object({ type: ha.literal("pcb_trace_too_many_vias_warning"), pcb_trace_too_many_vias_warning_id: Cy("pcb_trace_too_many_vias_warning"), warning_type: ha.literal("pcb_trace_too_many_vias_warning").default("pcb_trace_too_many_vias_warning"), message: ha.string(), pcb_trace_id: ha.string(), source_net_id: ha.string().optional(), source_trace_id: ha.string().optional(), actual_via_count: ha.number().int().nonnegative(), maximum_via_count: ha.number().int().nonnegative(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a PCB trace has more vias than its maximum allowed count");
var Kv = Xy.extend({ type: ha.literal("pcb_trace_error"), pcb_trace_error_id: Cy("pcb_trace_error"), error_type: ha.literal("pcb_trace_error").default("pcb_trace_error"), center: by.optional(), pcb_trace_id: ha.string(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace error on the PCB");
var eI = Xy.extend({ type: ha.literal("pcb_trace_missing_error"), pcb_trace_missing_error_id: Cy("pcb_trace_missing_error"), error_type: ha.literal("pcb_trace_missing_error").default("pcb_trace_missing_error"), center: by.optional(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines an error when a source trace has no corresponding PCB trace");
var tI = Xy.extend({ type: ha.literal("pcb_port_not_matched_error"), pcb_error_id: Cy("pcb_error"), error_type: ha.literal("pcb_port_not_matched_error").default("pcb_port_not_matched_error"), pcb_component_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace error on the PCB where a port is not matched");
var nI = Xy.extend({ type: ha.literal("pcb_port_not_connected_error"), pcb_port_not_connected_error_id: Cy("pcb_port_not_connected_error"), error_type: ha.literal("pcb_port_not_connected_error").default("pcb_port_not_connected_error"), pcb_port_ids: ha.array(ha.string()), pcb_component_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines an error when a pcb port is not connected to any trace");
var oI = ha.object({ type: ha.literal("pcb_net"), pcb_net_id: Cy("pcb_net"), source_net_id: ha.string().optional(), highlight_color: ha.string().optional() }).describe("Defines a net on the PCB");
var iI = ha.object({ type: ha.literal("pcb_via"), pcb_via_id: Cy("pcb_via"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), x: dy, y: dy, outer_diameter: dy.default("0.6mm"), hole_diameter: dy.default("0.25mm"), topmost_drill_layer: Wb.optional(), bottommost_drill_layer: Wb.optional(), through_hole: ha.boolean().optional(), from_layer: Wb.optional(), to_layer: Wb.optional(), layers: ha.array(Wb), pcb_port_ids: ha.array(ha.string()).optional(), pcb_trace_id: ha.string().optional(), source_trace_id: ha.string().optional(), source_net_id: ha.string().min(1).optional(), net_is_assignable: ha.boolean().optional(), net_assigned: ha.boolean().optional(), is_tented: ha.boolean().optional(), tented_on_top: ha.boolean().optional(), tented_on_bottom: ha.boolean().optional() }).transform(({ is_tented: e33, ...t2 }) => (e33 !== undefined && (t2.tented_on_top ??= e33, t2.tented_on_bottom ??= e33), t2)).describe("Defines a via on the PCB");
var rI = ha.object({ type: ha.literal("pcb_board"), pcb_board_id: Cy("pcb_board"), pcb_panel_id: ha.string().optional(), carrier_pcb_board_id: ha.string().optional(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), is_mounted_to_carrier_board: ha.boolean().optional(), is_via_in_pad_allowed: ha.boolean().optional(), default_via_tented_on_top: ha.boolean().optional(), default_via_tented_on_bottom: ha.boolean().optional(), default_via_plugged: ha.boolean().optional(), width: ly.optional(), height: ly.optional(), center: by, display_offset_x: ha.string().optional().describe("How to display the x offset for this board, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this board, usually corresponding with how the user specified it"), thickness: ly.optional().default(1.4), num_layers: ha.number().optional().default(4), allow_blind_and_buried_vias: ha.boolean().optional().describe("Whether autorouters may generate blind and buried vias. False restricts newly generated vias to the full board stack."), outline: ha.array(by).optional(), shape: ha.enum(["rect", "polygon"]).optional(), material: ha.enum(["fr4", "fr1", "flex"]).default("fr4"), solder_mask_color: ha.string().optional(), silkscreen_color: ha.string().optional(), anchor_position: by.optional(), anchor_alignment: Py.optional(), position_mode: ha.enum(["relative_to_panel_anchor", "none"]).optional() }).merge(Kx).describe("Defines the board outline of the PCB");
var sI = by.extend({ x: ly.pipe(ha.number().finite()), y: ly.pipe(ha.number().finite()) });
var aI = ha.object({ type: ha.literal("pcb_bend"), pcb_bend_id: Cy("pcb_bend"), pcb_board_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), start: sI, end: sI, bend_angle: _y.pipe(ha.number().finite()), bend_radius: ly.pipe(ha.number().finite().positive()), bend_side: ha.enum(["left", "right"]) }).refine(({ start: e33, end: t2 }) => e33.x !== t2.x || e33.y !== t2.y, { message: "Bend centerline endpoints must be distinct", path: ["end"] }).describe("Defines a finite-radius bend on a flat PCB for runtime CAD folding");
var cI = ly.pipe(ha.number().finite().positive());
var lI = by.extend({ x: ly.pipe(ha.number().finite()), y: ly.pipe(ha.number().finite()) });
var hI = ha.object({ type: ha.literal("pcb_stiffener"), pcb_stiffener_id: Cy("pcb_stiffener"), pcb_board_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), layer: ha.enum(["top", "bottom"]), material: ha.enum(["fr4", "polyimide", "stainless_steel", "aluminum"]), thickness: cI, adhesive_thickness: ly.pipe(ha.number().finite().nonnegative()).optional() });
var dI = hI.extend({ shape: ha.literal("rect"), center: lI, rotation: _y.pipe(ha.number().finite()).optional(), width: cI, height: cI, outline: ha.never().optional() });
var uI = hI.extend({ shape: ha.literal("polygon"), outline: ha.array(lI).min(3).refine((e33) => {
const t2 = e33.reduce((t3, n2, o2) => {
const i2 = e33[(o2 + 1) % e33.length];
return t3 + n2.x * i2.y - i2.x * n2.y;
}, 0);
return Number.isFinite(t2) && t2 !== 0;
}, "Stiffener outline must enclose a nonzero area"), center: ha.never().optional(), rotation: ha.never().optional(), width: ha.never().optional(), height: ha.never().optional() });
var pI = ha.discriminatedUnion("shape", [dI, uI]).describe("Defines bonded mechanical PCB reinforcement without adding copper layers");
var mI = ha.object({ type: ha.literal("pcb_panel"), pcb_panel_id: Cy("pcb_panel"), width: ly, height: ly, center: by, thickness: ly.optional().default(1.4), covered_with_solder_mask: ha.boolean().optional().default(true) }).describe("Defines a PCB panel that can contain multiple boards");
var gI = Xy.extend({ type: ha.literal("pcb_placement_error"), pcb_placement_error_id: Cy("pcb_placement_error"), error_type: ha.literal("pcb_placement_error").default("pcb_placement_error"), subcircuit_id: ha.string().optional() }).describe("Defines a placement error on the PCB");
var fI = Xy.extend({ type: ha.literal("pcb_packing_error"), pcb_packing_error_id: Cy("pcb_packing_error"), error_type: ha.literal("pcb_packing_error").default("pcb_packing_error"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a failure to pack PCB components within layout bounds");
var _I = Xy.extend({ type: ha.literal("pcb_panelization_placement_error"), pcb_panelization_placement_error_id: Cy("pcb_panelization_placement_error"), error_type: ha.literal("pcb_panelization_placement_error").default("pcb_panelization_placement_error"), pcb_panel_id: ha.string().optional(), pcb_board_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a panelization placement error on the PCB");
var yI = ha.object({ type: ha.literal("pcb_trace_hint"), pcb_trace_hint_id: Cy("pcb_trace_hint"), pcb_port_id: ha.string(), pcb_component_id: ha.string(), route: ha.array(Qx), subcircuit_id: ha.string().optional() }).describe("A hint that can be used during generation of a PCB trace");
var bI = ha.object({ type: ha.literal("pcb_silkscreen_line"), pcb_silkscreen_line_id: Cy("pcb_silkscreen_line"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), stroke_width: dy.default("0.1mm"), x1: dy, y1: dy, x2: dy, y2: dy, layer: Vb }).describe("Defines a silkscreen line on the PCB");
var xI = ha.object({ type: ha.literal("pcb_silkscreen_path"), pcb_silkscreen_path_id: Cy("pcb_silkscreen_path"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Vb, route: ha.array(by), stroke_width: ly }).describe("Defines a silkscreen path on the PCB");
var vI = ha.object({ type: ha.literal("pcb_silkscreen_text"), pcb_silkscreen_text_id: Cy("pcb_silkscreen_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: dy.default("0.2mm"), pcb_component_id: ha.string(), text: ha.string(), is_knockout: ha.boolean().default(false).optional(), knockout_padding: ha.object({ left: ly, top: ly, bottom: ly, right: ly }).default({ left: "0.2mm", top: "0.2mm", bottom: "0.2mm", right: "0.2mm" }).optional(), ccw_rotation: ha.number().optional(), layer: Wb, is_mirrored: ha.boolean().default(false).optional(), anchor_position: by.default({ x: 0, y: 0 }), anchor_alignment: Py.default("center") }).describe("Defines silkscreen text on the PCB");
var II = ha.object({ type: ha.literal("pcb_copper_text"), pcb_copper_text_id: Cy("pcb_copper_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: dy.default("0.2mm"), pcb_component_id: ha.string(), text: ha.string(), is_knockout: ha.boolean().default(false).optional(), knockout_padding: ha.object({ left: ly, top: ly, bottom: ly, right: ly }).default({ left: "0.2mm", top: "0.2mm", bottom: "0.2mm", right: "0.2mm" }).optional(), ccw_rotation: ha.number().optional(), layer: Wb, is_mirrored: ha.boolean().default(false).optional(), anchor_position: by.default({ x: 0, y: 0 }), anchor_alignment: Py.default("center") }).describe("Defines copper text on the PCB");
var SI = ha.object({ type: ha.literal("pcb_silkscreen_rect"), pcb_silkscreen_rect_id: Cy("pcb_silkscreen_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, width: ly, height: ly, layer: Wb, stroke_width: ly.default("1mm"), corner_radius: ly.optional(), is_filled: ha.boolean().default(true).optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), ccw_rotation: ha.number().optional() }).describe("Defines a silkscreen rect on the PCB");
var CI = ha.object({ type: ha.literal("pcb_silkscreen_circle"), pcb_silkscreen_circle_id: Cy("pcb_silkscreen_circle"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, radius: ly, layer: Vb, stroke_width: ly.default("1mm"), is_filled: ha.boolean().optional() }).describe("Defines a silkscreen circle on the PCB");
var PI = ha.object({ type: ha.literal("pcb_silkscreen_oval"), pcb_silkscreen_oval_id: Cy("pcb_silkscreen_oval"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, radius_x: dy, radius_y: dy, layer: Vb, ccw_rotation: _y.optional() }).describe("Defines a silkscreen oval on the PCB");
var MI = ha.object({ type: ha.literal("pcb_silkscreen_graphic"), pcb_silkscreen_graphic_id: Cy("pcb_silkscreen_graphic"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Vb, image_asset: wy.optional() }).extend({ shape: ha.literal("brep"), brep_shape: Xx }).describe("Defines a BRep silkscreen graphic on the PCB");
var wI = ha.discriminatedUnion("shape", [MI]).describe("Defines a silkscreen graphic on the PCB");
var NI = ha.object({ type: ha.literal("pcb_silkscreen_pill"), pcb_silkscreen_pill_id: Cy("pcb_silkscreen_pill"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, width: ly, height: ly, layer: Wb, ccw_rotation: ha.number().optional() }).describe("Defines a silkscreen pill on the PCB");
var TI = ha.object({ type: ha.literal("pcb_fabrication_note_text"), pcb_fabrication_note_text_id: Cy("pcb_fabrication_note_text"), subcircuit_id: ha.string().optional(), pcb_group_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: dy.default("1mm"), pcb_component_id: ha.string(), text: ha.string(), ccw_rotation: ha.number().optional(), layer: Vb, anchor_position: by.default({ x: 0, y: 0 }), anchor_alignment: ha.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center"), color: ha.string().optional() }).describe("Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators");
var RI = ha.object({ type: ha.literal("pcb_fabrication_note_path"), pcb_fabrication_note_path_id: Cy("pcb_fabrication_note_path"), pcb_component_id: ha.string(), subcircuit_id: ha.string().optional(), layer: Wb, route: ha.array(by), stroke_width: ly, color: ha.string().optional() }).describe("Defines a fabrication path on the PCB for fabricators or assemblers");
var EI = ha.object({ type: ha.literal("pcb_fabrication_note_rect"), pcb_fabrication_note_rect_id: Cy("pcb_fabrication_note_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, width: ly, height: ly, layer: Vb, stroke_width: ly.default("0.1mm"), corner_radius: ly.optional(), is_filled: ha.boolean().optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a fabrication note rectangle on the PCB");
var AI = ha.object({ type: ha.literal("pcb_fabrication_note_dimension"), pcb_fabrication_note_dimension_id: Cy("pcb_fabrication_note_dimension"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Vb, from: by, to: by, text: ha.string().optional(), text_ccw_rotation: ha.number().optional(), offset: ly.optional(), offset_distance: ly.optional(), offset_direction: ha.object({ x: ha.number(), y: ha.number() }).optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: ly.default("1mm"), color: ha.string().optional(), arrow_size: ly.default("1mm") }).describe("Defines a measurement annotation within PCB fabrication notes");
var OI = ha.object({ type: ha.literal("pcb_note_text"), pcb_note_text_id: Cy("pcb_note_text"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: dy.default("1mm"), text: ha.string().optional(), anchor_position: by.default({ x: 0, y: 0 }), anchor_alignment: ha.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center"), layer: Vb.default("top"), is_mirrored_from_top_view: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a documentation note in text on the PCB");
var kI = ha.object({ type: ha.literal("pcb_note_rect"), pcb_note_rect_id: Cy("pcb_note_rect"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), center: by, width: ly, height: ly, layer: Vb.default("top"), stroke_width: ly.default("0.1mm"), corner_radius: ly.optional(), is_filled: ha.boolean().optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a rectangular documentation note on the PCB");
var DI = ha.object({ type: ha.literal("pcb_note_path"), pcb_note_path_id: Cy("pcb_note_path"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), route: ha.array(by), layer: Vb.default("top"), stroke_width: ly.default("0.1mm"), color: ha.string().optional() }).describe("Defines a polyline documentation note on the PCB");
var LI = ha.object({ type: ha.literal("pcb_note_line"), pcb_note_line_id: Cy("pcb_note_line"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), x1: dy, y1: dy, x2: dy, y2: dy, layer: Vb.default("top"), stroke_width: dy.default("0.1mm"), color: ha.string().optional(), is_dashed: ha.boolean().optional() }).describe("Defines a straight documentation note line on the PCB");
var zI = ha.object({ type: ha.literal("pcb_note_dimension"), pcb_note_dimension_id: Cy("pcb_note_dimension"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), from: by, to: by, text: ha.string().optional(), text_ccw_rotation: ha.number().optional(), offset_distance: ly.optional(), offset_direction: ha.object({ x: ha.number(), y: ha.number() }).optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: ly.default("1mm"), layer: Vb.default("top"), color: ha.string().optional(), arrow_size: ly.default("1mm") }).describe("Defines a measurement annotation within PCB documentation notes");
var BI = Xy.extend({ type: ha.literal("pcb_footprint_overlap_error"), pcb_error_id: Cy("pcb_error"), error_type: ha.literal("pcb_footprint_overlap_error").default("pcb_footprint_overlap_error"), pcb_smtpad_ids: ha.array(ha.string()).optional(), pcb_plated_hole_ids: ha.array(ha.string()).optional(), pcb_hole_ids: ha.array(ha.string()).optional(), pcb_keepout_ids: ha.array(ha.string()).optional() }).describe("Error emitted when a pcb footprint overlaps with another element");
var FI = Xy.extend({ type: ha.literal("pcb_courtyard_overlap_error"), pcb_error_id: Cy("pcb_error"), error_type: ha.literal("pcb_courtyard_overlap_error").default("pcb_courtyard_overlap_error"), pcb_component_ids: ha.tuple([ha.string(), ha.string()]) }).describe("Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another");
var jI = ha.object({ type: ha.literal("pcb_keepout"), shape: ha.literal("outline"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), outline: ha.array(by).min(2), stroke_width: ly, pcb_keepout_id: ha.string(), layers: ha.array(ha.string()), description: ha.string().optional(), excluded_pcb_component_ids: ha.array(ha.string()).optional(), warning_only: ha.boolean().optional(), allow_traces: ha.boolean().optional(), allow_placements: ha.boolean().optional() });
var $I = ha.object({ type: ha.literal("pcb_keepout"), shape: ha.literal("rect"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, width: dy, height: dy, pcb_keepout_id: ha.string(), layers: ha.array(ha.string()), description: ha.string().optional(), excluded_pcb_component_ids: ha.array(ha.string()).optional(), warning_only: ha.boolean().optional(), allow_traces: ha.boolean().optional(), allow_placements: ha.boolean().optional() }).or(ha.object({ type: ha.literal("pcb_keepout"), shape: ha.literal("circle"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, radius: dy, pcb_keepout_id: ha.string(), layers: ha.array(ha.string()), description: ha.string().optional(), excluded_pcb_component_ids: ha.array(ha.string()).optional(), warning_only: ha.boolean().optional(), allow_traces: ha.boolean().optional(), allow_placements: ha.boolean().optional() })).or(jI);
var YI = ha.object({ type: ha.literal("pcb_keepout_overlap_warning"), pcb_keepout_overlap_warning_id: Cy("pcb_keepout_overlap_warning"), warning_type: ha.literal("pcb_keepout_overlap_warning").default("pcb_keepout_overlap_warning"), message: ha.string(), pcb_keepout_id: ha.string(), pcb_component_ids: ha.array(ha.string()).optional(), pcb_trace_ids: ha.array(ha.string()).optional(), pcb_smtpad_ids: ha.array(ha.string()).optional(), pcb_plated_hole_ids: ha.array(ha.string()).optional(), pcb_via_ids: ha.array(ha.string()).optional(), center: by.optional(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when copper overlaps a PCB keepout with warning_only enabled");
var XI = ha.object({ type: ha.literal("pcb_cutout"), pcb_cutout_id: Cy("pcb_cutout"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_board_id: ha.string().optional(), pcb_panel_id: ha.string().optional() });
var WI = XI.extend({ shape: ha.literal("rect"), center: by, width: ly, height: ly, rotation: _y.optional(), corner_radius: ly.optional() });
var VI = XI.extend({ shape: ha.literal("circle"), center: by, radius: ly });
var HI = XI.extend({ shape: ha.literal("polygon"), points: ha.array(by) });
var GI = XI.extend({ shape: ha.literal("path"), route: ha.array(by), slot_width: ly, slot_length: ly.optional(), space_between_slots: ly.optional(), slot_corner_radius: ly.optional() });
var UI = ha.discriminatedUnion("shape", [WI, VI, HI, GI]).describe("Defines a cutout on the PCB, removing board material.");
var ZI = Xy.extend({ type: ha.literal("pcb_missing_footprint_error"), pcb_missing_footprint_error_id: Cy("pcb_missing_footprint_error"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("pcb_missing_footprint_error").default("pcb_missing_footprint_error"), source_component_id: ha.string() }).describe("Defines a missing footprint error on the PCB");
var qI = Xy.extend({ type: ha.literal("external_footprint_load_error"), external_footprint_load_error_id: Cy("external_footprint_load_error"), pcb_component_id: ha.string(), source_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), footprinter_string: ha.string().optional(), error_type: ha.literal("external_footprint_load_error").default("external_footprint_load_error") }).describe("Defines an error when an external footprint fails to load");
var JI = Xy.extend({ type: ha.literal("circuit_json_footprint_load_error"), circuit_json_footprint_load_error_id: Cy("circuit_json_footprint_load_error"), pcb_component_id: ha.string(), source_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("circuit_json_footprint_load_error").default("circuit_json_footprint_load_error"), circuit_json: ha.array(ha.any()).optional() }).describe("Defines an error when a circuit JSON footprint fails to load");
var QI = ha.object({ type: ha.literal("pcb_group"), pcb_group_id: Cy("pcb_group"), source_group_id: ha.string(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), width: ly.optional(), height: ly.optional(), center: by, display_offset_x: ha.string().optional().describe("How to display the x offset for this group, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this group, usually corresponding with how the user specified it"), outline: ha.array(by).optional(), anchor_position: by.optional(), anchor_alignment: Py.default("center"), position_mode: ha.enum(["packed", "relative_to_group_anchor", "none"]).optional(), positioned_relative_to_pcb_group_id: ha.string().optional(), positioned_relative_to_pcb_board_id: ha.string().optional(), pcb_component_ids: ha.array(ha.string()), child_layout_mode: ha.enum(["packed", "none"]).optional(), name: ha.string().optional(), description: ha.string().optional(), layout_mode: ha.string().optional(), autorouter_configuration: ha.object({ trace_clearance: ly }).optional(), autorouter_used_string: ha.string().optional() }).describe("Defines a group of components on the PCB");
var KI = Xy.extend({ type: ha.literal("pcb_autorouting_error"), pcb_error_id: Cy("pcb_autorouting_error"), error_type: ha.literal("pcb_autorouting_error").default("pcb_autorouting_error"), subcircuit_id: ha.string().optional() }).describe("The autorouting has failed to route a portion of the board");
var eS = Xy.extend({ type: ha.literal("pcb_preflight_routing_error"), pcb_preflight_routing_error_id: Cy("pcb_preflight_routing_error"), error_type: ha.literal("pcb_preflight_routing_error").default("pcb_preflight_routing_error"), error_code: ha.string(), subcircuit_id: ha.string().optional(), pcb_group_id: ha.string().optional(), routing_phase_index: ha.number().int().optional(), phase_name: ha.string().optional(), source_trace_ids: ha.array(ha.string()).optional(), pcb_component_ids: ha.array(ha.string()).optional(), pcb_port_ids: ha.array(ha.string()).optional(), related_error_ids: ha.array(ha.string()).optional(), measurements: ha.record(ha.number().finite()).optional() });
var tS = ha.object({ type: ha.literal("pcb_manual_edit_conflict_warning"), pcb_manual_edit_conflict_warning_id: Cy("pcb_manual_edit_conflict_warning"), warning_type: ha.literal("pcb_manual_edit_conflict_warning").default("pcb_manual_edit_conflict_warning"), message: ha.string(), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_component_id: ha.string() }).describe("Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates");
var nS = ha.enum(["x-", "x+", "y+", "y-"]);
var oS = ha.object({ type: ha.literal("pcb_connector_not_in_accessible_orientation_warning"), pcb_connector_not_in_accessible_orientation_warning_id: Cy("pcb_connector_not_in_accessible_orientation_warning"), warning_type: ha.literal("pcb_connector_not_in_accessible_orientation_warning").default("pcb_connector_not_in_accessible_orientation_warning"), message: ha.string(), pcb_component_id: ha.string(), source_component_id: ha.string().optional(), pcb_board_id: ha.string().optional(), facing_direction: nS, recommended_facing_direction: nS, subcircuit_id: ha.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");
var iS = ha.object({ type: ha.literal("pcb_component_missing_courtyard_warning"), pcb_component_missing_courtyard_warning_id: Cy("pcb_component_missing_courtyard_warning"), warning_type: ha.literal("pcb_component_missing_courtyard_warning").default("pcb_component_missing_courtyard_warning"), message: ha.string(), pcb_component_id: ha.string(), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a PCB component has no courtyard geometry");
var rS = ha.object({ type: ha.literal("supplier_footprint_mismatch_warning"), supplier_footprint_mismatch_warning_id: Cy("supplier_footprint_mismatch_warning"), warning_type: ha.literal("supplier_footprint_mismatch_warning").default("supplier_footprint_mismatch_warning"), message: ha.string(), source_component_id: ha.string(), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), supplier_name: Wy.optional(), supplier_part_number: ha.string().optional(), supplier_footprint_url: ha.string().optional(), footprint_copper_intersection_over_union: ha.number() }).describe("Warning emitted when a supplier part footprint does not match the expected footprint");
var sS = ha.object({ type: ha.literal("pcb_fabricator_extra_charge_warning"), pcb_fabricator_extra_charge_warning_id: Cy("pcb_fabricator_extra_charge_warning"), warning_type: ha.literal("pcb_fabricator_extra_charge_warning").default("pcb_fabricator_extra_charge_warning"), message: ha.string(), fabricator_preset: ha.string(), pcb_board_id: ha.string().optional(), pcb_via_ids: ha.array(ha.string()).optional(), subcircuit_id: ha.string().optional() }).describe("Warning that a design feature incurs an extra charge for the selected fabricator preset, such as via hole diameters below 0.3 mm with JLCPCB economy or standard presets.");
var aS = ha.object({ type: ha.literal("pcb_breakout_point"), pcb_breakout_point_id: Cy("pcb_breakout_point"), pcb_group_id: ha.string(), subcircuit_id: ha.string().optional(), source_trace_id: ha.string().optional(), source_port_id: ha.string().optional(), source_net_id: ha.string().optional(), layer: Wb.optional(), x: dy, y: dy }).describe("Defines a routing target within a pcb_group for a source_trace or source_net");
var cS = ha.object({ type: ha.literal("pcb_ground_plane"), pcb_ground_plane_id: Cy("pcb_ground_plane"), source_pcb_ground_plane_id: ha.string(), source_net_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a ground plane on the PCB");
var lS = ha.object({ type: ha.literal("pcb_ground_plane_region"), pcb_ground_plane_region_id: Cy("pcb_ground_plane_region"), pcb_ground_plane_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Wb, points: ha.array(by) }).describe("Defines a polygon region of a ground plane");
var hS = ha.object({ type: ha.literal("pcb_thermal_spoke"), pcb_thermal_spoke_id: Cy("pcb_thermal_spoke"), pcb_ground_plane_id: ha.string(), shape: ha.string(), spoke_count: ha.number(), spoke_thickness: dy, spoke_inner_diameter: dy, spoke_outer_diameter: dy, pcb_plated_hole_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Pattern for connecting a ground plane to a plated hole");
var dS = ha.object({ type: ha.literal("pcb_copper_pour"), pcb_copper_pour_id: Cy("pcb_copper_pour"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Wb, source_net_id: ha.string().optional(), covered_with_solder_mask: ha.boolean().optional().default(true) });
var uS = dS.extend({ shape: ha.literal("rect"), center: by, width: ly, height: ly, rotation: _y.optional() });
var pS = dS.extend({ shape: ha.literal("brep"), brep_shape: Xx });
var mS = dS.extend({ shape: ha.literal("polygon"), points: ha.array(by) });
var gS = ha.discriminatedUnion("shape", [uS, pS, mS]).describe("Defines a copper pour on the PCB.");
var fS = Xy.extend({ type: ha.literal("pcb_component_outside_board_error"), pcb_component_outside_board_error_id: Cy("pcb_component_outside_board_error"), error_type: ha.literal("pcb_component_outside_board_error").default("pcb_component_outside_board_error"), pcb_component_id: ha.string(), pcb_board_id: ha.string(), component_center: by, component_bounds: ha.object({ min_x: ha.number(), max_x: ha.number(), min_y: ha.number(), max_y: ha.number() }), subcircuit_id: ha.string().optional(), source_component_id: ha.string().optional() }).describe("Error emitted when a PCB component is placed outside the board boundaries");
var _S = Xy.extend({ type: ha.literal("pcb_component_not_on_board_edge_error"), pcb_component_not_on_board_edge_error_id: Cy("pcb_component_not_on_board_edge_error"), error_type: ha.literal("pcb_component_not_on_board_edge_error").default("pcb_component_not_on_board_edge_error"), pcb_component_id: ha.string(), pcb_board_id: ha.string(), component_center: by, pad_to_nearest_board_edge_distance: ha.number(), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a component that must be placed on the board edge is centered away from the edge");
var yS = Xy.extend({ type: ha.literal("pcb_component_invalid_layer_error"), pcb_component_invalid_layer_error_id: Cy("pcb_component_invalid_layer_error"), error_type: ha.literal("pcb_component_invalid_layer_error").default("pcb_component_invalid_layer_error"), pcb_component_id: ha.string().optional(), source_component_id: ha.string(), layer: Wb, subcircuit_id: ha.string().optional() }).describe("Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)");
var bS = Xy.extend({ type: ha.literal("pcb_via_clearance_error"), pcb_error_id: Cy("pcb_error"), error_type: ha.literal("pcb_via_clearance_error").default("pcb_via_clearance_error"), pcb_via_ids: ha.array(ha.string()).min(2), minimum_clearance: dy.optional(), actual_clearance: dy.optional(), pcb_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when vias are closer than the allowed clearance");
var xS = Xy.extend({ type: ha.literal("pcb_via_trace_clearance_error"), pcb_via_trace_clearance_error_id: Cy("pcb_via_trace_clearance_error"), error_type: ha.literal("pcb_via_trace_clearance_error").default("pcb_via_trace_clearance_error"), pcb_via_id: ha.string(), pcb_trace_id: ha.string(), minimum_clearance: dy.optional(), actual_clearance: dy.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a via and trace are closer than the allowed clearance");
var vS = Xy.extend({ type: ha.literal("pcb_pad_pad_clearance_error"), pcb_pad_pad_clearance_error_id: Cy("pcb_pad_pad_clearance_error"), error_type: ha.literal("pcb_pad_pad_clearance_error").default("pcb_pad_pad_clearance_error"), pcb_pad_ids: ha.array(ha.string()).min(2), minimum_clearance: dy.optional(), actual_clearance: dy.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when pads are closer than the allowed clearance");
var IS = Xy.extend({ type: ha.literal("pcb_pad_trace_clearance_error"), pcb_pad_trace_clearance_error_id: Cy("pcb_pad_trace_clearance_error"), error_type: ha.literal("pcb_pad_trace_clearance_error").default("pcb_pad_trace_clearance_error"), pcb_pad_id: ha.string(), pcb_trace_id: ha.string(), minimum_clearance: dy.optional(), actual_clearance: dy.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a pad and trace are closer than allowed clearance");
var SS = ha.object({ type: ha.literal("pcb_courtyard_rect"), pcb_courtyard_rect_id: Cy("pcb_courtyard_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, width: ly, height: ly, layer: Vb, ccw_rotation: _y.optional(), color: ha.string().optional() }).describe("Defines a courtyard rectangle on the PCB");
var CS = ha.object({ type: ha.literal("pcb_courtyard_outline"), pcb_courtyard_outline_id: Cy("pcb_courtyard_outline"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Vb, outline: ha.array(by).min(2) }).describe("Defines a courtyard outline on the PCB");
var PS = ha.object({ type: ha.literal("pcb_courtyard_polygon"), pcb_courtyard_polygon_id: Cy("pcb_courtyard_polygon"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: Vb, points: ha.array(by).min(3), color: ha.string().optional() }).describe("Defines a courtyard polygon on the PCB");
var MS = ha.object({ type: ha.literal("pcb_courtyard_circle"), pcb_courtyard_circle_id: Cy("pcb_courtyard_circle"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, radius: ly, layer: Vb, color: ha.string().optional() }).describe("Defines a courtyard circle on the PCB");
var wS = ha.object({ type: ha.literal("pcb_courtyard_pill"), pcb_courtyard_pill_id: Cy("pcb_courtyard_pill"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: by, width: ly, height: ly, radius: ly, layer: Vb, color: ha.string().optional() }).describe("Defines a courtyard pill on the PCB");
var NS = ["obj", "stl", "3mf", "gltf", "glb", "step", "wrl"];
var TS = ["x+", "x-", "y+", "y-", "z+", "z-"];
var RS = { obj: "z+", stl: "z+", "3mf": "z+", gltf: "y+", glb: "y+", step: "z+", wrl: "y+" };
var ES = ha.object({ type: ha.literal("cad_component"), cad_component_id: ha.string(), pcb_component_id: ha.string().optional().describe("Optional PCB component reference; omit for CAD geometry without a PCB component"), source_component_id: ha.string(), position: vy, rotation: vy.optional(), is_on_folded_board: ha.boolean().optional().describe("True when position and rotation describe the assembled folded board pose. False or omitted means the flat board pose. PCB records remain flat; pcb_component_id identifies the flat mount and owning board for reversible transforms."), size: vy.optional(), layer: Wb.optional(), subcircuit_id: ha.string().optional(), footprinter_string: ha.string().optional(), model_obj_url: ha.string().optional(), model_stl_url: ha.string().optional(), model_3mf_url: ha.string().optional(), model_gltf_url: ha.string().optional(), model_glb_url: ha.string().optional(), model_step_url: ha.string().optional(), model_wrl_url: ha.string().optional(), model_asset: wy.optional(), model_unit_to_mm_scale_factor: ha.number().optional(), model_board_normal_direction: ha.enum(TS).optional().describe(`The direction in the model's coordinate space that is considered "up" or "coming out of the board surface"`), model_origin_position: vy.optional(), model_origin_alignment: ha.enum(["unknown", "center", "center_of_component_on_board_surface", "bottom_center_of_component"]).optional(), model_object_fit: ha.enum(["contain_within_bounds", "fill_bounds"]).optional().default("contain_within_bounds"), model_jscad: ha.any().optional(), show_as_translucent_model: ha.boolean().optional(), show_as_bounding_box: ha.boolean().optional(), show_hidden_edges: ha.boolean().optional(), anchor_alignment: ha.enum(["center", "center_of_component_on_board_surface"]).optional().default("center") }).describe("Defines CAD geometry, optionally associated with a PCB component");
var AS = ha.enum(["sinewave", "square", "triangle", "sawtooth"]);
var OS = ha.union([ha.string(), ha.number()]).transform((e33) => typeof e33 == "string" ? e33.endsWith("%") ? parseFloat(e33.slice(0, -1)) / 100 : parseFloat(e33) : e33).pipe(ha.number().min(0, "Duty cycle must be non-negative").max(1, "Duty cycle cannot be greater than 100%"));
var kS = ha.object({ type: ha.literal("simulation_voltage_source"), simulation_voltage_source_id: Cy("simulation_voltage_source"), is_dc_source: ha.literal(true).optional().default(true), positive_source_port_id: ha.string().optional(), negative_source_port_id: ha.string().optional(), positive_source_net_id: ha.string().optional(), negative_source_net_id: ha.string().optional(), voltage: cy, ac_magnitude: cy.optional(), ac_phase: _y.optional() }).describe("Defines a DC voltage source for simulation");
var DS = ha.object({ type: ha.literal("simulation_voltage_source"), simulation_voltage_source_id: Cy("simulation_voltage_source"), is_dc_source: ha.literal(false), terminal1_source_port_id: ha.string().optional(), terminal2_source_port_id: ha.string().optional(), terminal1_source_net_id: ha.string().optional(), terminal2_source_net_id: ha.string().optional(), voltage: cy.optional(), frequency: hy.optional(), peak_to_peak_voltage: cy.optional(), wave_shape: AS.optional(), phase: _y.optional(), duty_cycle: OS.optional(), pulse_delay: gy.optional(), rise_time: gy.optional(), fall_time: gy.optional(), pulse_width: gy.optional(), period: gy.optional(), ac_magnitude: cy.optional(), ac_phase: _y.optional() }).describe("Defines an AC voltage source for simulation");
var LS = ha.union([kS, DS]).describe("Defines a voltage source for simulation");
var zS = ha.union([ha.string(), ha.number()]).transform((e33) => typeof e33 == "string" ? e33.endsWith("%") ? parseFloat(e33.slice(0, -1)) / 100 : parseFloat(e33) : e33).pipe(ha.number().min(0, "Duty cycle must be non-negative").max(1, "Duty cycle cannot be greater than 100%"));
var BS = ha.object({ type: ha.literal("simulation_current_source"), simulation_current_source_id: Cy("simulation_current_source"), is_dc_source: ha.literal(true).optional().default(true), positive_source_port_id: ha.string().optional(), negative_source_port_id: ha.string().optional(), positive_source_net_id: ha.string().optional(), negative_source_net_id: ha.string().optional(), current: uy, ac_magnitude: uy.optional(), ac_phase: _y.optional() }).describe("Defines a DC current source for simulation");
var FS = ha.object({ type: ha.literal("simulation_current_source"), simulation_current_source_id: Cy("simulation_current_source"), is_dc_source: ha.literal(false), terminal1_source_port_id: ha.string().optional(), terminal2_source_port_id: ha.string().optional(), terminal1_source_net_id: ha.string().optional(), terminal2_source_net_id: ha.string().optional(), current: uy.optional(), frequency: hy.optional(), peak_to_peak_current: uy.optional(), wave_shape: AS.optional(), phase: _y.optional(), duty_cycle: zS.optional(), ac_magnitude: uy.optional(), ac_phase: _y.optional() }).describe("Defines an AC current source for simulation");
var jS = ha.union([BS, FS]).describe("Defines a current source for simulation");
var $S = ha.custom((e33) => e33 === "V" || e33 === "A");
var YS = ha.custom((e33) => e33 === "Ω" || e33 === "F" || e33 === "H" || e33 === "V" || e33 === "A");
var XS = ha.union([ha.literal("spice_dc_sweep"), ha.literal("spice_dc_operating_point"), ha.literal("spice_transient_analysis"), ha.literal("spice_ac_analysis")]);
var WS = ha.object({ method: ha.enum(["trap", "gear"]).optional(), reltol: ha.union([ha.number(), ha.string()]).optional(), abstol: ha.union([ha.number(), ha.string()]).optional(), vntol: ha.union([ha.number(), ha.string()]).optional() }).describe("SPICE solver options for a simulation experiment");
var VS = ha.object({ type: ha.literal("simulation_experiment"), simulation_experiment_id: Cy("simulation_experiment"), name: ha.string(), experiment_type: XS, time_per_step: py.optional(), start_time_ms: gy.optional(), end_time_ms: gy.optional(), spice_options: WS.optional(), dc_sweep_voltage_source_id: ha.string().optional(), dc_sweep_current_source_id: ha.string().optional(), dc_sweep_start: ha.number().optional(), dc_sweep_stop: ha.number().optional(), dc_sweep_step: ha.number().refine((e33) => e33 !== 0).optional(), dc_sweep_unit: $S.optional(), ac_sweep_type: ha.enum(["linear", "decade", "octave"]).optional(), ac_samples_per_interval: ha.number().int().positive().optional(), ac_sample_count: ha.number().int().positive().optional(), ac_start_frequency_hz: ha.number().positive().optional(), ac_stop_frequency_hz: ha.number().positive().optional() }).superRefine((e33, t2) => {
if (e33.experiment_type === "spice_dc_sweep") {
const n2 = ["dc_sweep_start", "dc_sweep_stop", "dc_sweep_step", "dc_sweep_unit"];
for (const o2 of n2)
e33[o2] === undefined && t2.addIssue({ code: ha.ZodIssueCode.custom, path: [o2], message: `${o2} is required for a DC sweep` });
e33.dc_sweep_voltage_source_id !== undefined === (e33.dc_sweep_current_source_id !== undefined) && t2.addIssue({ code: ha.ZodIssueCode.custom, path: ["dc_sweep_voltage_source_id"], message: "Exactly one DC sweep voltage or current source ID is required" });
}
e33.experiment_type === "spice_ac_analysis" && (e33.ac_sweep_type === undefined && t2.addIssue({ code: ha.ZodIssueCode.custom, path: ["ac_sweep_type"], message: "ac_sweep_type is required for an AC analysis" }), e33.ac_start_frequency_hz === undefined && t2.addIssue({ code: ha.ZodIssueCode.custom, path: ["ac_start_frequency_hz"], message: "ac_start_frequency_hz is required for an AC analysis" }), e33.ac_stop_frequency_hz === undefined && t2.addIssue({ code: ha.ZodIssueCode.custom, path: ["ac_stop_frequency_hz"], message: "ac_stop_frequency_hz is required for an AC analysis" }), e33.ac_sweep_type === "linear" && e33.ac_sample_count === undefined && t2.addIssue({ code: ha.ZodIssueCode.custom, path: ["ac_sample_count"], message: "ac_sample_count is required for a linear AC analysis" }), e33.ac_sweep_type !== "decade" && e33.ac_sweep_type !== "octave" || e33.ac_samples_per_interval !== undefined || t2.addIssue({ code: ha.ZodIssueCode.custom, path: ["ac_samples_per_interval"], message: "ac_samples_per_interval is required for decade and octave AC analyses" }));
}).describe("Defines a simulation experiment configuration");
var HS = ha.object({ simulation_parameter_sweep_id: ha.string(), sweep_index: ha.number().int().nonnegative(), parameter_value: ha.number(), parameter_unit: YS });
var GS = ha.object({ type: ha.literal("simulation_transient_voltage_graph"), simulation_transient_voltage_graph_id: Cy("simulation_transient_voltage_graph"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), timestamps_ms: ha.array(ha.number()).optional(), voltage_levels: ha.array(ha.number()), source_component_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), time_per_step: py, start_time_ms: gy, end_time_ms: gy, name: ha.string().optional(), color: ha.string().optional() }).describe("Stores voltage measurements over time for a simulation");
var US = ha.object({ type: ha.literal("simulation_transient_current_graph"), simulation_transient_current_graph_id: Cy("simulation_transient_current_graph"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), timestamps_ms: ha.array(ha.number()).optional(), current_levels: ha.array(ha.number()), source_component_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), time_per_step: py, start_time_ms: gy, end_time_ms: gy, name: ha.string().optional(), color: ha.string().optional() }).describe("Stores current measurements over time for a simulation");
var ZS = ha.object({ type: ha.literal("simulation_switch"), simulation_switch_id: Cy("simulation_switch"), source_component_id: ha.string().optional(), closes_at: gy.optional(), opens_at: gy.optional(), starts_closed: ha.boolean().optional(), switching_frequency: hy.optional() }).describe("Defines a switch for simulation timing control");
var qS = ha.object({ type: ha.literal("simulation_voltage_probe"), simulation_voltage_probe_id: Cy("simulation_voltage_probe"), source_component_id: ha.string().optional(), name: ha.string().optional(), signal_input_source_port_id: ha.string().optional(), signal_input_source_net_id: ha.string().optional(), reference_input_source_port_id: ha.string().optional(), reference_input_source_net_id: ha.string().optional(), subcircuit_id: ha.string().optional(), color: ha.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((e33, t2) => {
if (e33.reference_input_source_port_id || e33.reference_input_source_net_id) {
const n2 = !!e33.signal_input_source_port_id || !!e33.reference_input_source_port_id, o2 = !!e33.signal_input_source_net_id || !!e33.reference_input_source_net_id;
n2 && o2 ? t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Cannot mix port and net connections in a differential probe." }) : n2 ? e33.signal_input_source_port_id && e33.reference_input_source_port_id || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id." }) : o2 && (e33.signal_input_source_net_id && e33.reference_input_source_net_id || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id." }));
} else
!!e33.signal_input_source_port_id == !!e33.signal_input_source_net_id && t2.addIssue({ code: ha.ZodIssueCode.custom, message: "A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id." });
});
var JS = ha.object({ type: ha.literal("simulation_current_probe"), simulation_current_probe_id: Cy("simulation_current_probe"), source_component_id: ha.string().optional(), name: ha.string().optional(), positive_source_port_id: ha.string().optional(), negative_source_port_id: ha.string().optional(), positive_source_net_id: ha.string().optional(), negative_source_net_id: ha.string().optional(), subcircuit_id: ha.string().optional(), color: ha.string().optional() }).describe("Defines a current probe for simulation. It measures current flowing from the positive endpoint to the negative endpoint.").superRefine((e33, t2) => {
const n2 = !!e33.positive_source_port_id, o2 = !!e33.negative_source_port_id, i2 = !!e33.positive_source_net_id, r2 = !!e33.negative_source_net_id, s2 = n2 || o2, a2 = i2 || r2;
s2 && a2 ? t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Cannot mix port and net connections in a current probe." }) : s2 ? n2 && o2 || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Current probe using source ports requires both positive_source_port_id and negative_source_port_id." }) : a2 ? i2 && r2 || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Current probe using source nets requires both positive_source_net_id and negative_source_net_id." }) : t2.addIssue({ code: ha.ZodIssueCode.custom, message: "A current probe must have either positive/negative source port ids or positive/negative source net ids." });
});
var QS = Xy.extend({ type: ha.literal("simulation_unknown_experiment_error"), simulation_unknown_experiment_error_id: Cy("simulation_unknown_experiment_error"), error_type: ha.literal("simulation_unknown_experiment_error").default("simulation_unknown_experiment_error"), simulation_experiment_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("An unknown error occurred during the simulation experiment.");
var KS = ha.enum(["resistance", "capacitance", "inductance", "voltage", "current"]);
var eC = ha.object({ type: ha.literal("simulation_parameter_sweep"), simulation_parameter_sweep_id: Cy("simulation_parameter_sweep"), simulation_experiment_id: ha.string(), name: ha.string().optional(), parameter_values: ha.array(ha.number()).min(1), parameter_unit: YS });
var tC = ha.discriminatedUnion("parameter_type", [eC.extend({ parameter_type: ha.literal("resistance"), resistor_source_component_id: ha.string() }), eC.extend({ parameter_type: ha.literal("capacitance"), capacitor_source_component_id: ha.string() }), eC.extend({ parameter_type: ha.literal("inductance"), inductor_source_component_id: ha.string() }), eC.extend({ parameter_type: ha.literal("voltage"), source_net_id: ha.string() }), eC.extend({ parameter_type: ha.literal("current"), current_source_component_id: ha.string() })]).describe("Repeats a simulation experiment over component parameter values");
var nC = ha.object({ type: ha.literal("simulation_dc_operating_point_voltage"), simulation_dc_operating_point_voltage_id: Cy("simulation_dc_operating_point_voltage"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), simulation_voltage_probe_id: ha.string(), voltage: ha.number(), name: ha.string().optional(), color: ha.string().optional() });
var oC = ha.object({ type: ha.literal("simulation_dc_operating_point_current"), simulation_dc_operating_point_current_id: Cy("simulation_dc_operating_point_current"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), simulation_current_probe_id: ha.string(), current: ha.number(), name: ha.string().optional(), color: ha.string().optional() });
var iC = ha.object({ type: ha.literal("simulation_dc_sweep_voltage_graph"), simulation_dc_sweep_voltage_graph_id: Cy("simulation_dc_sweep_voltage_graph"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), simulation_voltage_probe_id: ha.string(), sweep_values: ha.array(ha.number()), sweep_unit: $S, voltage_levels: ha.array(ha.number()), name: ha.string().optional(), color: ha.string().optional() }).refine((e33) => e33.sweep_values.length === e33.voltage_levels.length, { message: "sweep_values and voltage_levels must have the same length" });
var rC = ha.object({ type: ha.literal("simulation_dc_sweep_current_graph"), simulation_dc_sweep_current_graph_id: Cy("simulation_dc_sweep_current_graph"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), simulation_current_probe_id: ha.string(), sweep_values: ha.array(ha.number()), sweep_unit: $S, current_levels: ha.array(ha.number()), name: ha.string().optional(), color: ha.string().optional() }).refine((e33) => e33.sweep_values.length === e33.current_levels.length, { message: "sweep_values and current_levels must have the same length" });
var sC = ha.object({ re: ha.number(), im: ha.number() });
var aC = ha.object({ type: ha.literal("simulation_ac_sweep_voltage_graph"), simulation_ac_sweep_voltage_graph_id: Cy("simulation_ac_sweep_voltage_graph"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), simulation_voltage_probe_id: ha.string(), frequencies_hz: ha.array(ha.number()), complex_voltages: ha.array(sC), name: ha.string().optional(), color: ha.string().optional() }).refine((e33) => e33.frequencies_hz.length === e33.complex_voltages.length, { message: "frequencies_hz and complex_voltages must have the same length" });
var cC = ha.object({ type: ha.literal("simulation_ac_sweep_current_graph"), simulation_ac_sweep_current_graph_id: Cy("simulation_ac_sweep_current_graph"), simulation_experiment_id: ha.string(), simulation_parameter_sweep_coordinate: HS.optional(), simulation_current_probe_id: ha.string(), frequencies_hz: ha.array(ha.number()), complex_currents: ha.array(sC), name: ha.string().optional(), color: ha.string().optional() }).refine((e33) => e33.frequencies_hz.length === e33.complex_currents.length, { message: "frequencies_hz and complex_currents must have the same length" });
var lC = ha.object({ type: ha.literal("simulation_op_amp"), simulation_op_amp_id: Cy("simulation_op_amp"), source_component_id: ha.string().optional(), inverting_input_source_port_id: ha.string(), non_inverting_input_source_port_id: ha.string(), output_source_port_id: ha.string(), positive_supply_source_port_id: ha.string(), negative_supply_source_port_id: ha.string() }).describe("Defines a simple ideal operational amplifier for simulation");
var hC = ha.object({ type: ha.literal("simulation_spice_subcircuit"), simulation_spice_subcircuit_id: Cy("simulation_spice_subcircuit"), source_component_id: ha.string(), spice_pin_to_source_port_map: ha.record(ha.string(), ha.string()), subcircuit_source: ha.string() }).describe("Defines a custom SPICE subcircuit model for simulation");
var dC = (e33) => e33 !== undefined;
var uC = ha.object({ type: ha.literal("simulation_oscilloscope_trace"), simulation_oscilloscope_trace_id: Cy("simulation_oscilloscope_trace"), simulation_transient_voltage_graph_id: ha.string().optional(), simulation_transient_current_graph_id: ha.string().optional(), simulation_voltage_probe_id: ha.string().optional(), simulation_current_probe_id: ha.string().optional(), display_name: ha.string().optional(), color: ha.string().optional(), display_center_value: ha.number().optional(), display_center_offset_divs: ha.number().optional(), volts_per_div: ha.number().positive().optional(), amps_per_div: ha.number().positive().optional() }).describe("Defines how a simulation measurement is rendered as an oscilloscope-style trace.").superRefine((e33, t2) => {
const n2 = [e33.simulation_transient_voltage_graph_id, e33.simulation_voltage_probe_id].filter(dC).length, o2 = [e33.simulation_transient_current_graph_id, e33.simulation_current_probe_id].filter(dC).length;
n2 + o2 !== 1 && t2.addIssue({ code: ha.ZodIssueCode.custom, message: "An oscilloscope trace must reference exactly one voltage graph, current graph, voltage probe, or current probe." }), n2 > 0 && e33.amps_per_div !== undefined && t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Voltage oscilloscope traces must use volts_per_div, not amps_per_div." }), o2 > 0 && e33.volts_per_div !== undefined && t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Current oscilloscope traces must use amps_per_div, not volts_per_div." });
});
var pC = ha.union([Lb, tx, kb, Db, Ob, Bb, zb, Qy, Hy, Uy, qy, Gy, Ky, ib, rb, lb, ub, pb, yb, mb, gb, fb, _b, ab, sb, $b, Hb, Fb, bb, Ib, Sb, Pb, Gb, ex, Mb, wb, Ub, Zb, qb, Jb, Qb, Kb, Rb, Eb, jb, ev, rv, yv, ZI, qI, JI, tS, oS, iS, rS, sS, Pv, $I, YI, Mv, oI, $v, Gv, Uv, Jv, Zv, qv, Qv, iI, Ov, jv, rI, aI, pI, mI, QI, yI, bI, xI, vI, NI, II, SI, CI, PI, wI, Kv, eI, gI, fI, _I, tI, nI, bS, xS, vS, IS, RI, TI, EI, AI, OI, kI, DI, LI, zI, KI, eS, BI, FI, aS, UI, cS, lS, hS, gS, fS, _S, yS, SS, CS, PS, MS, wS, nx, yx, dx, ux, px, mx, cx, hx, bx, gx, ox, vx, Ix, xx, wx, Nx, Tx, Rx, Ex, jx, Ax, kx, Dx, Fx, Lx, zx, ES, LS, jS, VS, GS, US, nC, oC, iC, rC, aC, cC, tC, ZS, qS, JS, uC, QS, lC, hC]);
var mC = pC;
function gC(e33, t2, n2) {
if (!t2 || !n2)
return;
let o2 = e33.get(t2);
o2 || (o2 = new Set, e33.set(t2, o2)), o2.add(n2);
let i2 = e33.get(n2);
i2 || (i2 = new Set, e33.set(n2, i2)), i2.add(t2);
}
var fC = (e33, t2 = {}) => {
const n2 = e33;
let o2 = n2._internal_store;
if (!o2) {
o2 = { counts: {}, editCount: 0 }, n2._internal_store = o2;
for (const e34 of n2) {
const t3 = e34.type, n3 = e34[`${t3}_id`];
if (!n3)
continue;
const i3 = Number.parseInt(n3.split("_").pop());
Number.isNaN(i3) || (o2.counts[t3] = Math.max(o2.counts[t3] ?? 0, i3));
}
}
const i2 = new Proxy({}, { get: (e34, r2) => {
if (r2 === "toArray")
return () => (n2.editCount = o2.editCount, n2);
if (r2 === "editCount")
return o2.editCount;
if (r2 === "subtree")
return (e35) => fC(function(e36, t3) {
if (!t3.subcircuit_id && !t3.source_group_id)
return [...e36];
let n3 = t3;
if (t3.subcircuit_id) {
const o4 = new Set([t3.subcircuit_id]), i4 = new Map, r4 = new Map;
for (const t4 of e36)
if (t4.type === "source_group") {
const { source_group_id: e37, subcircuit_id: n4 } = t4;
n4 && r4.set(e37, n4);
const o5 = t4.parent_source_group_id;
o5 && (i4.has(o5) || i4.set(o5, []), i4.get(o5).push(e37));
}
let s4;
for (const [e37, n4] of r4)
if (n4 === t3.subcircuit_id) {
s4 = e37;
break;
}
if (s4) {
const e37 = (t4) => {
const n4 = i4.get(t4) || [];
for (const t5 of n4) {
const n5 = r4.get(t5);
n5 && o4.add(n5), e37(t5);
}
};
e37(s4), n3 = { ...t3, subcircuit_ids: Array.from(o4) };
}
}
const o3 = new Map;
for (const t4 of e36) {
const e37 = t4[`${t4.type}_id`];
typeof e37 == "string" && o3.set(e37, t4);
}
const i3 = new Map;
for (const t4 of e36) {
const e37 = Object.entries(t4);
for (const [n4, r4] of e37)
if (n4 !== "parent_source_group_id") {
if (n4.endsWith("_id") && typeof r4 == "string")
gC(i3, t4, o3.get(r4));
else if (n4.endsWith("_ids") && Array.isArray(r4))
for (const e38 of r4)
typeof e38 == "string" && gC(i3, t4, o3.get(e38));
}
}
const r3 = [], s3 = new Set;
for (const t4 of e36) {
let e37 = false;
(n3.subcircuit_id && ("subcircuit_id" in t4) && t4.subcircuit_id === n3.subcircuit_id || n3.subcircuit_ids && ("subcircuit_id" in t4) && t4.subcircuit_id && n3.subcircuit_ids.includes(t4.subcircuit_id) || n3.source_group_id && ("source_group_id" in t4) && t4.source_group_id === n3.source_group_id || n3.source_group_id && ("member_source_group_ids" in t4) && Array.isArray(t4.member_source_group_ids) && t4.member_source_group_ids.includes(n3.source_group_id)) && (e37 = true), e37 && (r3.push(t4), s3.add(t4));
}
for (;r3.length > 0; ) {
const e37 = r3.shift(), t4 = i3.get(e37);
if (t4)
for (const e38 of t4)
s3.has(e38) || (s3.add(e38), r3.push(e38));
}
return e36.filter((e37) => s3.has(e37));
}(n2, e35), t2);
if (r2 === "insert")
return (e35) => {
const i3 = e35.type;
if (!i3)
throw new Error("insert requires an element with a type");
o2.counts[i3] ??= -1, o2.counts[i3]++;
const r3 = o2.counts[i3], s3 = { ...e35, type: i3, [`${i3}_id`]: `${i3}_${r3}` };
if (t2.validateInserts) {
(q_[i3] ?? mC).parse(s3);
}
return n2.push(s3), o2.editCount++, s3;
};
if (r2 === "insertAll")
return (e35) => e35.map((e36) => i2.insert(e36));
const s2 = r2;
return { get: (e35) => n2.find((t3) => t3.type === s2 && t3[`${s2}_id`] === e35), getUsing: (e35) => {
const t3 = Object.keys(e35);
if (t3.length !== 1)
throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");
const o3 = t3[0], i3 = o3.replace("_id", ""), r3 = n2.find((t4) => t4.type === i3 && t4[o3] === e35[o3]);
return r3 ? n2.find((e36) => e36.type === s2 && e36[`${s2}_id`] === r3[`${s2}_id`]) : null;
}, getWhere: (e35) => {
const t3 = Object.keys(e35);
return n2.find((n3) => n3.type === s2 && t3.every((t4) => n3[t4] === e35[t4]));
}, list: (e35) => {
const t3 = e35 ? Object.keys(e35) : [];
return n2.filter((n3) => n3.type === s2 && t3.every((t4) => n3[t4] === e35[t4]));
}, insert: (e35) => {
o2.counts[s2] ??= -1, o2.counts[s2]++;
const i3 = o2.counts[s2], r3 = { type: s2, [`${s2}_id`]: `${s2}_${i3}`, ...e35 };
if (t2.validateInserts) {
(q_[s2] ?? mC).parse(r3);
}
return n2.push(r3), o2.editCount++, r3;
}, delete: (e35) => {
const t3 = n2.find((t4) => t4[`${s2}_id`] === e35);
t3 && (n2.splice(n2.indexOf(t3), 1), o2.editCount++);
}, update: (e35, t3) => {
const i3 = n2.find((t4) => t4.type === s2 && t4[`${s2}_id`] === e35);
return i3 ? (Object.assign(i3, t3), o2.editCount++, i3) : null;
}, select: (e35) => {
if (s2 === "source_component")
return n2.find((t3) => t3.type === "source_component" && t3.name === e35.replace(/\./g, ""));
if (s2 === "pcb_port" || s2 === "source_port" || s2 === "schematic_port") {
const [t3, o3] = e35.replace(/\./g, "").split(/[\s\>]+/), i3 = n2.find((e36) => e36.type === "source_component" && e36.name === t3);
if (!i3)
return null;
const r3 = n2.find((e36) => e36.type === "source_port" && e36.source_component_id === i3.source_component_id && (e36.name === o3 || (e36.port_hints ?? []).includes(o3)));
if (!r3)
return null;
if (s2 === "source_port")
return r3;
if (s2 === "pcb_port")
return n2.find((e36) => e36.type === "pcb_port" && e36.source_port_id === r3.source_port_id);
if (s2 === "schematic_port")
return n2.find((e36) => e36.type === "schematic_port" && e36.source_port_id === r3.source_port_id);
}
} };
} });
return i2;
};
fC.unparsed = fC;
var _C = fC;
function yC(e33) {
const t2 = e33.type;
return `${t2}:${e33[`${t2}_id`]}`;
}
var bC = (e33, t2 = {}) => {
let n2 = e33._internal_store_indexed;
if (!n2) {
n2 = { counts: {}, editCount: 0, indexes: {} };
for (const t3 of e33) {
const e34 = t3.type, o3 = t3[`${e34}_id`];
if (!o3)
continue;
const i3 = Number.parseInt(o3.split("_").pop() || "");
Number.isNaN(i3) || (n2.counts[e34] = Math.max(n2.counts[e34] ?? 0, i3));
}
const o2 = t2.indexConfig || {}, i2 = n2.indexes;
if (o2.byId && (i2.byId = new Map), o2.byType && (i2.byType = new Map), o2.byRelation && (i2.byRelation = new Map), o2.bySubcircuit && (i2.bySubcircuit = new Map), o2.byCustomField && o2.byCustomField.length > 0) {
i2.byCustomField = new Map;
for (const e34 of o2.byCustomField)
i2.byCustomField.set(e34, new Map);
}
for (const t3 of e33) {
if (o2.byId) {
const e34 = yC(t3);
i2.byId.set(e34, t3);
}
if (o2.byType) {
const e34 = i2.byType.get(t3.type) || [];
e34.push(t3), i2.byType.set(t3.type, e34);
}
if (o2.byRelation) {
const e34 = Object.entries(t3);
for (const [n3, o3] of e34)
if (n3.endsWith("_id") && n3 !== `${t3.type}_id` && typeof o3 == "string") {
const e35 = i2.byRelation.get(n3) || new Map, r2 = e35.get(o3) || [];
r2.push(t3), e35.set(o3, r2), i2.byRelation.set(n3, e35);
}
}
if (o2.bySubcircuit && "subcircuit_id" in t3) {
const e34 = t3.subcircuit_id;
if (e34 && typeof e34 == "string") {
const n3 = i2.bySubcircuit.get(e34) || [];
n3.push(t3), i2.bySubcircuit.set(e34, n3);
}
}
if (o2.byCustomField && i2.byCustomField) {
for (const e34 of o2.byCustomField)
if (e34 in t3) {
const n3 = t3[e34];
if (n3 !== undefined && (typeof n3 == "string" || typeof n3 == "number")) {
const o3 = String(n3), r2 = i2.byCustomField.get(e34), s2 = r2.get(o3) || [];
s2.push(t3), r2.set(o3, s2);
}
}
}
}
e33._internal_store_indexed = n2;
}
return new Proxy({}, { get: (o2, i2) => {
if (i2 === "toArray")
return () => (e33.editCount = n2.editCount, e33);
if (i2 === "editCount")
return n2.editCount;
const r2 = i2;
return { get: (o3) => {
const i3 = t2.indexConfig || {};
if (i3.byId && n2.indexes.byId)
return n2.indexes.byId.get(`${r2}:${o3}`) || null;
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e34) => e34[`${r2}_id`] === o3) || null;
}
return e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === o3) || null;
}, getUsing: (o3) => {
const i3 = t2.indexConfig || {}, s2 = Object.keys(o3);
if (s2.length !== 1)
throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");
const a2 = s2[0], c2 = a2.replace("_id", "");
if (i3.byRelation && n2.indexes.byRelation) {
const t3 = n2.indexes.byRelation.get(a2);
if (t3) {
const s3 = (t3.get(o3[a2]) || []).find((e34) => e34.type === c2);
if (!s3)
return null;
const l3 = s3[`${r2}_id`];
if (i3.byId && n2.indexes.byId)
return n2.indexes.byId.get(`${r2}:${l3}`) || null;
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e34) => e34[`${r2}_id`] === l3) || null;
}
return e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === l3) || null;
}
}
const l2 = e33.find((e34) => e34.type === c2 && e34[a2] === o3[a2]);
return l2 && e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === l2[`${r2}_id`]) || null;
}, getWhere: (o3) => {
const i3 = t2.indexConfig || {}, s2 = Object.keys(o3);
if (s2.length === 1 && i3.byCustomField && n2.indexes.byCustomField) {
const e34 = s2[0], t3 = n2.indexes.byCustomField.get(e34);
if (t3) {
const n3 = String(o3[e34]);
return (t3.get(n3) || []).find((e35) => e35.type === r2) || null;
}
}
if ("subcircuit_id" in o3 && i3.bySubcircuit && n2.indexes.bySubcircuit) {
const e34 = o3.subcircuit_id;
return (n2.indexes.bySubcircuit.get(e34) || []).find((e35) => e35.type === r2 && s2.every((t3) => e35[t3] === o3[t3])) || null;
}
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e34) => s2.every((t3) => e34[t3] === o3[t3])) || null;
}
return e33.find((e34) => e34.type === r2 && s2.every((t3) => e34[t3] === o3[t3])) || null;
}, list: (o3) => {
const i3 = t2.indexConfig || {}, s2 = o3 ? Object.keys(o3) : [];
if (s2.length === 0 && i3.byType && n2.indexes.byType)
return n2.indexes.byType.get(r2) || [];
if (s2.length === 1 && s2[0] === "subcircuit_id" && i3.bySubcircuit && n2.indexes.bySubcircuit) {
const e34 = o3.subcircuit_id;
return (n2.indexes.bySubcircuit.get(e34) || []).filter((e35) => e35.type === r2);
}
let a2;
return a2 = i3.byType && n2.indexes.byType ? n2.indexes.byType.get(r2) || [] : e33.filter((e34) => e34.type === r2), s2.length > 0 ? a2.filter((e34) => s2.every((t3) => e34[t3] === o3[t3])) : a2;
}, insert: (o3) => {
n2.counts[r2] ??= -1, n2.counts[r2]++;
const i3 = n2.counts[r2], s2 = { type: r2, [`${r2}_id`]: `${r2}_${i3}`, ...o3 };
if (t2.validateInserts) {
(q_[r2] ?? mC).parse(s2);
}
e33.push(s2), n2.editCount++;
const a2 = t2.indexConfig || {};
if (a2.byId && n2.indexes.byId) {
const e34 = yC(s2);
n2.indexes.byId.set(e34, s2);
}
if (a2.byType && n2.indexes.byType) {
const e34 = n2.indexes.byType.get(r2) || [];
e34.push(s2), n2.indexes.byType.set(r2, e34);
}
if (a2.byRelation && n2.indexes.byRelation) {
const e34 = Object.entries(s2);
for (const [t3, o4] of e34)
if (t3.endsWith("_id") && t3 !== `${s2.type}_id` && typeof o4 == "string") {
const e35 = n2.indexes.byRelation.get(t3) || new Map, i4 = e35.get(o4) || [];
i4.push(s2), e35.set(o4, i4), n2.indexes.byRelation.set(t3, e35);
}
}
if (a2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in s2) {
const e34 = s2.subcircuit_id;
if (e34 && typeof e34 == "string") {
const t3 = n2.indexes.bySubcircuit.get(e34) || [];
t3.push(s2), n2.indexes.bySubcircuit.set(e34, t3);
}
}
if (a2.byCustomField && n2.indexes.byCustomField) {
for (const e34 of a2.byCustomField)
if (e34 in s2) {
const t3 = s2[e34];
if (t3 !== undefined && (typeof t3 == "string" || typeof t3 == "number")) {
const o4 = String(t3), i4 = n2.indexes.byCustomField.get(e34), r3 = i4.get(o4) || [];
r3.push(s2), i4.set(o4, r3);
}
}
}
return s2;
}, delete: (o3) => {
const i3 = t2.indexConfig || {};
let s2;
if (i3.byId && n2.indexes.byId)
s2 = n2.indexes.byId.get(`${r2}:${o3}`);
else if (i3.byType && n2.indexes.byType) {
const e34 = n2.indexes.byType.get(r2) || [];
s2 = e34.find((e35) => e35[`${r2}_id`] === o3);
} else
s2 = e33.find((e34) => e34[`${r2}_id`] === o3);
if (!s2)
return;
const a2 = e33.indexOf(s2);
if (a2 >= 0 && (e33.splice(a2, 1), n2.editCount++), i3.byId && n2.indexes.byId) {
const e34 = yC(s2);
n2.indexes.byId.delete(e34);
}
if (i3.byType && n2.indexes.byType) {
const e34 = (n2.indexes.byType.get(r2) || []).filter((e35) => e35[`${r2}_id`] !== o3);
n2.indexes.byType.set(r2, e34);
}
if (i3.byRelation && n2.indexes.byRelation)
for (const [e34, t3] of n2.indexes.byRelation.entries())
for (const [e35, n3] of t3.entries()) {
const o4 = n3.filter((e36) => e36 !== s2);
o4.length === 0 ? t3.delete(e35) : t3.set(e35, o4);
}
if (i3.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in s2) {
const e34 = s2.subcircuit_id;
if (e34) {
const t3 = (n2.indexes.bySubcircuit.get(e34) || []).filter((e35) => e35 !== s2);
t3.length === 0 ? n2.indexes.bySubcircuit.delete(e34) : n2.indexes.bySubcircuit.set(e34, t3);
}
}
if (i3.byCustomField && n2.indexes.byCustomField)
for (const e34 of n2.indexes.byCustomField.values())
for (const [t3, n3] of e34.entries()) {
const o4 = n3.filter((e35) => e35 !== s2);
o4.length === 0 ? e34.delete(t3) : e34.set(t3, o4);
}
}, update: (o3, i3) => {
const s2 = t2.indexConfig || {};
let a2;
if (s2.byId && n2.indexes.byId)
a2 = n2.indexes.byId.get(`${r2}:${o3}`);
else if (s2.byType && n2.indexes.byType) {
const e34 = n2.indexes.byType.get(r2) || [];
a2 = e34.find((e35) => e35[`${r2}_id`] === o3);
} else
a2 = e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === o3);
if (!a2)
return null;
if (s2.byRelation && n2.indexes.byRelation) {
const e34 = Object.entries(a2);
for (const [t3, o4] of e34)
if (t3.endsWith("_id") && t3 !== `${a2.type}_id` && typeof o4 == "string" && t3 in i3 && i3[t3] !== o4) {
const e35 = n2.indexes.byRelation.get(t3);
if (e35) {
const t4 = (e35.get(o4) || []).filter((e36) => e36 !== a2);
t4.length === 0 ? e35.delete(o4) : e35.set(o4, t4);
}
}
}
if (s2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in a2 && "subcircuit_id" in i3) {
const e34 = a2.subcircuit_id;
if (e34 !== i3.subcircuit_id) {
const t3 = (n2.indexes.bySubcircuit.get(e34) || []).filter((e35) => e35 !== a2);
t3.length === 0 ? n2.indexes.bySubcircuit.delete(e34) : n2.indexes.bySubcircuit.set(e34, t3);
}
}
if (s2.byCustomField && n2.indexes.byCustomField) {
for (const e34 of s2.byCustomField)
if (e34 in a2 && e34 in i3 && a2[e34] !== i3[e34]) {
const t3 = n2.indexes.byCustomField.get(e34);
if (t3) {
const n3 = String(a2[e34]), o4 = (t3.get(n3) || []).filter((e35) => e35 !== a2);
o4.length === 0 ? t3.delete(n3) : t3.set(n3, o4);
}
}
}
if (Object.assign(a2, i3), n2.editCount++, s2.byRelation && n2.indexes.byRelation) {
const e34 = Object.entries(a2);
for (const [t3, o4] of e34)
if (t3.endsWith("_id") && t3 !== `${a2.type}_id` && typeof o4 == "string" && t3 in i3) {
const e35 = n2.indexes.byRelation.get(t3) || new Map, i4 = e35.get(o4) || [];
i4.includes(a2) || (i4.push(a2), e35.set(o4, i4), n2.indexes.byRelation.set(t3, e35));
}
}
if (s2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in a2 && "subcircuit_id" in i3) {
const e34 = a2.subcircuit_id;
if (e34 && typeof e34 == "string") {
const t3 = n2.indexes.bySubcircuit.get(e34) || [];
t3.includes(a2) || (t3.push(a2), n2.indexes.bySubcircuit.set(e34, t3));
}
}
if (s2.byCustomField && n2.indexes.byCustomField) {
for (const e34 of s2.byCustomField)
if (e34 in a2 && e34 in i3) {
const t3 = a2[e34];
if (t3 !== undefined && (typeof t3 == "string" || typeof t3 == "number")) {
const o4 = String(t3), i4 = n2.indexes.byCustomField.get(e34), r3 = i4.get(o4) || [];
r3.includes(a2) || (r3.push(a2), i4.set(o4, r3));
}
}
}
return a2;
}, select: (t3) => {
if (r2 === "source_component")
return e33.find((e34) => e34.type === "source_component" && e34.name === t3.replace(/\./g, "")) || null;
if (r2 === "pcb_port" || r2 === "source_port" || r2 === "schematic_port") {
const [n3, o3] = t3.replace(/\./g, "").split(/[\s\>]+/), i3 = e33.find((e34) => e34.type === "source_component" && e34.name === n3);
if (!i3)
return null;
const s2 = e33.find((e34) => e34.type === "source_port" && e34.source_component_id === i3.source_component_id && (e34.name === o3 || (e34.port_hints ?? []).includes(o3)));
if (!s2)
return null;
if (r2 === "source_port")
return s2;
if (r2 === "pcb_port")
return e33.find((e34) => e34.type === "pcb_port" && e34.source_port_id === s2.source_port_id) || null;
if (r2 === "schematic_port")
return e33.find((e34) => e34.type === "schematic_port" && e34.source_port_id === s2.source_port_id) || null;
}
return null;
} };
} });
};
bC.unparsed = bC;
var xC = (e33) => e33[`${e33.type}_id`];
var vC = (e33, t2) => {
const n2 = fC(e33).pcb_port.get(t2);
if (!n2)
return `pcb_port[#${t2}]`;
const o2 = n2.pcb_component_id ? fC(e33).pcb_component.get(n2.pcb_component_id) : undefined;
if (!o2)
return `pcb_port[#${t2}]`;
const i2 = fC(e33).source_component.get(o2.source_component_id);
if (!i2)
return `pcb_port[#${t2}]`;
const r2 = fC(e33).source_port.get(n2.source_port_id);
if (!r2)
return `pcb_port[#${t2}]`;
let s2;
return s2 = r2?.port_hints && r2.port_hints.length > 0 || r2.port_hints && r2.port_hints.length > 0 ? r2.port_hints[0] : t2, `pcb_port[.${i2.name} > .${s2}]`;
};
function IC(e33, t2) {
const n2 = fC(e33).pcb_trace.get(t2);
if (!n2)
return `trace[${t2}]`;
const o2 = n2.route.flatMap((e34) => [e34.start_pcb_port_id, e34.end_pcb_port_id]).filter(Boolean);
if (o2.length === 0)
return `trace[${t2}]`;
return `trace[${o2.map((t3) => {
const n3 = function(t4) {
const n4 = fC(e33).pcb_port.get(t4);
if (!n4)
return null;
const o3 = n4.pcb_component_id ? fC(e33).pcb_component.get(n4.pcb_component_id) : undefined;
if (!o3)
return null;
const i2 = fC(e33).source_component.get(o3.source_component_id);
if (!i2)
return null;
const r2 = fC(e33).source_port.get(n4.source_port_id), s2 = r2?.port_hints ? r2.port_hints[1] : "";
return { componentName: i2.name, portHint: s2 };
}(t3);
return n3 ? `.${n3.componentName} > port.${n3.portHint}` : `port[${t3}]`;
}).join(", ")}]`;
}
var SC = (e33, t2) => {
if (typeof t2 == "string") {
const n2 = ((e34, t3) => e34.find((e35) => xC(e35) === t3) ?? null)(e33, t2);
return SC(e33, n2);
}
switch (t2.type) {
case "pcb_port":
return vC(e33, t2.pcb_port_id);
case "pcb_smtpad":
return function(e34, t3) {
const n2 = fC(e34).pcb_smtpad.get(t3);
return n2 && n2.pcb_port_id ? vC(e34, n2.pcb_port_id) : `smtpad[${t3}]`;
}(e33, t2.pcb_smtpad_id);
case "pcb_trace":
return IC(e33, t2.pcb_trace_id);
case "source_component":
return `source_component[${t2.name}]`;
default:
return `${t2.type}[#${xC(t2)}]`;
}
};
var CC = (e33, t2) => ({ minX: Math.min(e33.minX, t2.minX), minY: Math.min(e33.minY, t2.minY), maxX: Math.max(e33.maxX, t2.maxX), maxY: Math.max(e33.maxY, t2.maxY) });
var PC = (e33, t2, n2) => {
const o2 = n2 / 2;
return { minX: e33 - o2, minY: t2 - o2, maxX: e33 + o2, maxY: t2 + o2 };
};
var MC = (e33, t2, n2, o2, i2) => {
const r2 = n2 / 2, s2 = o2 / 2, a2 = i2 * Math.PI / 180, c2 = Math.cos(a2), l2 = Math.sin(a2), h2 = [{ x: -r2, y: -s2 }, { x: r2, y: -s2 }, { x: r2, y: s2 }, { x: -r2, y: s2 }].map((n3) => ({ x: e33 + n3.x * c2 - n3.y * l2, y: t2 + n3.x * l2 + n3.y * c2 }));
return { minX: Math.min(...h2.map((e34) => e34.x)), minY: Math.min(...h2.map((e34) => e34.y)), maxX: Math.max(...h2.map((e34) => e34.x)), maxY: Math.max(...h2.map((e34) => e34.y)) };
};
var wC = (e33, t2, n2, o2, i2) => {
const r2 = n2 / 2, s2 = o2 / 2, a2 = i2 * Math.PI / 180, c2 = Math.cos(a2), l2 = Math.sin(a2), h2 = Math.hypot(r2 * c2, s2 * l2), d2 = Math.hypot(r2 * l2, s2 * c2);
return { minX: e33 - h2, minY: t2 - d2, maxX: e33 + h2, maxY: t2 + d2 };
};
var NC = (e33, t2, n2, o2, i2) => {
const r2 = Math.min(n2, o2) / 2, s2 = Math.max(n2, o2) / 2 - r2, a2 = i2 * Math.PI / 180, c2 = n2 >= o2 ? { x: s2, y: 0 } : { x: 0, y: s2 }, l2 = { x: c2.x * Math.cos(a2) - c2.y * Math.sin(a2), y: c2.x * Math.sin(a2) + c2.y * Math.cos(a2) }, h2 = Math.abs(l2.x) + r2, d2 = Math.abs(l2.y) + r2;
return { minX: e33 - h2, minY: t2 - d2, maxX: e33 + h2, maxY: t2 + d2 };
};
var TC = (e33) => e33.length === 0 ? null : { minX: Math.min(...e33.map((e34) => e34.x)), minY: Math.min(...e33.map((e34) => e34.y)), maxX: Math.max(...e33.map((e34) => e34.x)), maxY: Math.max(...e33.map((e34) => e34.y)) };
var RC = (e33) => Array.isArray(e33) ? e33.flatMap((e34) => {
if (!e34 || typeof e34 != "object")
return [];
if ("x" in e34 && "y" in e34 && typeof e34.x == "number" && typeof e34.y == "number")
return [{ x: e34.x, y: e34.y }];
if ("start" in e34 && "end" in e34) {
return [e34.start, e34.end].filter((e35) => Boolean(e35 && typeof e35 == "object" && "x" in e35 && "y" in e35 && typeof e35.x == "number" && typeof e35.y == "number"));
}
return [];
}) : [];
var EC = (e33) => {
if (!e33.type.startsWith("pcb_"))
return null;
if (e33.type === "pcb_smtpad" && e33.shape === "polygon" && Array.isArray(e33.points))
return TC(e33.points);
if (e33.type === "pcb_hole" && e33.hole_shape === "circle")
return PC(e33.x, e33.y, e33.hole_diameter);
if (e33.type === "pcb_plated_hole") {
let t3;
if ("outer_diameter" in e33 && typeof e33.outer_diameter == "number" ? t3 = PC(e33.x, e33.y, e33.outer_diameter) : ("hole_diameter" in e33) && typeof e33.hole_diameter == "number" && (t3 = PC(e33.x, e33.y, e33.hole_diameter)), (e33.shape === "oval" || e33.shape === "pill") && typeof e33.outer_width == "number" && typeof e33.outer_height == "number") {
t3 = (e33.shape === "pill" ? NC : wC)(e33.x, e33.y, e33.outer_width, e33.outer_height, e33.ccw_rotation ?? 0);
}
if ("rect_pad_width" in e33 && typeof e33.rect_pad_width == "number" && "rect_pad_height" in e33 && typeof e33.rect_pad_height == "number") {
const n3 = MC(e33.x, e33.y, e33.rect_pad_width, e33.rect_pad_height, "rect_ccw_rotation" in e33 ? e33.rect_ccw_rotation ?? 0 : 0);
t3 = t3 ? CC(t3, n3) : n3;
}
if ("hole_diameter" in e33 && typeof e33.hole_diameter == "number") {
const n3 = PC(e33.x + ("hole_offset_x" in e33 ? e33.hole_offset_x ?? 0 : 0), e33.y + ("hole_offset_y" in e33 ? e33.hole_offset_y ?? 0 : 0), e33.hole_diameter);
t3 = t3 ? CC(t3, n3) : n3;
}
if (t3)
return t3;
}
const t2 = e33, n2 = TC(RC(t2.route));
if (n2)
return n2;
const o2 = TC(RC(t2.outline));
if (o2)
return o2;
const i2 = TC(RC(t2.points));
if (i2)
return i2;
let r2, s2, a2, c2;
"x" in e33 && "y" in e33 && (r2 = Number(e33.x), s2 = Number(e33.y)), "outer_diameter" in e33 && (a2 = Number(e33.outer_diameter), c2 = Number(e33.outer_diameter)), "width" in e33 && (a2 = Number(e33.width)), "height" in e33 && (c2 = Number(e33.height)), "center" in e33 && e33.center && typeof e33.center == "object" && "x" in e33.center && "y" in e33.center && (r2 = Number(e33.center.x), s2 = Number(e33.center.y));
let l2 = 0;
if ("rotation" in e33 && typeof e33.rotation == "number" && (l2 = e33.rotation), "ccw_rotation" in e33 && typeof e33.ccw_rotation == "number" && (l2 = e33.ccw_rotation), r2 !== undefined && s2 !== undefined)
return a2 !== undefined && c2 !== undefined ? l2 ? MC(r2, s2, a2, c2, l2) : { minX: r2 - a2 / 2, minY: s2 - c2 / 2, maxX: r2 + a2 / 2, maxY: s2 + c2 / 2 } : ("radius" in e33) && typeof e33.radius == "number" ? PC(r2, s2, 2 * e33.radius) : { minX: r2, minY: s2, maxX: r2, maxY: s2 };
const h2 = [t2.anchor_position, t2.position].filter((e34) => Boolean(e34 && typeof e34 == "object" && "x" in e34 && "y" in e34 && typeof e34.x == "number" && typeof e34.y == "number")).at(0);
return h2 ? { minX: h2.x, minY: h2.y, maxX: h2.x, maxY: h2.y } : null;
};
var AC = (e33) => {
let t2 = { minX: Number.POSITIVE_INFINITY, minY: Number.POSITIVE_INFINITY, maxX: Number.NEGATIVE_INFINITY, maxY: Number.NEGATIVE_INFINITY };
for (const n2 of e33) {
const e34 = EC(n2);
e34 && (t2 = CC(t2, e34));
}
return t2;
};
var OC = (e33) => e33[`${e33.type}_id`];
var kC = 0.000000001;
var DC = (e33, t2, n2) => {
const o2 = n2.x - t2.x, i2 = n2.y - t2.y, r2 = o2 * o2 + i2 * i2;
if (r2 <= kC)
return ((e34, t3) => Math.hypot(e34.x - t3.x, e34.y - t3.y))(e33, t2);
const s2 = (a2 = ((e33.x - t2.x) * o2 + (e33.y - t2.y) * i2) / r2, c2 = 0, l2 = 1, Math.max(c2, Math.min(l2, a2)));
var a2, c2, l2;
return Math.hypot(e33.x - (t2.x + s2 * o2), e33.y - (t2.y + s2 * i2));
};
var LC = (e33, t2, n2) => (t2.x - e33.x) * (n2.y - e33.y) - (t2.y - e33.y) * (n2.x - e33.x);
var zC = (e33, t2, n2) => !(Math.abs(LC(t2, n2, e33)) > kC) && (e33.x >= Math.min(t2.x, n2.x) - kC && e33.x <= Math.max(t2.x, n2.x) + kC && e33.y >= Math.min(t2.y, n2.y) - kC && e33.y <= Math.max(t2.y, n2.y) + kC);
var BC = (e33, t2, n2, o2) => {
const i2 = LC(e33, t2, n2), r2 = LC(e33, t2, o2), s2 = LC(n2, o2, e33), a2 = LC(n2, o2, t2);
return (i2 > kC && r2 < -1e-9 || i2 < -1e-9 && r2 > kC) && (s2 > kC && a2 < -1e-9 || s2 < -1e-9 && a2 > kC) || (zC(n2, e33, t2) || zC(o2, e33, t2) || zC(e33, n2, o2) || zC(t2, n2, o2));
};
var FC = (e33) => {
const t2 = [];
if (e33.points.length < 2)
return t2;
for (let n2 = 0;n2 < e33.points.length; n2 += 1) {
const o2 = e33.points[n2], i2 = e33.points[(n2 + 1) % e33.points.length];
o2 && i2 && t2.push([o2, i2]);
}
return t2;
};
var jC = (e33, t2) => {
for (const [n3, o2] of FC(t2))
if (zC(e33, n3, o2))
return true;
let n2 = false;
for (let o2 = 0, i2 = t2.points.length - 1;o2 < t2.points.length; i2 = o2++) {
const r2 = t2.points[o2], s2 = t2.points[i2];
if (!r2 || !s2)
continue;
r2.y > e33.y != s2.y > e33.y && e33.x < (s2.x - r2.x) * (e33.y - r2.y) / (s2.y - r2.y) + r2.x && (n2 = !n2);
}
return n2;
};
var $C = (e33, t2) => {
if (t2.points.length < 3)
return Number.POSITIVE_INFINITY;
if (jC({ x: e33.x, y: e33.y }, t2))
return 0;
let n2 = Number.POSITIVE_INFINITY;
for (const [o2, i2] of FC(t2))
n2 = Math.min(n2, DC({ x: e33.x, y: e33.y }, o2, i2));
return Math.max(0, n2 - e33.radius);
};
var YC = ((e33, t2, n2 = 0) => {
const { a: o2, b: i2, c: r2, d: s2, e: a2, f: c2 } = L(k(t2.x, t2.y), j(n2 * Math.PI / 180));
return e33.transform(new kf(o2, i2, r2, s2, a2, c2));
});
var XC = (e33) => e33.orientation() === Ym.CCW ? e33 : e33.reverse();
var WC = (e33, t2) => XC(new Kf(new Zf(new $f(e33.x, e33.y), t2)));
var VC = (e33) => {
const t2 = [];
for (let n2 = 0;n2 < e33.vertices.length; n2++) {
const o2 = e33.vertices[n2], i2 = e33.vertices[(n2 + 1) % e33.vertices.length], r2 = i2.x - o2.x, s2 = i2.y - o2.y;
if (r2 === 0 && s2 === 0)
continue;
const a2 = o2.bulge ?? 0;
if (a2 === 0)
t2.push(new Vf(new $f(o2.x, o2.y), new $f(i2.x, i2.y)));
else {
const e34 = (1 - a2 * a2) / (4 * a2), n3 = new $f((o2.x + i2.x) / 2 - s2 * e34, (o2.y + i2.y) / 2 + r2 * e34);
t2.push(new qf(n3, Math.hypot(r2, s2) * (1 + a2 * a2) / (4 * Math.abs(a2)), Math.atan2(o2.y - n3.y, o2.x - n3.x), Math.atan2(i2.y - n3.y, i2.x - n3.x), a2 > 0));
}
}
return XC(new Kf(t2));
};
var HC = (e33, t2) => {
for (const n2 of t2.reverse().faces)
e33.addFace(n2.shapes);
return e33;
};
var GC = (e33) => {
if (e33.shape === "rect")
return ((e34, t3, n2, o2 = 0, i2 = 0) => {
const r2 = t3 / 2, s2 = n2 / 2, a2 = Math.max(0, Math.min(o2, r2, s2));
if (a2 === 0)
return YC(XC(new Kf(new Jf(-r2, -s2, r2, s2))), e34, i2);
const c2 = [new qf(new $f(r2 - a2, -s2 + a2), a2, -Math.PI / 2, 0, true), new qf(new $f(r2 - a2, s2 - a2), a2, 0, Math.PI / 2, true), new qf(new $f(-r2 + a2, s2 - a2), a2, Math.PI / 2, Math.PI, true), new qf(new $f(-r2 + a2, -s2 + a2), a2, Math.PI, 1.5 * Math.PI, true)], l2 = [];
for (let e35 = 0;e35 < c2.length; e35++) {
const t4 = c2[e35], n3 = c2[(e35 + 1) % c2.length];
l2.push(t4), t4.end.distanceTo(n3.start)[0] > 0.000000000001 && l2.push(new Vf(t4.end, n3.start));
}
return YC(XC(new Kf(l2)), e34, i2);
})(e33.center, e33.width, e33.height, 0, e33.rotation);
if (e33.shape === "polygon")
return XC(new Kf(e33.points.map((e34) => new $f(e34.x, e34.y))));
const t2 = VC(e33.brep_shape.outer_ring);
for (const n2 of e33.brep_shape.inner_rings)
HC(t2, VC(n2));
return t2;
};
var UC = (e33, t2, n2, o2 = n2) => {
const i2 = Math.hypot(t2.x - e33.x, t2.y - e33.y), r2 = n2 / 2, s2 = o2 / 2;
if (i2 <= Math.abs(s2 - r2))
return WC(r2 >= s2 ? e33 : t2, Math.max(r2, s2));
const a2 = Math.atan2(t2.y - e33.y, t2.x - e33.x), c2 = Math.acos((r2 - s2) / i2), l2 = new qf(new $f(e33.x, e33.y), r2, a2 + c2, a2 - c2, true), h2 = new qf(new $f(t2.x, t2.y), s2, a2 - c2, a2 + c2, true);
return XC(new Kf([l2, new Vf(l2.end, h2.start), h2, new Vf(h2.end, l2.start)]));
};
var ZC = (e33, t2) => {
const n2 = t2 * Math.PI / 180;
return { x: e33.x * Math.cos(n2) - e33.y * Math.sin(n2), y: e33.x * Math.sin(n2) + e33.y * Math.cos(n2) };
};
var qC = ({ x: e33, y: t2, width: n2, height: o2, ccwRotation: i2 }) => {
const r2 = n2 / 2, s2 = o2 / 2;
return [{ x: -r2, y: -s2 }, { x: r2, y: -s2 }, { x: r2, y: s2 }, { x: -r2, y: s2 }].map((n3) => {
const o3 = ZC(n3, i2);
return { x: e33 + o3.x, y: t2 + o3.y };
});
};
var JC = (e33) => {
let t2, n2, o2, i2 = 0;
e33.type === "pcb_hole" ? (t2 = e33.hole_width, n2 = e33.hole_height, o2 = Math.min(t2, n2) / 2, e33.hole_shape === "rotated_pill" && (i2 = e33.ccw_rotation)) : e33.type === "pcb_plated_hole" ? (t2 = e33.outer_width, n2 = e33.outer_height, o2 = Math.min(t2, n2) / 2, i2 = e33.ccw_rotation) : (t2 = e33.width, n2 = e33.height, o2 = e33.radius, e33.shape === "rotated_pill" && (i2 = e33.ccw_rotation));
const r2 = Math.max(Math.max(t2, n2) / 2 - o2, 0), s2 = ZC(t2 >= n2 ? { x: r2, y: 0 } : { x: 0, y: r2 }, i2);
return { start: { x: e33.x - s2.x, y: e33.y - s2.y }, end: { x: e33.x + s2.x, y: e33.y + s2.y }, radius: o2 };
};
var QC = (e33) => {
if (e33.type === "pcb_smtpad") {
if (e33.shape === "polygon")
return e33.points;
if (e33.shape === "rotated_rect")
return qC({ x: e33.x, y: e33.y, width: e33.width, height: e33.height, ccwRotation: e33.ccw_rotation });
}
if (e33.type === "pcb_plated_hole" && "rect_pad_width" in e33 && "rect_pad_height" in e33)
return qC({ x: e33.x, y: e33.y, width: e33.rect_pad_width, height: e33.rect_pad_height, ccwRotation: "rect_ccw_rotation" in e33 && typeof e33.rect_ccw_rotation == "number" ? e33.rect_ccw_rotation : 0 });
throw new Error(`Expected polygonal pad geometry, got ${e33.type} with shape "${e33.shape}"`);
};
var KC = (e33) => e33.map((t2, n2) => [t2, e33[(n2 + 1) % e33.length]]);
var eP = (e33, t2, n2, o2) => {
const i2 = It(e33, t2, n2, o2);
if (i2)
return { distance: 0, pointOnA: i2, pointOnB: i2, center: i2 };
const r2 = [{ pointOnA: e33, pointOnB: Bt(e33, n2, o2) }, { pointOnA: t2, pointOnB: Bt(t2, n2, o2) }, { pointOnA: Bt(n2, e33, t2), pointOnB: n2 }, { pointOnA: Bt(o2, e33, t2), pointOnB: o2 }];
let s2 = r2[0], a2 = Xt(s2.pointOnA, s2.pointOnB);
for (const e34 of r2.slice(1)) {
const t3 = Xt(e34.pointOnA, e34.pointOnB);
t3 < a2 && (s2 = e34, a2 = t3);
}
return { distance: kt(e33, t2, n2, o2), pointOnA: s2.pointOnA, pointOnB: s2.pointOnB, center: { x: (s2.pointOnA.x + s2.pointOnB.x) / 2, y: (s2.pointOnA.y + s2.pointOnB.y) / 2 } };
};
var tP = (e33, t2, n2) => {
if (n2.length < 3)
return { distance: Number.POSITIVE_INFINITY, center: e33, tracePoint: e33, obstaclePoint: e33 };
const o2 = KC(n2).map(([n3, o3]) => It(e33, t2, n3, o3)).filter((e34) => e34 !== null);
if (o2.length > 0) {
const n3 = t2.x - e33.x, i3 = t2.y - e33.y, r2 = n3 * n3 + i3 * i3;
return o2.sort((t3, o3) => ((t3.x - e33.x) * n3 + (t3.y - e33.y) * i3) / r2 - ((o3.x - e33.x) * n3 + (o3.y - e33.y) * i3) / r2), { distance: 0, center: o2[0], tracePoint: o2[0], obstaclePoint: o2[0] };
}
if (Nt(e33, n2) || Nt(t2, n2)) {
const n3 = { x: (e33.x + t2.x) / 2, y: (e33.y + t2.y) / 2 };
return { distance: 0, center: n3, tracePoint: n3, obstaclePoint: n3 };
}
let i2 = eP(e33, t2, n2[0], n2[1]);
for (const [o3, r2] of KC(n2).slice(1)) {
const n3 = eP(e33, t2, o3, r2);
n3.distance < i2.distance && (i2 = n3);
}
return { distance: i2.distance, center: i2.center, tracePoint: i2.pointOnA, obstaclePoint: i2.pointOnB };
};
function nP(e33, t2) {
return Math.sqrt((t2.x - e33.x) ** 2 + (t2.y - e33.y) ** 2);
}
var oP = 0.000000001;
var iP = 0.000000001;
function rP(e33, t2) {
const n2 = (e33.y - t2.start.y) * (t2.end.x - t2.start.x) - (e33.x - t2.start.x) * (t2.end.y - t2.start.y);
if (Math.abs(n2) > oP)
return false;
const o2 = (e33.x - t2.start.x) * (t2.end.x - t2.start.x) + (e33.y - t2.start.y) * (t2.end.y - t2.start.y);
if (o2 < -1e-9)
return false;
return o2 <= (t2.end.x - t2.start.x) ** 2 + (t2.end.y - t2.start.y) ** 2 + oP;
}
function sP(e33, t2) {
let n2 = false;
for (let o2 = 0, i2 = t2.length - 1;o2 < t2.length; i2 = o2++) {
const r2 = t2[o2], s2 = t2[i2];
if (rP(e33, { start: r2, end: s2 }))
return true;
r2.y > e33.y != s2.y > e33.y && e33.x < (s2.x - r2.x) * (e33.y - r2.y) / (s2.y - r2.y) + r2.x && (n2 = !n2);
}
return n2;
}
function aP(e33, t2) {
if (t2.type === "pcb_smtpad") {
if (t2.shape === "circle")
return nP(e33, t2) <= t2.radius + iP;
if (t2.shape === "rect") {
const n2 = t2.width / 2, o2 = t2.height / 2;
return Math.abs(e33.x - t2.x) <= n2 + iP && Math.abs(e33.y - t2.y) <= o2 + iP;
}
if (t2.shape === "rotated_rect")
return sP(e33, QC(t2));
if (t2.shape === "pill" || t2.shape === "rotated_pill") {
if (t2.shape === "rotated_pill") {
const n3 = JC(t2);
return xt(e33, n3.start, n3.end) <= n3.radius + iP;
}
const n2 = t2.width / 2, o2 = t2.height / 2, i2 = t2.radius;
if (Math.abs(e33.x - t2.x) <= n2 - i2 + iP && Math.abs(e33.y - t2.y) <= o2 + iP)
return true;
const r2 = Math.max(Math.abs(e33.x - t2.x) - (n2 - i2), 0), s2 = Math.max(Math.abs(e33.y - t2.y) - (o2 - i2), 0), a2 = i2 + iP;
return r2 * r2 + s2 * s2 <= a2 * a2;
}
if (t2.shape === "polygon")
return sP(e33, t2.points);
}
if (t2.type === "pcb_plated_hole") {
if (t2.shape === "circle")
return nP(e33, t2) <= t2.outer_diameter / 2 + iP;
if ("rect_pad_width" in t2 && "rect_pad_height" in t2)
return sP(e33, QC(t2));
if (t2.shape === "oval" || t2.shape === "pill")
return Math.abs(e33.x - t2.x) <= t2.outer_width / 2 + iP && Math.abs(e33.y - t2.y) <= t2.outer_height / 2 + iP;
}
return false;
}
function cP(e33) {
return e33.type === "pcb_trace_segment" || e33.type === "pcb_smtpad" ? [e33.layer] : e33.type === "pcb_plated_hole" ? Array.isArray(e33.layers) ? e33.layers : [...Yb] : e33.type === "pcb_hole" ? [...Yb] : e33.type === "pcb_via" ? Array.isArray(e33.layers) ? e33.layers : [...Yb] : e33.type === "pcb_keepout" && Array.isArray(e33.layers) ? e33.layers : [];
}
var lP = 0.1;
var hP = 0.2;
var dP = 0.1;
var uP = 0.1;
var pP = 0.2;
var mP = 0.1;
var gP = 0.005;
var fP = (e33) => e33.find((e34) => e34.type === "pcb_board");
var _P = (e33, t2) => e33?.[t2];
var yP = (e33) => e33.type === "pcb_keepout" ? e33.shape === "outline" ? { minX: Math.min(...e33.outline.map((e34) => e34.x)), minY: Math.min(...e33.outline.map((e34) => e34.y)), maxX: Math.max(...e33.outline.map((e34) => e34.x)), maxY: Math.max(...e33.outline.map((e34) => e34.y)) } : e33.shape === "circle" ? { minX: e33.center.x - e33.radius, minY: e33.center.y - e33.radius, maxX: e33.center.x + e33.radius, maxY: e33.center.y + e33.radius } : { minX: e33.center.x - e33.width / 2, minY: e33.center.y - e33.height / 2, maxX: e33.center.x + e33.width / 2, maxY: e33.center.y + e33.height / 2 } : AC([e33]);
var bP = (e33) => {
if (e33.type === "pcb_keepout" && e33.shape === "circle")
return e33.radius;
const t2 = yP(e33);
return Math.min(t2.maxX - t2.minX, t2.maxY - t2.minY) / 2;
};
var xP = (e33) => e33.type === "pcb_via" || e33.shape === "circle";
var vP = (e33) => e33.type === "pcb_smtpad" && (e33.shape === "pill" || e33.shape === "rotated_pill") || e33.type === "pcb_plated_hole" && (e33.shape === "oval" || e33.shape === "pill");
var IP = (e33) => {
const t2 = ((e34) => {
if (e34.type === "pcb_keepout" && e34.shape !== "outline")
return e34.center;
const t3 = yP(e34);
return Yt({ x: t3.minX, y: t3.minY }, { x: t3.maxX, y: t3.maxY });
})(e33);
return { kind: "circle", x: t2.x, y: t2.y, radius: bP(e33) };
};
var SP = (e33) => {
if (e33.type === "pcb_keepout") {
if (e33.shape === "outline")
return { kind: "polygon", points: e33.outline };
if (e33.shape !== "rect")
throw new Error(`Expected rectangular keepout, got ${e33.shape}`);
return { kind: "polygon", points: [{ x: e33.center.x - e33.width / 2, y: e33.center.y - e33.height / 2 }, { x: e33.center.x + e33.width / 2, y: e33.center.y - e33.height / 2 }, { x: e33.center.x + e33.width / 2, y: e33.center.y + e33.height / 2 }, { x: e33.center.x - e33.width / 2, y: e33.center.y + e33.height / 2 }] };
}
if (e33.type === "pcb_smtpad" && (e33.shape === "polygon" || e33.shape === "rotated_rect"))
return { kind: "polygon", points: QC(e33) };
if (e33.type === "pcb_plated_hole" && "rect_pad_width" in e33 && "rect_pad_height" in e33)
return { kind: "polygon", points: QC(e33) };
const t2 = yP(e33);
return { kind: "polygon", points: [{ x: t2.minX, y: t2.minY }, { x: t2.maxX, y: t2.minY }, { x: t2.maxX, y: t2.maxY }, { x: t2.minX, y: t2.maxY }] };
};
var CP = (e33) => {
if (e33.type !== "pcb_smtpad" || e33.shape !== "rect" && e33.shape !== "rotated_rect" || !e33.corner_radius || e33.corner_radius <= 0)
return null;
const t2 = Math.min(e33.corner_radius, e33.width / 2, e33.height / 2);
if (t2 === Math.min(e33.width, e33.height) / 2) {
return { core: { ...e33, shape: "rotated_pill", radius: t2, ccw_rotation: e33.shape === "rotated_rect" ? e33.ccw_rotation : 0 }, radius: 0 };
}
return { core: { ...e33, width: e33.width - 2 * t2, height: e33.height - 2 * t2, corner_radius: 0 }, radius: t2 };
};
var PP = (e33, t2) => {
const n2 = CP(e33), o2 = CP(t2);
if (n2 || o2)
return PP(n2?.core ?? e33, o2?.core ?? t2) - (n2?.radius ?? 0) - (o2?.radius ?? 0);
if (vP(e33) && vP(t2)) {
const n3 = JC(e33), o3 = JC(t2);
return kt(n3.start, n3.end, o3.start, o3.end) - n3.radius - o3.radius;
}
if (vP(e33) && xP(t2)) {
const n3 = JC(e33);
return zt(n3.start, n3.end, IP(t2)) - n3.radius;
}
if (xP(e33) && vP(t2)) {
const n3 = JC(t2);
return zt(n3.start, n3.end, IP(e33)) - n3.radius;
}
if (vP(e33)) {
const n3 = JC(e33);
return tP(n3.start, n3.end, SP(t2).points).distance - n3.radius;
}
if (vP(t2)) {
const n3 = JC(t2);
return tP(n3.start, n3.end, SP(e33).points).distance - n3.radius;
}
return xP(e33) && xP(t2) ? (i2 = IP(e33), r2 = IP(t2), Math.max(0, Math.hypot(i2.x - r2.x, i2.y - r2.y) - i2.radius - r2.radius)) : xP(e33) ? $C(IP(e33), SP(t2)) : xP(t2) ? $C(IP(t2), SP(e33)) : ((e34, t3) => {
if (e34.points.length < 3 || t3.points.length < 3)
return Number.POSITIVE_INFINITY;
for (const [n4, o4] of FC(e34))
for (const [e35, i4] of FC(t3))
if (BC(n4, o4, e35, i4))
return 0;
const n3 = e34.points[0], o3 = t3.points[0];
if (n3 && jC(n3, t3) || o3 && jC(o3, e34))
return 0;
let i3 = Number.POSITIVE_INFINITY;
for (const [n4, o4] of FC(e34))
for (const [e35, r3] of FC(t3))
i3 = Math.min(i3, DC(n4, e35, r3), DC(o4, e35, r3), DC(e35, n4, o4), DC(r3, n4, o4));
return i3;
})(SP(e33), SP(t2));
var i2, r2;
};
var MP = (e33) => [..._C(e33).pcb_smtpad.list(), ..._C(e33).pcb_plated_hole.list()];
var wP = (e33) => _C(e33).pcb_trace.list().flatMap((e34) => {
const t2 = [];
for (let n2 = 0;n2 < e34.route.length - 1; n2++) {
const o2 = e34.route[n2], i2 = e34.route[n2 + 1];
o2.route_type === "wire" && (i2.route_type === "wire" && o2.layer === i2.layer && t2.push({ type: "pcb_trace_segment", pcb_trace_id: e34.pcb_trace_id, _pcbTrace: e34, thickness: "width" in o2 ? o2.width : ("width" in i2) ? i2.width : mP, layer: o2.layer, x1: o2.x, y1: o2.y, x2: i2.x, y2: i2.y }));
}
return t2;
});
var NP = ({ tracePoint: e33, obstaclePoint: t2, traceRadius: n2, obstacleRadius: o2 }) => {
const i2 = t2.x - e33.x, r2 = t2.y - e33.y, s2 = Math.hypot(i2, r2);
if (s2 === 0)
return Yt(e33, t2);
const a2 = i2 / s2, c2 = r2 / s2;
if (s2 <= n2 + o2) {
const t3 = (Math.max(-n2, s2 - o2) + Math.min(n2, s2 + o2)) / 2;
return { x: e33.x + a2 * t3, y: e33.y + c2 * t3 };
}
return Yt({ x: e33.x + a2 * n2, y: e33.y + c2 * n2 }, { x: t2.x - a2 * o2, y: t2.y - c2 * o2 });
};
var TP = (e33, t2) => {
const n2 = CP(t2);
n2 && (t2 = n2.core);
const o2 = n2?.radius ?? 0, i2 = { x: e33.x1, y: e33.y1 }, r2 = { x: e33.x2, y: e33.y2 }, s2 = e33.thickness / 2;
if (t2.type === "pcb_via" || xP(t2)) {
const e34 = t2.type === "pcb_via" ? { x: t2.x, y: t2.y, radius: t2.outer_diameter / 2 } : IP(t2), n3 = Bt(e34, i2, r2);
return { gap: zt(i2, r2, e34) - s2, center: NP({ tracePoint: n3, obstaclePoint: e34, traceRadius: s2, obstacleRadius: e34.radius }) };
}
if (vP(t2)) {
const n3 = ((e34, t3) => {
const n4 = JC(t3), o3 = eP({ x: e34.x1, y: e34.y1 }, { x: e34.x2, y: e34.y2 }, n4.start, n4.end);
return { distance: o3.distance, center: o3.center, radius: n4.radius, tracePoint: o3.pointOnA, obstaclePoint: o3.pointOnB };
})(e33, t2);
return { gap: n3.distance - s2 - n3.radius, center: NP({ tracePoint: n3.tracePoint, obstaclePoint: n3.obstaclePoint, traceRadius: s2, obstacleRadius: n3.radius }) };
}
const a2 = tP(i2, r2, SP(t2).points);
return { gap: a2.distance - s2 - o2, center: NP({ tracePoint: a2.tracePoint, obstaclePoint: a2.obstaclePoint, traceRadius: s2, obstacleRadius: o2 }) };
};
var RP = (e33) => e33 <= 0;
var EP = (e33, t2) => {
const n2 = { x: e33.x1, y: e33.y1 }, o2 = { x: e33.x2, y: e33.y2 }, i2 = { x: t2.x1, y: t2.y1 }, r2 = { x: t2.x2, y: t2.y2 }, s2 = { x: o2.x - n2.x, y: o2.y - n2.y }, a2 = { x: r2.x - i2.x, y: r2.y - i2.y }, c2 = s2.x * s2.x + s2.y * s2.y, l2 = a2.x * a2.x + a2.y * a2.y;
if (c2 === 0 || l2 === 0) {
if (c2 === 0 && l2 === 0)
return { x: (n2.x + i2.x) / 2, y: (n2.y + i2.y) / 2 };
if (c2 === 0) {
const e35 = OP(((n2.x - i2.x) * a2.x + (n2.y - i2.y) * a2.y) / l2, 0, 1), t4 = { x: i2.x + e35 * a2.x, y: i2.y + e35 * a2.y };
return { x: (n2.x + t4.x) / 2, y: (n2.y + t4.y) / 2 };
}
const e34 = OP(((i2.x - n2.x) * s2.x + (i2.y - n2.y) * s2.y) / c2, 0, 1), t3 = { x: n2.x + e34 * s2.x, y: n2.y + e34 * s2.y };
return { x: (t3.x + i2.x) / 2, y: (t3.y + i2.y) / 2 };
}
const h2 = n2.x - i2.x, d2 = n2.y - i2.y, u2 = s2.x * s2.x + s2.y * s2.y, p2 = s2.x * a2.x + s2.y * a2.y, m2 = s2.x * h2 + s2.y * d2, g2 = a2.x * a2.x + a2.y * a2.y, f2 = a2.x * h2 + a2.y * d2, _2 = u2 * g2 - p2 * p2;
if (_2 < 0.0000000001)
return AP(n2, o2, i2, r2, s2, a2, c2, l2);
let y2 = (p2 * f2 - g2 * m2) / _2, b2 = (u2 * f2 - p2 * m2) / _2;
y2 = OP(y2, 0, 1), b2 = OP(b2, 0, 1), b2 = (y2 * p2 + f2) / g2, b2 = OP(b2, 0, 1), y2 = (b2 * p2 - m2) / u2, y2 = OP(y2, 0, 1);
const x2 = n2.x + y2 * s2.x, v2 = n2.y + y2 * s2.y, I2 = i2.x + b2 * a2.x, S2 = i2.y + b2 * a2.y;
return { x: (x2 + I2) / 2, y: (v2 + S2) / 2 };
};
var AP = (e33, t2, n2, o2, i2, r2, s2, a2) => {
let c2 = ((n2.x - e33.x) * i2.x + (n2.y - e33.y) * i2.y) / s2;
c2 = OP(c2, 0, 1);
const l2 = { x: e33.x + c2 * i2.x, y: e33.y + c2 * i2.y };
let h2 = ((o2.x - e33.x) * i2.x + (o2.y - e33.y) * i2.y) / s2;
h2 = OP(h2, 0, 1);
const d2 = { x: e33.x + h2 * i2.x, y: e33.y + h2 * i2.y };
let u2 = ((e33.x - n2.x) * r2.x + (e33.y - n2.y) * r2.y) / a2;
u2 = OP(u2, 0, 1);
const p2 = { x: n2.x + u2 * r2.x, y: n2.y + u2 * r2.y };
let m2 = ((t2.x - n2.x) * r2.x + (t2.y - n2.y) * r2.y) / a2;
m2 = OP(m2, 0, 1);
const g2 = { x: n2.x + m2 * r2.x, y: n2.y + m2 * r2.y }, f2 = [{ pointA: l2, pointB: n2, distance: Math.sqrt((l2.x - n2.x) ** 2 + (l2.y - n2.y) ** 2) }, { pointA: d2, pointB: o2, distance: Math.sqrt((d2.x - o2.x) ** 2 + (d2.y - o2.y) ** 2) }, { pointA: e33, pointB: p2, distance: Math.sqrt((e33.x - p2.x) ** 2 + (e33.y - p2.y) ** 2) }, { pointA: t2, pointB: g2, distance: Math.sqrt((t2.x - g2.x) ** 2 + (t2.y - g2.y) ** 2) }].reduce((e34, t3) => t3.distance < e34.distance ? t3 : e34);
return { x: (f2.pointA.x + f2.pointB.x) / 2, y: (f2.pointA.y + f2.pointB.y) / 2 };
};
var OP = (e33, t2, n2) => Math.max(t2, Math.min(n2, e33));
function kP(e33) {
return e33.route_type !== "wire" ? [] : [e33.start_pcb_port_id, e33.end_pcb_port_id].filter((e34) => Boolean(e34));
}
function DP(e33) {
const t2 = new Set;
for (const n2 of e33.route)
for (const e34 of kP(n2))
t2.add(e34);
return Array.from(t2);
}
function LP(e33) {
const t2 = new Set;
for (const n2 of e33)
for (const e34 of DP(n2))
t2.add(e34);
return Array.from(t2);
}
var zP = 0.000000001;
var BP = (e33) => new $f(e33.x, e33.y);
function FP(e33, t2) {
if (!Number.isFinite(e33) || e33 <= 0)
throw new Error(`${t2} must be finite and positive`);
return e33;
}
function jP(e33, t2) {
return FP(t2, "radius"), new Kf(new Zf(BP(e33), t2));
}
function $P(e33) {
const t2 = e33.filter((t3, n3) => n3 === 0 || BP(t3).distanceTo(BP(e33[n3 - 1]))[0] > zP);
if (t2.length > 1 && BP(t2[0]).distanceTo(BP(t2.at(-1)))[0] <= zP && t2.pop(), t2.length < 2)
throw new Error("A ring needs at least two distinct vertices");
const n2 = t2.map((e34, n3) => {
const o3 = t2[(n3 + 1) % t2.length];
if (![e34.x, e34.y, e34.bulge ?? 0].every(Number.isFinite))
throw new Error("Non-finite ring vertex");
const i2 = e34.bulge ?? 0;
if (Math.abs(i2) <= zP)
return new Vf(BP(e34), BP(o3));
const r2 = o3.x - e34.x, s2 = o3.y - e34.y, a2 = Math.hypot(r2, s2), c2 = a2 * (1 - i2 * i2) / (4 * i2), l2 = new $f((e34.x + o3.x) / 2 - s2 / a2 * c2, (e34.y + o3.y) / 2 + r2 / a2 * c2);
return new qf(l2, a2 * (1 + i2 * i2) / (4 * Math.abs(i2)), Math.atan2(e34.y - l2.y, e34.x - l2.x), Math.atan2(o3.y - l2.y, o3.x - l2.x), i2 > 0);
}), o2 = new Kf;
if (o2.addFace(n2), o2.area() <= zP)
throw new Error("A ring must enclose a non-zero area");
return o2;
}
function YP(e33, t2, n2, o2 = 0, i2 = 0) {
if (FP(t2, "width"), FP(n2, "height"), !Number.isFinite(o2) || !Number.isFinite(i2) || i2 < 0)
throw new Error("Invalid rectangle rotation or corner radius");
const r2 = Math.min(i2, t2 / 2, n2 / 2), s2 = t2 / 2, a2 = n2 / 2;
let c2;
if (r2 <= zP)
c2 = $P([{ x: -s2, y: -a2 }, { x: s2, y: -a2 }, { x: s2, y: a2 }, { x: -s2, y: a2 }]);
else {
const e34 = [new $f(s2 - r2, -a2 + r2), new $f(s2 - r2, a2 - r2), new $f(-s2 + r2, a2 - r2), new $f(-s2 + r2, -a2 + r2)], t3 = [];
for (let n3 = 0;n3 < 4; n3++) {
const o3 = -Math.PI / 2 + n3 * Math.PI / 2, i3 = new qf(e34[n3], r2, o3, o3 + Math.PI / 2, true), s3 = e34[(n3 + 1) % 4], a3 = new $f(s3.x + r2 * Math.cos(o3 + Math.PI / 2), s3.y + r2 * Math.sin(o3 + Math.PI / 2));
t3.push(i3), i3.end.distanceTo(a3)[0] > zP && t3.push(new Vf(i3.end, a3));
}
c2 = new Kf, c2.addFace(t3);
}
return c2.rotate(o2 * Math.PI / 180).translate(new Xf(e33.x, e33.y));
}
function XP(e33, t2, n2, o2 = n2) {
const i2 = FP(n2, "trace width") / 2, r2 = FP(o2, "trace width") / 2, s2 = BP(e33).distanceTo(BP(t2))[0];
if (s2 <= Math.abs(i2 - r2) + zP)
return jP(i2 >= r2 ? e33 : t2, Math.max(i2, r2));
const a2 = Math.atan2(t2.y - e33.y, t2.x - e33.x), c2 = Math.acos((i2 - r2) / s2), l2 = a2 - c2, h2 = a2 + c2, d2 = (e34, t3, n3) => new $f(e34.x + t3 * Math.cos(n3), e34.y + t3 * Math.sin(n3)), u2 = new Kf;
return u2.addFace([new Vf(d2(e33, i2, l2), d2(t2, r2, l2)), new qf(BP(t2), r2, l2, h2, true), new Vf(d2(t2, r2, h2), d2(e33, i2, h2)), new qf(BP(e33), i2, h2, l2, true)]), u2;
}
function WP(e33, t2) {
const n2 = e33.clone(), o2 = [...n2.faces][0].orientation();
for (const e34 of t2) {
const t3 = e34.clone();
[...t3.faces][0].orientation() === o2 && t3.reverse();
for (const e35 of t3.faces)
n2.addFace(e35.shapes);
}
return n2;
}
function VP(e33, t2, n2, o2 = 0, i2 = 0.001) {
if (FP(t2, "ellipse width"), FP(n2, "ellipse height"), FP(i2, "curveTolerance"), Math.abs(t2 - n2) < zP)
return jP(e33, t2 / 2);
const r2 = Math.max(t2, n2) / 2, s2 = Math.max(16, Math.ceil(Math.PI / Math.acos(Math.max(-1, 1 - i2 / r2))));
if (s2 > 1e5)
throw new Error("curveTolerance requires more than 100000 ellipse segments");
return $P(Array.from({ length: s2 }, (e34, o3) => ({ x: t2 / 2 * Math.cos(2 * o3 * Math.PI / s2), y: n2 / 2 * Math.sin(2 * o3 * Math.PI / s2) }))).rotate(o2 * Math.PI / 180).translate(new Xf(e33.x, e33.y));
}
function HP(e33, t2) {
if (!e33.length)
return [];
const n2 = e33.map((e34) => t2.indexOf(e34));
if (n2.some((e34) => e34 < 0))
throw new Error(`Layer is missing from copperLayers: ${e33.join(", ")}`);
return t2.slice(Math.min(...n2), Math.max(...n2) + 1);
}
function GP(e33) {
switch (e33.shape) {
case "circle":
return jP(e33, e33.radius);
case "polygon":
return $P(e33.points);
case "rect":
case "rotated_rect":
return YP(e33, e33.width, e33.height, "ccw_rotation" in e33 ? e33.ccw_rotation : 0, e33.rect_border_radius ?? e33.corner_radius ?? 0);
case "pill":
case "rotated_pill":
return YP(e33, e33.width, e33.height, "ccw_rotation" in e33 ? e33.ccw_rotation : 0, e33.radius);
}
}
function UP(e33, t2) {
switch (e33.hole_shape) {
case "circle":
return jP(e33, e33.hole_diameter / 2);
case "square":
return YP(e33, e33.hole_diameter, e33.hole_diameter);
case "rect":
return YP(e33, e33.hole_width, e33.hole_height);
case "oval":
return VP(e33, e33.hole_width, e33.hole_height, 0, t2);
case "pill":
case "rotated_pill":
return YP(e33, e33.hole_width, e33.hole_height, "ccw_rotation" in e33 ? e33.ccw_rotation : 0, Math.min(e33.hole_width, e33.hole_height) / 2);
}
}
function ZP(e33, t2, n2, o2) {
let i2, r2;
const s2 = { x: e33.x + ("hole_offset_x" in e33 ? e33.hole_offset_x ?? 0 : 0), y: e33.y + ("hole_offset_y" in e33 ? e33.hole_offset_y ?? 0 : 0) };
switch (e33.shape) {
case "circle":
i2 = jP(e33, e33.outer_diameter / 2), r2 = jP(e33, e33.hole_diameter / 2);
break;
case "oval":
i2 = VP(e33, e33.outer_width, e33.outer_height, e33.ccw_rotation, o2), r2 = VP(e33, e33.hole_width, e33.hole_height, e33.ccw_rotation, o2);
break;
case "pill":
i2 = YP(e33, e33.outer_width, e33.outer_height, e33.ccw_rotation, Math.min(e33.outer_width, e33.outer_height) / 2), r2 = YP(e33, e33.hole_width, e33.hole_height, e33.ccw_rotation, Math.min(e33.hole_width, e33.hole_height) / 2);
break;
case "circular_hole_with_rect_pad":
case "pill_hole_with_rect_pad":
case "rotated_pill_hole_with_rect_pad":
i2 = YP(e33, e33.rect_pad_width, e33.rect_pad_height, "rect_ccw_rotation" in e33 ? e33.rect_ccw_rotation : 0, e33.rect_border_radius ?? 0), r2 = e33.shape === "circular_hole_with_rect_pad" ? jP(s2, e33.hole_diameter / 2) : YP(s2, e33.hole_width, e33.hole_height, "hole_ccw_rotation" in e33 ? e33.hole_ccw_rotation : 0, Math.min(e33.hole_width, e33.hole_height) / 2);
break;
case "hole_with_polygon_pad": {
const n3 = e33.ccw_rotation ?? t2;
i2 = $P(e33.pad_outline).rotate(n3 * Math.PI / 180).translate(new Xf(e33.x, e33.y)), r2 = e33.hole_shape === "circle" ? jP(s2, e33.hole_diameter / 2) : e33.hole_shape === "oval" ? VP(s2, e33.hole_width, e33.hole_height, n3, o2) : YP(s2, e33.hole_width, e33.hole_height, n3, Math.min(e33.hole_width, e33.hole_height) / 2);
break;
}
}
return n2 ? WP(i2, [r2]) : i2;
}
var qP = (e33, t2) => e33.x === t2.x && e33.y === t2.y;
var JP = (e33, t2) => {
const n2 = Math.hypot(e33, t2);
return n2 ? { x: e33 / n2, y: t2 / n2 } : { x: 1, y: 0 };
};
function QP(e33, t2) {
try {
return yf.subtract(e33, t2);
} catch (n2) {
if (!(n2 instanceof Error) || n2.message !== "Unresolved boundary conflict in boolean operation")
throw n2;
const o2 = new kf(1000, 0, 0, 1000, 0, 0), i2 = new kf(0.001, 0, 0, 0.001, 0, 0);
return yf.subtract(e33.transform(o2), t2.transform(o2)).transform(i2);
}
}
function KP(e33, t2, n2) {
const o2 = new Map, i2 = new Map, r2 = [], s2 = (e34, t3) => o2.set(e34, [...o2.get(e34) ?? [], t3]);
for (const o3 of e33.route) {
if (o3.route_type === "via") {
const e34 = o3, r3 = o3.outer_diameter ?? e34.via_diameter;
if (r3 === undefined)
continue;
const a2 = o3.hole_diameter ?? e34.via_hole_diameter, c2 = jP(o3, r3 / 2), l2 = n2 && a2 ? jP(o3, a2 / 2) : undefined;
for (const e35 of HP([o3.from_layer, o3.to_layer], t2))
s2(e35, l2 ? WP(c2, [l2]) : c2), l2 && i2.set(e35, [...i2.get(e35) ?? [], l2]);
}
if (o3.route_type === "through_pad")
for (const e34 of new Set([o3.start_layer, o3.end_layer]))
s2(e34, XP(o3.start, o3.end, o3.width));
}
for (let n3 = 0;n3 < e33.route.length - 1; n3++) {
const o3 = e33.route[n3], i3 = e33.route[n3 + 1], s3 = o3.route_type === "through_pad" ? o3.end : o3, a2 = i3.route_type === "through_pad" ? i3.start : i3;
if (qP(s3, a2))
continue;
const c2 = o3.route_type === "wire" ? [o3.layer] : o3.route_type === "via" ? HP([o3.from_layer, o3.to_layer], t2) : [o3.end_layer], l2 = i3.route_type === "wire" ? [i3.layer] : i3.route_type === "via" ? HP([i3.from_layer, i3.to_layer], t2) : [i3.start_layer], h2 = c2.filter((e34) => l2.includes(e34));
if (h2.length !== 1)
throw new Error(`Cannot determine one wire layer between route points ${n3} and ${n3 + 1}`);
const d2 = h2[0], u2 = "width" in o3 ? o3.width : ("width" in i3) ? i3.width : undefined;
u2 === undefined || qP(s3, a2) || r2.push({ start: s3, end: a2, layer: d2, startWidth: u2, endWidth: "width" in i3 ? i3.width : u2 });
}
if (e33.route_thickness_mode === "interpolated") {
let e34 = [];
const t3 = () => {
e34.length && (s2(e34[0].layer, function(e35) {
const t4 = [{ ...e35[0].start, width: e35[0].startWidth }, ...e35.map((e36) => ({ ...e36.end, width: e36.endWidth }))], n3 = e35.map((e36) => JP(e36.end.x - e36.start.x, e36.end.y - e36.start.y)), o3 = [], i3 = [];
for (let e36 = 0;e36 < t4.length; e36++) {
const r3 = t4[e36];
FP(r3.width, "interpolated trace width");
const s3 = n3[Math.max(0, e36 - 1)], a2 = n3[Math.min(e36, n3.length - 1)], c2 = JP(s3.x + a2.x, s3.y + a2.y), l2 = -c2.y * r3.width / 2, h2 = c2.x * r3.width / 2;
o3.push({ x: r3.x + l2, y: r3.y + h2 }), i3.push({ x: r3.x - l2, y: r3.y - h2 });
}
return $P([...o3, ...i3.reverse()]);
}(e34)), e34 = []);
};
for (const n3 of r2) {
const o3 = e34.at(-1);
!o3 || o3.layer === n3.layer && qP(o3.end, n3.start) && o3.endWidth === n3.startWidth || t3(), e34.push(n3);
}
t3();
} else
for (const e34 of r2)
s2(e34.layer, XP(e34.start, e34.end, e34.startWidth));
for (const [e34, t3] of i2)
o2.set(e34, o2.get(e34).map((e35) => t3.reduce((e36, t4) => QP(e36, t4), e35)).filter((e35) => e35.faces.size > 0));
return o2;
}
var eM = ["pcb_board", "pcb_smtpad", "pcb_plated_hole", "pcb_hole", "pcb_via", "pcb_trace", "pcb_copper_pour", "pcb_cutout", "pcb_keepout", "pcb_courtyard_rect", "pcb_courtyard_circle", "pcb_courtyard_pill", "pcb_courtyard_polygon", "pcb_courtyard_outline"];
function tM(e33) {
switch (e33.shape) {
case "circle":
return [jP(e33.center, e33.radius)];
case "rect":
return [YP(e33.center, e33.width, e33.height, e33.rotation, e33.corner_radius)];
case "polygon":
return [$P(e33.points)];
case "path":
if (e33.slot_length !== undefined || e33.space_between_slots !== undefined || e33.slot_corner_radius !== undefined)
throw new Error("Patterned/custom-corner path cutouts are not supported; use explicit rect/polygon cutouts");
return e33.route.slice(1).map((t2, n2) => XP(e33.route[n2], t2, e33.slot_width));
}
}
function nM(e33, t2 = {}) {
if (t2.layer && t2.layers)
throw new Error("Specify layer or layers, not both");
const n2 = t2.layer ? [t2.layer] : t2.layers, o2 = function(e34, t3) {
if (t3.copperLayers) {
if (!t3.copperLayers.length || new Set(t3.copperLayers).size !== t3.copperLayers.length)
throw new Error("copperLayers must be a non-empty list without duplicates");
return [...t3.copperLayers];
}
const n3 = e34.find((e35) => e35.type === "pcb_board");
let o3 = n3?.num_layers ?? 2;
for (const t4 of e34) {
const e35 = "layers" in t4 ? t4.layers : ("layer" in t4) ? [t4.layer] : [];
if (Array.isArray(e35))
for (const t5 of e35) {
const e36 = typeof t5 == "string" && /^inner(\d+)$/.exec(t5);
e36 && (o3 = Math.max(o3, Number(e36[1]) + 2));
}
if (t4.type === "pcb_trace")
for (const e36 of t4.route)
for (const t5 of e36.route_type === "wire" ? [e36.layer] : e36.route_type === "via" ? [e36.from_layer, e36.to_layer] : [e36.start_layer, e36.end_layer]) {
const e37 = /^inner(\d+)$/.exec(t5);
e37 && (o3 = Math.max(o3, Number(e37[1]) + 2));
}
}
if (!Number.isInteger(o3) || o3 < 1 || o3 > 10)
throw new Error("Supported copper layer count is 1–10");
return o3 === 1 ? ["top"] : ["top", ...Array.from({ length: o3 - 2 }, (e35, t4) => `inner${t4 + 1}`), "bottom"];
}(e33, t2), i2 = { elements: [], warnings: [], bounds: undefined, copperLayers: o2 }, r2 = new Map(e33.filter((e34) => e34.type === "pcb_component").map((e34) => [e34.pcb_component_id, e34.rotation])), s2 = t2.curveTolerance ?? 0.001;
if (!Number.isFinite(s2) || s2 <= 0)
throw new Error("curveTolerance must be finite and positive");
const a2 = t2.includeDrillHoles !== false;
for (const c2 of e33) {
if (!eM.includes(c2.type))
continue;
const e34 = c2[`${c2.type}_id`];
if (t2.elementTypes && !t2.elementTypes.includes(c2.type))
continue;
if (t2.elementIds && !t2.elementIds.includes(e34))
continue;
let l2, h2 = "copper", d2 = [null], u2 = [];
try {
switch (c2.type) {
case "pcb_smtpad":
d2 = [c2.layer], u2 = [GP(c2)];
break;
case "pcb_plated_hole":
d2 = HP(c2.layers, o2), u2 = [ZP(c2, r2.get(c2.pcb_component_id ?? "") ?? 0, a2, s2)];
break;
case "pcb_via": {
d2 = HP(c2.layers, o2);
const e35 = jP(c2, c2.outer_diameter / 2);
u2 = [a2 ? WP(e35, [jP(c2, c2.hole_diameter / 2)]) : e35];
break;
}
case "pcb_trace":
l2 = KP(c2, o2, a2), d2 = [...l2.keys()];
break;
case "pcb_copper_pour":
d2 = [c2.layer], u2 = [c2.shape === "rect" ? YP(c2.center, c2.width, c2.height, c2.rotation) : c2.shape === "polygon" ? $P(c2.points) : WP($P(c2.brep_shape.outer_ring.vertices), c2.brep_shape.inner_rings.map((e35) => $P(e35.vertices)))];
break;
case "pcb_board":
h2 = "board", u2 = [c2.outline?.length ? $P(c2.outline) : YP(c2.center, c2.width, c2.height)];
break;
case "pcb_hole":
h2 = "drill", u2 = [UP(c2, s2)];
break;
case "pcb_cutout":
h2 = "cutout", u2 = tM(c2);
break;
case "pcb_keepout":
h2 = "keepout", d2 = c2.layers, u2 = [c2.shape === "circle" ? jP(c2.center, c2.radius) : c2.shape === "rect" ? YP(c2.center, c2.width, c2.height) : $P(c2.outline)];
break;
case "pcb_courtyard_rect":
h2 = "courtyard", d2 = [c2.layer], u2 = [YP(c2.center, c2.width, c2.height, c2.ccw_rotation)];
break;
case "pcb_courtyard_circle":
h2 = "courtyard", d2 = [c2.layer], u2 = [jP(c2.center, c2.radius)];
break;
case "pcb_courtyard_pill":
h2 = "courtyard", d2 = [c2.layer], u2 = [YP(c2.center, c2.width, c2.height, 0, c2.radius)];
break;
case "pcb_courtyard_polygon":
h2 = "courtyard", d2 = [c2.layer], u2 = [$P(c2.points)];
break;
case "pcb_courtyard_outline":
h2 = "courtyard", d2 = [c2.layer], u2 = [$P(c2.outline)];
}
if (t2.roles && !t2.roles.includes(h2))
continue;
const p2 = [];
for (const o3 of new Set(d2)) {
if (o3 === null ? t2.includeLayerless === false : n2 && !n2.includes(o3))
continue;
const i3 = l2?.get(o3) ?? u2;
if (!i3.length)
continue;
const r3 = i3.reduce((e35, t3) => e35.merge(t3.box), i3[0].box);
if (![r3.xmin, r3.ymin, r3.xmax, r3.ymax].every(Number.isFinite))
throw new Error("Non-finite geometry bounds");
const s3 = { elementId: e34, elementType: c2.type, sourceElement: c2, role: h2, layer: o3, shapes: i3, bounds: r3 };
p2.push(s3);
}
for (const e35 of p2)
i2.elements.push(e35), i2.bounds = i2.bounds ? i2.bounds.merge(e35.bounds) : e35.bounds;
} catch (n3) {
const o3 = n3 instanceof Error ? n3.message : String(n3);
if (t2.strict)
throw new Error(`${e34}: ${o3}`);
i2.warnings.push({ elementId: e34, elementType: c2.type, message: o3 });
}
}
return i2;
}
var oM = 0.000000001;
function iM(e33) {
const t2 = new Map(e33.filter((e34) => e34.type === "pcb_port").map((e34) => [e34.pcb_port_id, e34])), n2 = e33.filter((e34) => e34.type === "pcb_smtpad" || e34.type === "pcb_plated_hole"), o2 = new Map;
for (const e34 of n2) {
if (!e34.pcb_port_id)
continue;
const t3 = o2.get(e34.pcb_port_id) ?? [];
t3.push(e34), o2.set(e34.pcb_port_id, t3);
}
const i2 = e33.filter((e34) => e34.type === "pcb_via");
let r2;
const s2 = (e34) => {
const t3 = o2.get(e34.pcb_port_id);
return t3?.length ? [...new Set(t3.flatMap(cP))] : e34.layers;
};
return { ports: t2, layersForPort: s2, canConnect: (n3, a2) => {
const c2 = t2.get(a2);
if (!c2)
return true;
const l2 = s2(c2);
if (l2.includes(n3.layer))
return true;
const h2 = o2.get(a2) ?? [];
return (() => {
if (r2)
return r2;
r2 = i2.map((e34) => ({ ...e34, diameter: e34.outer_diameter }));
const t3 = e33.find((e34) => e34.type === "pcb_board"), n4 = ["top", ...Yb.filter((e34) => e34.startsWith("inner")).slice(0, t3 ? Math.max(0, t3.num_layers - 2) : undefined), ...t3?.num_layers === 1 ? [] : ["bottom"]];
for (const t4 of e33)
if (t4.type === "pcb_trace")
for (const e34 of t4.route) {
if (e34.route_type !== "via")
continue;
if (i2.some((t6) => Math.hypot(t6.x - e34.x, t6.y - e34.y) <= oM))
continue;
const t5 = n4.indexOf(e34.from_layer), o3 = n4.indexOf(e34.to_layer);
t5 < 0 || o3 < 0 || r2.push({ ...e34, layers: n4.slice(Math.min(t5, o3), Math.max(t5, o3) + 1), diameter: e34.outer_diameter });
}
return r2;
})().some((e34) => {
if (!e34.layers.includes(n3.layer) || !l2.some((t4) => e34.layers.includes(t4)))
return false;
if (e34.diameter !== undefined && (!Number.isFinite(e34.diameter) || e34.diameter <= 0))
return false;
const t3 = e34.diameter === undefined ? 0 : e34.diameter / 2 + n3.width / 2;
return !(Math.hypot(n3.x - e34.x, n3.y - e34.y) > t3 + oM) && (h2.length === 0 ? Math.hypot(c2.x - e34.x, c2.y - e34.y) <= oM : h2.some((t4) => !!cP(t4).some((t5) => e34.layers.includes(t5)) && (e34.diameter === undefined ? aP(e34, t4) : PP({ type: "pcb_via", pcb_via_id: "layer-contact", x: e34.x, y: e34.y, outer_diameter: e34.diameter, hole_diameter: 0, layers: e34.layers }, t4) <= oM)));
});
} };
}
function rM(e33) {
if (!e33.some((e34) => e34.type === "pcb_via" || e34.type === "pcb_copper_pour" || e34.type === "pcb_trace" && e34.route.some((e35) => e35.route_type === "via")))
return [];
const t2 = [], n2 = [], o2 = 1e6, i2 = 0.0000001 * o2, r2 = function(e34) {
const t3 = new WeakMap, n3 = (e35) => {
let n4 = t3.get(e35);
return n4 || (n4 = { box: e35.box, facePoints: [...e35.faces].map((e36) => e36.first.start), edges: [...e35.edges].map((e36) => e36.shape), edgeIndex: e35.edges }, t3.set(e35, n4)), n4;
};
return (t4, o3) => {
if (t4.isEmpty() || o3.isEmpty())
return false;
const i3 = n3(t4), r3 = n3(o3);
if (i3.box.xmin > r3.box.xmax + e34 || i3.box.xmax < r3.box.xmin - e34 || i3.box.ymin > r3.box.ymax + e34 || i3.box.ymax < r3.box.ymin - e34)
return false;
if (i3.facePoints.some((e35) => r3.box.contains(e35) && o3.contains(e35)) || r3.facePoints.some((e35) => i3.box.contains(e35) && t4.contains(e35)))
return true;
const [s3, a3] = i3.edges.length <= r3.edges.length ? [i3, r3] : [r3, i3];
for (const t5 of s3.edges) {
const n4 = t5.box, o4 = new Jf(n4.xmin - e34, n4.ymin - e34, n4.xmax + e34, n4.ymax + e34), i4 = a3.edgeIndex.search(o4);
for (const n5 of i4)
if (t5.distanceTo(n5.shape)[0] <= e34)
return true;
}
return false;
};
}(i2), s2 = (e34, n3, i3, r3 = false) => {
i3.isEmpty() || t2.push({ id: e34, layers: n3, polygon: i3.scale(o2, o2), bridges: r3 });
}, a2 = e33.filter((e34) => e34.type === "pcb_via"), c2 = e33.find((e34) => e34.type === "pcb_board"), l2 = ["top", ...Yb.filter((e34) => e34.startsWith("inner")).slice(0, c2 ? Math.max(0, c2.num_layers - 2) : undefined), ...c2?.num_layers === 1 ? [] : ["bottom"]];
for (const t3 of e33)
if (t3.type === "pcb_via")
s2(t3.pcb_via_id, t3.layers, WC(t3, t3.outer_diameter / 2), true), t3.pcb_trace_id && n2.push([t3.pcb_via_id, t3.pcb_trace_id]);
else if (t3.type === "pcb_copper_pour")
s2(t3.pcb_copper_pour_id, [t3.layer], GC(t3), true);
else if (t3.type === "pcb_trace") {
if (t3.route_thickness_mode === "interpolated")
continue;
for (let e34 = 0;e34 < t3.route.length; e34++) {
const n3 = t3.route[e34], o3 = t3.route[e34 + 1];
if (n3.route_type !== "wire" || o3?.route_type !== "wire" || n3.layer !== o3.layer || n3.x === o3.x && n3.y === o3.y) {
if (n3.route_type === "via") {
if (a2.some((e35) => e35.pcb_trace_id === t3.pcb_trace_id && Math.hypot(e35.x - n3.x, e35.y - n3.y) < 0.000000001))
continue;
const o4 = l2.indexOf(n3.from_layer), i3 = l2.indexOf(n3.to_layer);
if (o4 < 0 || i3 < 0 || !n3.outer_diameter)
continue;
const r3 = { pcb_via_id: `${t3.pcb_trace_id}_via_${e34}`, x: n3.x, y: n3.y, outer_diameter: n3.outer_diameter, layers: l2.slice(Math.min(o4, i3), Math.max(o4, i3) + 1) };
s2(t3.pcb_trace_id, r3.layers, WC(r3, r3.outer_diameter / 2), true);
}
} else
s2(t3.pcb_trace_id, [n3.layer], UC(n3, o3, n3.width));
}
}
if (!t2.length)
return n2;
const h2 = new je(t2.length);
for (const { polygon: e34 } of t2) {
const t3 = e34.box;
h2.add(t3.xmin, t3.ymin, t3.xmax, t3.ymax);
}
h2.finish();
for (const [e34, o3] of t2.entries()) {
if (!o3.bridges)
continue;
const s3 = o3.polygon.box;
for (const a3 of h2.search(s3.xmin - i2, s3.ymin - i2, s3.xmax + i2, s3.ymax + i2)) {
const i3 = t2[a3];
e34 === a3 || o3.id === i3.id || i3.bridges && a3 < e34 || !o3.layers.some((e35) => i3.layers.includes(e35)) || r2(o3.polygon, i3.polygon) && n2.push([o3.id, i3.id]);
}
}
return n2;
}
function sM(e33, t2, n2, o2) {
return Math.sqrt((n2 - e33) ** 2 + (o2 - t2) ** 2);
}
var aM = (e33) => nM(e33.filter((e34) => e34.type === "pcb_hole"), { elementTypes: ["pcb_hole"], strict: true, curveTolerance: 0.000001 }).elements;
var cM = (e33, t2) => {
const n2 = t2.sourceElement;
if (n2.type !== "pcb_hole")
throw new Error(`Expected hole geometry for ${t2.elementId}`);
const o2 = new $f(e33.x1, e33.y1), i2 = new $f(e33.x2, e33.y2);
let r2 = 1 / 0, s2 = Bt(n2, o2, i2);
if (n2.hole_shape === "circle")
r2 = xt(n2, o2, i2) - n2.hole_diameter / 2;
else {
const e34 = new Vf(o2, i2);
for (const n3 of t2.shapes) {
const [t3, a2] = n3.distanceTo(e34), c2 = n3.contains(o2) || n3.contains(i2) ? 0 : t3;
c2 < r2 && (r2 = c2, s2 = a2.end);
}
}
return { gap: r2 - e33.thickness / 2, center: s2 };
};
var lM = class {
buckets;
objectsById;
getBounds;
getId;
CELL_SIZE = 0.4;
constructor({ objects: e33, getBounds: t2, getId: n2, CELL_SIZE: o2 }) {
this.buckets = new Map, this.objectsById = new Map, this.getBounds = t2, this.getId = n2 ?? (() => this._getNextId()), this.CELL_SIZE = o2 ?? this.CELL_SIZE;
for (const t3 of e33)
this.addObject(t3);
}
_idCounter = 0;
_getNextId() {
return "" + this._idCounter++;
}
addObject(e33) {
const t2 = this.getBounds(e33), n2 = this.getId(e33), o2 = { ...e33, spatialIndexId: n2 };
this.objectsById.set(n2, o2);
const i2 = Math.floor(t2.minX / this.CELL_SIZE), r2 = Math.floor(t2.minY / this.CELL_SIZE), s2 = Math.floor(t2.maxX / this.CELL_SIZE), a2 = Math.floor(t2.maxY / this.CELL_SIZE);
for (let e34 = i2;e34 <= s2; e34++)
for (let t3 = r2;t3 <= a2; t3++) {
const n3 = `${e34}x${t3}`, i3 = this.buckets.get(n3);
i3 ? i3.push(o2) : this.buckets.set(n3, [o2]);
}
}
removeObject(e33) {
const t2 = this.objectsById.get(e33);
if (!t2)
return false;
this.objectsById.delete(e33);
const n2 = this.getBounds(t2), o2 = Math.floor(n2.minX / this.CELL_SIZE), i2 = Math.floor(n2.minY / this.CELL_SIZE), r2 = Math.floor(n2.maxX / this.CELL_SIZE), s2 = Math.floor(n2.maxY / this.CELL_SIZE);
for (let t3 = o2;t3 <= r2; t3++)
for (let n3 = i2;n3 <= s2; n3++) {
const o3 = `${t3}x${n3}`, i3 = this.buckets.get(o3);
if (i3) {
const t4 = i3.findIndex((t5) => t5.spatialIndexId === e33);
t4 !== -1 && (i3.splice(t4, 1), i3.length === 0 && this.buckets.delete(o3));
}
}
return true;
}
getBucketKey(e33, t2) {
return `${Math.floor(e33 / this.CELL_SIZE)}x${Math.floor(t2 / this.CELL_SIZE)}`;
}
getObjectsInBounds(e33, t2 = 0) {
const n2 = [], o2 = new Set, i2 = Math.floor((e33.minX - t2) / this.CELL_SIZE), r2 = Math.floor((e33.minY - t2) / this.CELL_SIZE), s2 = Math.floor((e33.maxX + t2) / this.CELL_SIZE), a2 = Math.floor((e33.maxY + t2) / this.CELL_SIZE);
for (let e34 = i2;e34 <= s2; e34++)
for (let t3 = r2;t3 <= a2; t3++) {
const i3 = `${e34}x${t3}`, r3 = this.buckets.get(i3) || [];
for (const e35 of r3) {
const t4 = e35.spatialIndexId;
o2.has(t4) || (o2.add(t4), n2.push(e35));
}
}
return n2;
}
};
var hM = (e33, t2) => {
const n2 = { x: e33.x1, y: e33.y1 }, o2 = { x: e33.x2, y: e33.y2 }, i2 = t2.minX, r2 = t2.minY, s2 = t2.maxX, a2 = t2.maxY;
if (n2.x === o2.x && n2.y === o2.y) {
const e34 = Math.max(i2, Math.min(s2, n2.x)), t3 = Math.max(r2, Math.min(a2, n2.y));
return e34 === n2.x && t3 === n2.y ? { x: n2.x, y: n2.y } : { x: e34, y: t3 };
}
const c2 = o2.x - n2.x, l2 = o2.y - n2.y, h2 = c2 !== 0 ? (i2 - n2.x) / c2 : Number.NEGATIVE_INFINITY, d2 = c2 !== 0 ? (s2 - n2.x) / c2 : Number.POSITIVE_INFINITY, u2 = l2 !== 0 ? (r2 - n2.y) / l2 : Number.NEGATIVE_INFINITY, p2 = l2 !== 0 ? (a2 - n2.y) / l2 : Number.POSITIVE_INFINITY, m2 = Math.max(Math.min(h2, d2), Math.min(u2, p2)), g2 = Math.min(Math.max(h2, d2), Math.max(u2, p2));
if (m2 <= g2 && g2 >= 0 && m2 <= 1) {
const e34 = Math.max(0, Math.min(1, m2));
return { x: n2.x + e34 * c2, y: n2.y + e34 * l2 };
}
const f2 = { x: Math.max(i2, Math.min(s2, n2.x)), y: Math.max(r2, Math.min(a2, n2.y)) }, _2 = { x: Math.max(i2, Math.min(s2, o2.x)), y: Math.max(r2, Math.min(a2, o2.y)) }, y2 = (f2.x - n2.x) ** 2 + (f2.y - n2.y) ** 2, b2 = (_2.x - o2.x) ** 2 + (_2.y - o2.y) ** 2, x2 = [{ start: { x: i2, y: r2 }, end: { x: s2, y: r2 } }, { start: { x: s2, y: r2 }, end: { x: s2, y: a2 } }, { start: { x: s2, y: a2 }, end: { x: i2, y: a2 } }, { start: { x: i2, y: a2 }, end: { x: i2, y: r2 } }];
let v2 = Math.min(y2, b2), I2 = y2 <= b2 ? f2 : _2;
const S2 = (e34, t3, n3) => Math.max(t3, Math.min(n3, e34));
for (const e34 of x2) {
const t3 = { x: o2.x - n2.x, y: o2.y - n2.y }, i3 = { x: e34.end.x - e34.start.x, y: e34.end.y - e34.start.y }, r3 = { x: n2.x - e34.start.x, y: n2.y - e34.start.y }, s3 = t3.x * t3.x + t3.y * t3.y, a3 = t3.x * i3.x + t3.y * i3.y, c3 = t3.x * r3.x + t3.y * r3.y, l3 = i3.x * i3.x + i3.y * i3.y, h3 = i3.x * r3.x + i3.y * r3.y, d3 = s3 * l3 - a3 * a3;
if (Math.abs(d3) < 0.0000000001)
continue;
let u3 = (a3 * h3 - l3 * c3) / d3, p3 = (s3 * h3 - a3 * c3) / d3;
u3 = S2(u3, 0, 1), p3 = S2(p3, 0, 1);
const m3 = { x: n2.x + u3 * t3.x, y: n2.y + u3 * t3.y }, g3 = { x: e34.start.x + p3 * i3.x, y: e34.start.y + p3 * i3.y }, f3 = m3.x - g3.x, _3 = m3.y - g3.y, y3 = f3 * f3 + _3 * _3;
y3 < v2 && (v2 = y3, I2 = { x: (m3.x + g3.x) / 2, y: (m3.y + g3.y) / 2 });
}
return I2;
};
var dM = (e33) => {
if (e33.type === "pcb_hole" && (e33.hole_shape === "pill" || e33.hole_shape === "rotated_pill") || e33.type === "pcb_smtpad" && e33.shape === "rotated_pill") {
const t2 = JC(e33);
return { minX: Math.min(t2.start.x, t2.end.x) - t2.radius, minY: Math.min(t2.start.y, t2.end.y) - t2.radius, maxX: Math.max(t2.start.x, t2.end.x) + t2.radius, maxY: Math.max(t2.start.y, t2.end.y) + t2.radius };
}
if (e33.type === "pcb_trace_segment")
return { minX: Math.min(e33.x1, e33.x2), minY: Math.min(e33.y1, e33.y2), maxX: Math.max(e33.x1, e33.x2), maxY: Math.max(e33.y1, e33.y2) };
if (e33.type === "pcb_smtpad" || e33.type === "pcb_plated_hole") {
if (e33.type === "pcb_smtpad" && (e33.shape === "rotated_rect" || e33.shape === "polygon") || e33.type === "pcb_plated_hole" && "rect_pad_width" in e33 && "rect_pad_height" in e33) {
const t2 = QC(e33);
return { minX: Math.min(...t2.map((e34) => e34.x)), minY: Math.min(...t2.map((e34) => e34.y)), maxX: Math.max(...t2.map((e34) => e34.x)), maxY: Math.max(...t2.map((e34) => e34.y)) };
}
}
return AC([e33]);
};
var uM = (e33) => e33.type === "pcb_port" ? e33.pcb_port_id : e33.type === "pcb_smtpad" ? e33.pcb_smtpad_id : e33.pcb_plated_hole_id;
function pM(e33, { connMap: t2, minClearance: n2 } = {}) {
const o2 = function(e34) {
const t3 = new Set(e34.flatMap((e35) => e35.type === "source_bus" && e35.max_length_skew !== undefined ? e35.source_trace_ids : [])), n3 = _C(e34), o3 = [];
for (const i3 of e34) {
if (i3.type !== "pcb_trace")
continue;
if (!i3.source_trace_id || !t3.has(i3.source_trace_id))
continue;
const r3 = [], s3 = [];
let a3, c3 = 0, l3 = 0;
for (let e35 = 0;e35 < i3.route.length - 1; e35++) {
s3[e35] = c3;
const t4 = i3.route[e35], n4 = i3.route[e35 + 1];
if (t4.route_type !== "wire" || n4.route_type !== "wire" || t4.layer !== n4.layer) {
l3++;
continue;
}
const o4 = Math.hypot(n4.x - t4.x, n4.y - t4.y);
o4 !== 0 && (r3.push({ type: "pcb_trace_segment", _pcbTrace: i3, pcb_trace_id: i3.pcb_trace_id, thickness: t4.width, layer: t4.layer, x1: t4.x, y1: t4.y, x2: n4.x, y2: n4.y, run: l3, startDistance: c3, endDistance: c3 + o4 }), c3 += o4);
}
s3[i3.route.length - 1] = c3;
e:
for (let e35 = 0;e35 < r3.length; e35++) {
const t4 = r3[e35];
for (let n4 = e35 + 1;n4 < r3.length; n4++) {
const e36 = r3[n4];
if (t4.layer !== e36.layer)
continue;
const o4 = (t4.thickness + e36.thickness) / 2, i4 = (t4.x2 - t4.x1) * (e36.x2 - e36.x1) + (t4.y2 - t4.y1) * (e36.y2 - e36.y1), s4 = (t4.x2 - t4.x1) * (e36.y2 - e36.y1) - (t4.y2 - t4.y1) * (e36.x2 - e36.x1), c4 = i4 >= Math.hypot(t4.x2 - t4.x1, t4.y2 - t4.y1) * Math.hypot(e36.x2 - e36.x1, e36.y2 - e36.y1) * -1e-9, l4 = t4.run === e36.run && e36.startDistance === t4.endDistance;
if ((!l4 || i4 < 0 && Math.abs(s4) < 0.000000001) && !(!l4 && t4.run === e36.run && e36.startDistance - t4.endDistance <= Math.SQRT2 * o4 && c4 || kt({ x: t4.x1, y: t4.y1 }, { x: t4.x2, y: t4.y2 }, { x: e36.x1, y: e36.y1 }, { x: e36.x2, y: e36.y2 }) - o4 > 0.000000001)) {
a3 = EP(t4, e36);
break e;
}
}
}
if (!a3) {
const t4 = e34.find((e35) => e35.type === "pcb_board"), o4 = ["top", ...Yb.filter((e35) => e35.startsWith("inner")).slice(0, t4 ? Math.max(0, t4.num_layers - 2) : undefined), ...t4?.num_layers === 1 ? [] : ["bottom"]];
e:
for (let e35 = 0;e35 < i3.route.length; e35++) {
const t5 = i3.route[e35];
if (t5.route_type !== "via")
continue;
const c4 = n3.pcb_via.list().find((e36) => (e36.pcb_trace_id === i3.pcb_trace_id || !e36.pcb_trace_id && e36.source_trace_id === i3.source_trace_id) && Math.hypot(e36.x - t5.x, e36.y - t5.y) <= 0.000000001), l4 = c4?.outer_diameter ?? t5.outer_diameter;
if (l4 === undefined || !Number.isFinite(l4) || l4 <= 0)
continue;
const h3 = o4.indexOf(t5.from_layer), d3 = o4.indexOf(t5.to_layer), u3 = c4?.layers ?? (h3 >= 0 && d3 >= 0 ? o4.slice(Math.min(h3, d3), Math.max(h3, d3) + 1) : []);
for (const n4 of r3) {
if (!u3.includes(n4.layer))
continue;
const o5 = (l4 + n4.thickness) / 2;
if (Math.max(n4.startDistance - s3[e35], s3[e35] - n4.endDistance, 0) <= o5 + 0.000000001)
continue;
const i4 = { ...n4, x1: t5.x, y1: t5.y, x2: t5.x, y2: t5.y };
if (!(kt(t5, t5, { x: n4.x1, y: n4.y1 }, { x: n4.x2, y: n4.y2 }) - o5 > 0.000000001)) {
a3 = EP(n4, i4);
break e;
}
}
}
}
if (a3) {
const e35 = n3.source_trace.get(i3.source_trace_id), t4 = (e35?.connected_source_port_ids ?? []).map((e36) => {
const t5 = n3.source_port.get(e36), o4 = t5?.source_component_id ? n3.source_component.get(t5.source_component_id) : undefined;
return o4?.name && t5?.name ? `${o4.name}.${t5.name}` : undefined;
}).filter((e36) => Boolean(e36)), r4 = e35?.name || e35?.display_name || t4.join(" → ") || "unnamed";
o3.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", pcb_trace_error_id: `self_short_${i3.pcb_trace_id}`, pcb_trace_id: i3.pcb_trace_id, source_trace_id: i3.source_trace_id, message: `PCB trace "${r4}" shorts to itself, bypassing part of its length-matched route`, center: a3, pcb_component_ids: [], pcb_port_ids: LP([i3]), subcircuit_id: i3.subcircuit_id });
}
}
return o3;
}(e33);
((e34) => {
const t3 = e34.filter((e35) => e35.type === "pcb_port"), n3 = e34.filter((e35) => e35.type === "pcb_smtpad"), o3 = e34.filter((e35) => e35.type === "pcb_trace");
function i3(e35, o4 = {}) {
const i4 = o4.traceWidth || 0, r3 = t3.find((t4) => t4.layers.includes(e35.layer) && sM(t4.x, t4.y, e35.x, e35.y) < 0.01);
if (r3)
return r3.pcb_port_id;
if (o4.isFirstOrLastPoint) {
const t4 = n3.find((t5) => t5.layer === e35.layer && (t5.shape === "rect" ? Math.abs(e35.x - t5.x) < t5.width / 2 + i4 / 2 && Math.abs(e35.y - t5.y) < t5.height / 2 + i4 / 2 : t5.shape === "circle" ? sM(e35.x, e35.y, t5.x, t5.y) < t5.radius : t5.shape === "pill" || t5.shape === "rotated_pill" ? aP(e35, t5) : undefined));
if (t4)
return t4.pcb_port_id ?? null;
}
return null;
}
for (const e35 of o3)
for (let t4 = 0;t4 < e35.route.length; t4++) {
const n4 = e35.route[t4], o4 = t4 === 0 || t4 === e35.route.length - 1;
if (n4.route_type === "wire") {
if (!n4.start_pcb_port_id && t4 === 0) {
const e36 = i3(n4, { isFirstOrLastPoint: o4, traceWidth: n4.width });
e36 && (n4.start_pcb_port_id = e36);
}
if (!n4.end_pcb_port_id && t4 === e35.route.length - 1) {
const e36 = i3(n4, { isFirstOrLastPoint: o4, traceWidth: n4.width });
e36 && (n4.end_pcb_port_id = e36);
}
}
}
})(e33), t2 ??= ni(e33);
const i2 = fP(e33);
n2 ??= _P(i2, "min_trace_to_pad_edge_clearance") ?? 0.1;
const r2 = _C(e33).pcb_trace.list().flatMap((e34) => {
const t3 = [];
for (let n3 = 0;n3 < e34.route.length - 1; n3++) {
const o3 = e34.route[n3], i3 = e34.route[n3 + 1];
if (o3.route_type !== "wire" && o3.route_type !== "via" || i3.route_type !== "wire" && i3.route_type !== "via")
continue;
const r3 = o3.route_type === "wire" ? o3 : i3;
r3.route_type === "wire" && (o3.route_type === "wire" && i3.route_type === "wire" && o3.layer !== i3.layer || t3.push({ type: "pcb_trace_segment", pcb_trace_id: e34.pcb_trace_id, _pcbTrace: e34, thickness: Math.max(o3.route_type === "wire" ? o3.width ?? mP : 0, i3.route_type === "wire" ? i3.width ?? mP : 0), layer: r3.layer, x1: o3.x, y1: o3.y, x2: i3.x, y2: i3.y }));
}
return t3;
}), s2 = _C(e33).pcb_smtpad.list(), a2 = _C(e33).pcb_plated_hole.list(), c2 = _C(e33).pcb_port.list(), l2 = _C(e33).pcb_hole.list(), h2 = new Map(aM(e33).map((e34) => [e34.elementId, e34])), d2 = _C(e33).pcb_via.list(), u2 = _C(e33).pcb_keepout.list().filter((e34) => !e34.allow_traces), p2 = [...c2, ...s2, ...a2], m2 = new Map;
for (const e34 of u2) {
const t3 = new Set(e34.excluded_pcb_component_ids ?? []);
t3.size !== 0 && m2.set(e34.pcb_keepout_id, p2.filter((e35) => e35.pcb_component_id && t3.has(e35.pcb_component_id)).map(uM));
}
const g2 = [...r2, ...s2, ...a2, ...l2, ...d2, ...u2], f2 = new lM({ objects: g2, getBounds: dM }), _2 = (t3) => SC(e33, t3), y2 = (e34, t3, n3) => RP(n3) ? `PCB trace ${e34} overlaps with ${t3} (accidental contact)` : `PCB trace ${e34} is too close to ${t3} (gap: ${n3.toFixed(3)}mm)`, b2 = new Set;
for (const e34 of r2) {
const i3 = n2, r3 = dM(e34), s3 = f2.getObjectsInBounds(r3, i3 + e34.thickness / 2);
if (e34.x1 !== e34.x2 || e34.y1 !== e34.y2)
for (const r4 of s3) {
if (!cP(r4).includes(e34.layer))
continue;
if (r4.type === "pcb_keepout" && (m2.get(r4.pcb_keepout_id) ?? []).some((n3) => t2.areIdsConnected(e34.pcb_trace_id, n3)))
continue;
if (r4.type === "pcb_trace_segment") {
const i4 = r4;
if (e34.layer !== i4.layer)
continue;
if (t2.areIdsConnected(e34.pcb_trace_id, i4.pcb_trace_id))
continue;
const s5 = kt({ x: e34.x1, y: e34.y1 }, { x: e34.x2, y: e34.y2 }, { x: i4.x1, y: i4.y1 }, { x: i4.x2, y: i4.y2 }) - e34.thickness / 2 - i4.thickness / 2;
if (s5 > n2 - gP)
continue;
const a4 = `overlap_${e34.pcb_trace_id}_${i4.pcb_trace_id}`, c3 = `overlap_${i4.pcb_trace_id}_${e34.pcb_trace_id}`;
if (b2.has(a4))
continue;
if (b2.has(c3))
continue;
b2.add(a4), o2.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", message: y2(_2(e34.pcb_trace_id), _2(i4.pcb_trace_id), s5), pcb_trace_id: e34.pcb_trace_id, source_trace_id: "", pcb_trace_error_id: a4, pcb_component_ids: [], center: EP(e34, i4), pcb_port_ids: LP([e34._pcbTrace, i4._pcbTrace]) });
continue;
}
const s4 = OC(r4);
if (t2.areIdsConnected(e34.pcb_trace_id, "pcb_trace_id" in r4 ? r4.pcb_trace_id : s4))
continue;
if (r4.type === "pcb_smtpad" || r4.type === "pcb_plated_hole" || r4.type === "pcb_via") {
const { gap: t3, center: n3 } = TP(e34, r4);
if (!RP(t3))
continue;
const i4 = `overlap_${e34.pcb_trace_id}_${s4}`;
if (b2.has(i4))
continue;
b2.add(i4), o2.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", message: y2(_2(e34.pcb_trace_id), `${r4.type} "${_2(s4)}"`, t3), pcb_trace_id: e34.pcb_trace_id, center: n3, source_trace_id: "", pcb_trace_error_id: i4, pcb_component_ids: ["pcb_component_id" in r4 ? r4.pcb_component_id : undefined].filter(Boolean), pcb_port_ids: [...LP([e34._pcbTrace]), "pcb_port_id" in r4 ? r4.pcb_port_id : undefined].filter(Boolean) });
continue;
}
if (r4.type === "pcb_hole") {
const { gap: t3, center: n3 } = cM(e34, h2.get(r4.pcb_hole_id));
if (!RP(t3))
continue;
const i4 = `overlap_${e34.pcb_trace_id}_${s4}`;
if (b2.has(i4))
continue;
b2.add(i4), o2.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", message: y2(_2(e34.pcb_trace_id), `${r4.type} "${_2(s4)}"`, t3), pcb_trace_id: e34.pcb_trace_id, source_trace_id: e34._pcbTrace.source_trace_id ?? "", pcb_trace_error_id: i4, pcb_component_ids: r4.pcb_component_id ? [r4.pcb_component_id] : [], pcb_port_ids: LP([e34._pcbTrace]), center: n3 });
continue;
}
const a3 = Dt({ x: e34.x1, y: e34.y1 }, { x: e34.x2, y: e34.y2 }, dM(r4)) - e34.thickness / 2;
if (a3 + gP < i3) {
const t3 = `overlap_${e34.pcb_trace_id}_${s4}`;
if (b2.has(t3))
continue;
if (b2.add(t3), r4.type === "pcb_keepout" && r4.warning_only) {
o2.push({ type: "pcb_keepout_overlap_warning", warning_type: "pcb_keepout_overlap_warning", pcb_keepout_overlap_warning_id: `pcb_keepout_overlap_warning_${t3}`, pcb_keepout_id: r4.pcb_keepout_id, pcb_trace_ids: [e34.pcb_trace_id], message: `PCB trace ${_2(e34.pcb_trace_id)} violates advisory PCB keepout "${r4.description ?? r4.pcb_keepout_id}"`, center: hM(e34, dM(r4)), subcircuit_id: e34._pcbTrace.subcircuit_id ?? r4.subcircuit_id });
continue;
}
o2.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", message: y2(_2(e34.pcb_trace_id), `${r4.type} "${_2(OC(r4))}"`, a3), pcb_trace_id: e34.pcb_trace_id, source_trace_id: "", pcb_trace_error_id: t3, pcb_component_ids: ["pcb_component_id" in r4 ? r4.pcb_component_id : undefined].filter(Boolean), center: hM(e34, dM(r4)), pcb_port_ids: [...LP([e34._pcbTrace]), "pcb_port_id" in r4 ? r4.pcb_port_id : undefined].filter(Boolean) });
}
}
}
return o2;
}
function mM(e33, t2) {
return Math.hypot(e33.x - t2.x, e33.y - t2.y);
}
function gM(e33, t2) {
return mM(e33, t2) <= gP;
}
function fM(e33, { connMap: t2, minClearance: n2 } = {}) {
const o2 = e33.filter((e34) => e34.type === "pcb_via");
if (o2.length < 2)
return [];
const i2 = fP(e33);
n2 ??= _P(i2, "min_via_hole_edge_to_via_hole_edge_clearance") ?? lP, t2 ??= ni(e33);
const r2 = [], s2 = new Set;
for (let i3 = 0;i3 < o2.length; i3++)
for (let a2 = i3 + 1;a2 < o2.length; a2++) {
const c2 = o2[i3], l2 = o2[a2];
if (gM(c2, l2))
continue;
if (!t2.areIdsConnected(c2.pcb_via_id, l2.pcb_via_id))
continue;
const h2 = mM(c2, l2) - c2.hole_diameter / 2 - l2.hole_diameter / 2;
if (h2 + gP >= n2)
continue;
const d2 = [c2.pcb_via_id, l2.pcb_via_id].sort().join("_");
s2.has(d2) || (s2.add(d2), r2.push({ type: "pcb_via_clearance_error", pcb_error_id: `same_net_vias_close_${d2}`, message: `Vias ${SC(e33, c2.pcb_via_id)} and ${SC(e33, l2.pcb_via_id)} are too close together (gap: ${h2.toFixed(3)}mm)`, error_type: "pcb_via_clearance_error", pcb_via_ids: [c2.pcb_via_id, l2.pcb_via_id], minimum_clearance: n2, actual_clearance: h2, pcb_center: { x: (c2.x + l2.x) / 2, y: (c2.y + l2.y) / 2 } }));
}
return r2;
}
function _M(e33, { connMap: t2, minClearance: n2 } = {}) {
const o2 = e33.filter((e34) => e34.type === "pcb_via");
if (o2.length < 2)
return [];
const i2 = fP(e33);
n2 ??= _P(i2, "min_via_hole_edge_to_via_hole_edge_clearance") ?? lP;
const r2 = _P(i2, "min_pad_edge_to_pad_edge_clearance") ?? uP;
t2 ??= ni(e33);
const s2 = [], a2 = new Set;
for (let i3 = 0;i3 < o2.length; i3++)
for (let c2 = i3 + 1;c2 < o2.length; c2++) {
const l2 = o2[i3], h2 = o2[c2];
if (t2.areIdsConnected(l2.pcb_via_id, h2.pcb_via_id))
continue;
const d2 = mM(l2, h2);
let u2 = d2 - l2.hole_diameter / 2 - h2.hole_diameter / 2, p2 = n2;
if (u2 + gP >= p2) {
if (!l2.layers.some((e34) => h2.layers.includes(e34)))
continue;
if (u2 = d2 - l2.outer_diameter / 2 - h2.outer_diameter / 2, p2 = r2, u2 >= 0 && u2 + gP >= p2)
continue;
}
const m2 = [l2.pcb_via_id, h2.pcb_via_id].sort().join("_");
a2.has(m2) || (a2.add(m2), s2.push({ type: "pcb_via_clearance_error", pcb_error_id: `different_net_vias_close_${m2}`, message: `Vias ${SC(e33, l2.pcb_via_id)} and ${SC(e33, h2.pcb_via_id)} from different nets are too close together (gap: ${u2.toFixed(3)}mm)`, error_type: "pcb_via_clearance_error", pcb_via_ids: [l2.pcb_via_id, h2.pcb_via_id], minimum_clearance: p2, actual_clearance: u2, pcb_center: { x: (l2.x + h2.x) / 2, y: (l2.y + h2.y) / 2 } }));
}
return s2;
}
var yM = 0.000000001;
function bM({ point: e33, width: t2, ownerTrace: n2, index: o2, connectivity: i2 }) {
if (e33.route_type !== "wire" || !Number.isFinite(t2) || t2 <= 0)
return false;
const r2 = i2.getNetConnectedToId(n2.pcb_trace_id);
return !!r2 && (o2.get(r2)?.get(e33.layer) ?? []).some((o3) => {
if (o3.ownerTraceId === n2.pcb_trace_id)
return false;
if (!o3.touchesPad && ![...o3.touchingTraceIds].some((e34) => e34 !== n2.pcb_trace_id))
return false;
const i3 = o3.radius === undefined ? 0 : o3.radius + t2 / 2;
return Math.hypot(e33.x - o3.x, e33.y - o3.y) <= i3 + yM;
});
}
function xM(e33, t2) {
return e33.route_type === "wire" && cP(t2).includes(e33.layer) && aP(e33, t2);
}
function vM(e33, t2) {
if (e33.route_thickness_mode === "interpolated")
return;
let n2 = t2 === "start" ? 0 : e33.route.length - 2;
const o2 = t2 === "start" ? 1 : -1;
for (;n2 >= 0 && n2 < e33.route.length - 1; ) {
const t3 = e33.route[n2], i2 = e33.route[n2 + 1];
if (t3?.route_type !== "wire" || i2?.route_type !== "wire" || t3.layer !== i2.layer)
return;
if (Math.hypot(t3.x - i2.x, t3.y - i2.y) > 0.000000001)
return t3.width;
n2 += o2;
}
}
function IM({ point: e33, endpointTraceCopperWidth: t2, ownerTrace: n2, traceWireSegmentsByNetAndLayer: o2, fullConnectivityMap: i2 }) {
if (e33.route_type !== "wire")
return false;
const r2 = i2.getNetConnectedToId(n2.pcb_trace_id);
if (!r2)
return false;
const s2 = o2.get(r2)?.get(e33.layer) ?? [];
for (const o3 of s2) {
if (o3.trace.pcb_trace_id === n2.pcb_trace_id)
continue;
const i3 = t2 / 2 + o3.start.width / 2 + 0.000000001;
if (xt(e33, o3.start, o3.end) <= i3)
return true;
}
return false;
}
function SM(e33) {
return e33.route_type === "through_pad" ? { x: (e33.start.x + e33.end.x) / 2, y: (e33.start.y + e33.end.y) / 2 } : { x: e33.x, y: e33.y };
}
function CM(e33, t2, n2, o2) {
return t2.some((t3) => {
if (!t3.pcb_port_id || t3.pcb_port_id === n2)
return false;
const i2 = o2.get(t3.pcb_port_id);
return i2?.some((t4) => xM(e33, t4)) ?? false;
});
}
function PM({ firstPoint: e33, lastPoint: t2, port: n2, expectedPorts: o2, padMap: i2 }) {
let r2;
const s2 = e33.route_type === "wire" ? e33 : undefined, a2 = t2.route_type === "wire" ? t2 : undefined, c2 = kP(e33).includes(n2.pcb_port_id), l2 = kP(t2).includes(n2.pcb_port_id);
c2 && s2 ? r2 = s2 : l2 && a2 || CM(e33, o2, n2.pcb_port_id, i2) && a2 ? r2 = a2 : CM(t2, o2, n2.pcb_port_id, i2) && s2 ? r2 = s2 : s2 && a2 ? r2 = mM(s2, n2) <= mM(a2, n2) ? s2 : a2 : s2 ? r2 = s2 : a2 && (r2 = a2);
const h2 = SM(e33), d2 = SM(t2);
return r2 ? { x: r2.x, y: r2.y } : { x: (h2.x + d2.x) / 2, y: (h2.y + d2.y) / 2 };
}
function MM(e33, { connMap: t2, pcbConnectivityMap: n2 } = {}) {
const o2 = function(e34) {
const t3 = iM(e34);
return e34.flatMap((e35) => e35.type !== "pcb_trace" ? [] : e35.route.flatMap((n3, o3) => n3.route_type !== "wire" ? [] : [...new Set([n3.start_pcb_port_id, n3.end_pcb_port_id])].flatMap((i3) => {
if (!i3 || t3.canConnect(n3, i3))
return [];
const r3 = t3.ports.get(i3);
return [{ trace: e35, point: n3, index: o3, port: r3, padLayers: t3.layersForPort(r3) }];
})));
}(e33).map(({ trace: t3, point: n3, index: o3, port: i3, padLayers: r3 }) => ({ type: "pcb_trace_error", error_type: "pcb_trace_error", pcb_trace_error_id: `missing_layer_connection_${t3.pcb_trace_id}_${o3}_${i3.pcb_port_id}`, pcb_trace_id: t3.pcb_trace_id, source_trace_id: t3.source_trace_id ?? `!${t3.pcb_trace_id}`, pcb_port_ids: [i3.pcb_port_id], pcb_component_ids: i3.pcb_component_id ? [i3.pcb_component_id] : [], center: { x: n3.x, y: n3.y }, message: `Trace [${IC(e33, t3.pcb_trace_id)}] on ${n3.layer} is missing a via connection to port [${vC(e33, i3.pcb_port_id)}] on ${r3.join(", ")}.` })), i2 = e33.filter((e34) => e34.type === "pcb_port"), r2 = e33.filter((e34) => e34.type === "pcb_trace"), s2 = e33.filter((e34) => e34.type === "source_trace"), a2 = e33.filter((e34) => e34.type === "pcb_smtpad"), c2 = e33.filter((e34) => e34.type === "pcb_plated_hole"), l2 = new Map;
n2 ??= function(e34) {
const t3 = new oi;
t3.circuitJson = e34;
for (const n4 of e34)
n4.type === "pcb_trace" ? t3.traceIdToElm.set(n4.pcb_trace_id, n4) : n4.type === "pcb_port" && t3.portIdToElm.set(n4.pcb_port_id, n4);
const n3 = [...t3.traceIdToElm.values()], o3 = new Map;
for (const [e35, t4] of n3.entries()) {
const n4 = new Map;
for (let o4 = 0;o4 < t4.route.length - 1; o4++) {
const i4 = t4.route[o4], r4 = t4.route[o4 + 1];
if (i4.route_type !== "wire" || r4.route_type !== "wire" || i4.layer !== r4.layer)
continue;
const s4 = n4.get(i4.layer) ?? { traceIndex: e35, minX: 1 / 0, minY: 1 / 0, maxX: -1 / 0, maxY: -1 / 0 }, a4 = i4.width / 2 + 0.000000001;
s4.minX = Math.min(s4.minX, i4.x - a4, r4.x - a4), s4.minY = Math.min(s4.minY, i4.y - a4, r4.y - a4), s4.maxX = Math.max(s4.maxX, i4.x + a4, r4.x + a4), s4.maxY = Math.max(s4.maxY, i4.y + a4, r4.y + a4), n4.set(i4.layer, s4);
}
for (const [e36, t5] of n4) {
const n5 = o3.get(e36) ?? [];
n5.push(t5), o3.set(e36, n5);
}
}
const i3 = n3.map(() => new Set);
for (const e35 of o3.values()) {
const t4 = new je(e35.length);
for (const n4 of e35)
t4.add(n4.minX, n4.minY, n4.maxX, n4.maxY);
t4.finish();
for (const n4 of e35)
for (const o4 of t4.search(n4.minX, n4.minY, n4.maxX, n4.maxY)) {
const t5 = e35[o4].traceIndex;
t5 > n4.traceIndex && i3[n4.traceIndex].add(t5);
}
}
const r3 = [];
for (const [e35, o4] of i3.entries())
for (const i4 of [...o4].sort((e36, t4) => e36 - t4))
t3._arePcbTracesConnected(n3[e35], n3[i4]) && r3.push([n3[e35].pcb_trace_id, n3[i4].pcb_trace_id]);
const s3 = iM(e34), a3 = new Map;
for (const e35 of n3)
for (const n4 of e35.route)
if (n4.route_type === "wire")
for (const o4 of new Set([n4.start_pcb_port_id, n4.end_pcb_port_id])) {
if (!o4 || !t3.portIdToElm.has(o4))
continue;
if (!s3.canConnect(n4, o4))
continue;
const i4 = a3.get(o4) ?? [];
i4.push(n4.start_pcb_port_id === o4 ? [o4, e35.pcb_trace_id] : [e35.pcb_trace_id, o4]), a3.set(o4, i4);
}
for (const e35 of t3.portIdToElm.keys())
for (const t4 of a3.get(e35) ?? [])
r3.push(t4);
return r3.push(...rM(e34)), t3.connMap = new ti(ei(r3)), t3;
}(e33);
let h2, d2 = t2;
const u2 = () => (d2 ??= ni(e33), d2), p2 = () => (h2 ??= function(e34, t3) {
const n3 = new Map;
for (const o3 of e34) {
if (o3.route_thickness_mode === "interpolated")
continue;
const e35 = t3.getNetConnectedToId(o3.pcb_trace_id);
if (e35)
for (let t4 = 0;t4 < o3.route.length - 1; t4++) {
const i3 = o3.route[t4], r3 = o3.route[t4 + 1];
if (i3.route_type !== "wire" || r3.route_type !== "wire")
continue;
if (i3.layer !== r3.layer)
continue;
if (Math.hypot(i3.x - r3.x, i3.y - r3.y) <= 0.000000001)
continue;
const s3 = n3.get(e35) ?? new Map, a3 = s3.get(i3.layer) ?? [];
a3.push({ trace: o3, start: i3, end: r3 }), s3.set(i3.layer, a3), n3.set(e35, s3);
}
}
return n3;
}(r2, u2()), h2);
let m2;
const g2 = () => (m2 ??= function(e34, t3) {
const n3 = new Map, o3 = MP(e34), i3 = e34.filter((e35) => e35.type === "pcb_trace"), r3 = e34.filter((e35) => e35.type === "pcb_via"), s3 = e34.find((e35) => e35.type === "pcb_board"), a3 = s3?.num_layers, c3 = ["top", ...Yb.filter((e35) => e35.startsWith("inner")).slice(0, a3 === undefined ? undefined : Math.max(0, a3 - 2)), ...a3 === 1 ? [] : ["bottom"]], l3 = (e35, r4, s4) => {
if (![s4.x, s4.y].every(Number.isFinite))
return;
const a4 = t3.getNetConnectedToId(e35);
if (!a4)
return;
const c4 = o3.some((n4) => {
if (t3.getNetConnectedToId(OC(n4)) !== a4 || !cP(n4).some((e36) => r4.includes(e36)))
return false;
if (s4.radius === undefined)
return aP(s4, n4);
const o4 = { type: "pcb_via", pcb_via_id: e35, x: s4.x, y: s4.y, outer_diameter: 2 * s4.radius, hole_diameter: 0, layers: r4 };
return PP(o4, n4) <= yM;
}), l4 = new Set;
for (const e36 of i3)
if (e36.route_thickness_mode !== "interpolated" && t3.getNetConnectedToId(e36.pcb_trace_id) === a4)
for (let t4 = 1;t4 < e36.route.length; t4++) {
const n4 = e36.route[t4 - 1], o4 = e36.route[t4];
if (n4.route_type !== "wire" || o4.route_type !== "wire" || n4.layer !== o4.layer || !r4.includes(n4.layer) || !Number.isFinite(n4.width) || n4.width <= 0 || Math.hypot(n4.x - o4.x, n4.y - o4.y) <= yM)
continue;
const i4 = s4.radius === undefined ? 0 : s4.radius + n4.width / 2;
if (xt(s4, n4, o4) <= i4 + yM) {
l4.add(e36.pcb_trace_id);
break;
}
}
const h3 = { ...s4, touchesPad: c4, touchingTraceIds: l4 }, d3 = n3.get(a4) ?? new Map;
for (const e36 of r4) {
const t4 = d3.get(e36) ?? [];
t4.push(h3), d3.set(e36, t4);
}
n3.set(a4, d3);
};
for (const e35 of r3)
!Number.isFinite(e35.outer_diameter) || e35.outer_diameter <= 0 || l3(e35.pcb_via_id, cP(e35), { x: e35.x, y: e35.y, ownerTraceId: e35.pcb_trace_id, radius: e35.outer_diameter / 2 });
for (const n4 of e34)
if (n4.type === "pcb_trace")
for (const e35 of n4.route) {
if (e35.route_type !== "via")
continue;
if (r3.some((o5) => Math.hypot(o5.x - e35.x, o5.y - e35.y) <= yM && (o5.pcb_trace_id === n4.pcb_trace_id || !o5.pcb_trace_id && t3.areIdsConnected(o5.pcb_via_id, n4.pcb_trace_id))))
continue;
const o4 = c3.indexOf(e35.from_layer), i4 = c3.indexOf(e35.to_layer);
if (o4 < 0 || i4 < 0)
continue;
const s4 = e35.outer_diameter;
s4 !== undefined && (!Number.isFinite(s4) || s4 <= 0) || l3(n4.pcb_trace_id, c3.slice(Math.min(o4, i4), Math.max(o4, i4) + 1), { x: e35.x, y: e35.y, ownerTraceId: n4.pcb_trace_id, radius: s4 === undefined ? undefined : s4 / 2 });
}
return n3;
}(e33, u2()), m2), f2 = new Set;
for (const e34 of a2)
e34.pcb_port_id && l2.set(e34.pcb_port_id, [...l2.get(e34.pcb_port_id) ?? [], e34]);
for (const e34 of c2)
e34.pcb_port_id && l2.set(e34.pcb_port_id, [...l2.get(e34.pcb_port_id) ?? [], e34]);
const _2 = new Map, y2 = new Map;
for (const e34 of r2) {
const t3 = new Set, n3 = e34.route[0], o3 = e34.route.at(-1);
for (const e35 of [n3, o3])
if (e35)
for (const [n4, o4] of l2)
o4.some((t4) => xM(e35, t4)) && t3.add(n4);
_2.set(e34.pcb_trace_id, t3);
for (const n4 of t3) {
const t4 = y2.get(n4) ?? new Set;
t4.add(e34.pcb_trace_id), y2.set(n4, t4);
}
}
const b2 = new Map, x2 = (e34) => {
const t3 = b2.get(e34.pcb_trace_id);
if (t3)
return t3;
const o3 = new Set, i3 = [e34.pcb_trace_id];
for (;i3.length > 0; ) {
const e35 = i3.pop();
if (!o3.has(e35)) {
o3.add(e35);
for (const t4 of n2.getAllTracesConnectedToTrace(e35))
o3.has(t4.pcb_trace_id) || i3.push(t4.pcb_trace_id);
for (const t4 of _2.get(e35) ?? [])
for (const e36 of y2.get(t4) ?? [])
o3.has(e36) || i3.push(e36);
}
}
const s3 = r2.filter((e35) => o3.has(e35.pcb_trace_id));
for (const e35 of s3)
b2.set(e35.pcb_trace_id, s3);
return s3;
};
for (const t3 of r2) {
if (t3.route.length === 0)
continue;
const n3 = t3.route[0], r3 = t3.route[t3.route.length - 1], a3 = s2.find((e34) => e34.source_trace_id === t3.source_trace_id), c3 = a3 ? i2.filter((e34) => a3.connected_source_port_ids?.includes(e34.source_port_id)) : [];
for (let n4 = 1;n4 < t3.route.length - 1; n4++) {
const i3 = t3.route[n4 - 1], r4 = t3.route[n4], s3 = t3.route[n4 + 1];
if (r4.route_type === "via") {
const c4 = i3.route_type === "wire", l3 = s3.route_type === "wire";
if (c4 && l3) {
const c5 = Math.abs(i3.x - r4.x) < 0.01 && Math.abs(i3.y - r4.y) < 0.01, l4 = Math.abs(s3.x - r4.x) < 0.01 && Math.abs(s3.y - r4.y) < 0.01;
if (!c5 || !l4) {
const i4 = IC(e33, t3.pcb_trace_id);
o2.push({ type: "pcb_trace_error", message: `Via in trace [${i4}] is misaligned at position {x: ${r4.x}, y: ${r4.y}}.`, source_trace_id: a3?.source_trace_id || t3.source_trace_id || `!${t3.pcb_trace_id}`, error_type: "pcb_trace_error", pcb_trace_id: t3.pcb_trace_id, pcb_trace_error_id: `misaligned_via_${t3.pcb_trace_id}_${n4}`, pcb_component_ids: [], pcb_port_ids: [] });
}
}
}
}
const h3 = IC(e33, t3.pcb_trace_id);
if (a3 && c3.length > 0) {
if (f2.has(a3.source_trace_id))
continue;
f2.add(a3.source_trace_id);
}
for (const i3 of c3) {
if (!i3.pcb_port_id)
continue;
const s3 = l2.get(i3.pcb_port_id);
if (!s3?.length)
continue;
if (x2(t3).some((e34) => _2.get(e34.pcb_trace_id)?.has(i3.pcb_port_id)))
continue;
const d3 = s3.some((e34) => xM(n3, e34)), u3 = s3.some((e34) => xM(r3, e34));
if (!d3 && !u3) {
const d4 = vC(e33, i3.pcb_port_id).replace("pcb_port", ""), u4 = s3[0].type.replace(/pcb_/, ""), p3 = PM({ firstPoint: n3, lastPoint: r3, port: i3, expectedPorts: c3, padMap: l2 });
o2.push({ type: "pcb_trace_error", message: `Trace [${h3}] is missing a connection to ${u4}${d4}`, source_trace_id: a3?.source_trace_id || t3.source_trace_id || `!${t3.pcb_trace_id}`, error_type: "pcb_trace_error", pcb_trace_id: t3.pcb_trace_id, pcb_trace_error_id: `missing_connection_${t3.pcb_trace_id}_${i3.pcb_port_id}`, center: p3, pcb_component_ids: [], pcb_port_ids: [i3.pcb_port_id] });
}
}
if (c3.length === 0) {
let e34 = false, i3 = false;
for (const t4 of l2.values())
t4.some((e35) => xM(n3, e35)) && (e34 = true), t4.some((e35) => xM(r3, e35)) && (i3 = true);
const s3 = e34 ? undefined : vM(t3, "start"), c4 = i3 ? undefined : vM(t3, "end"), d3 = s3 !== undefined && IM({ point: n3, endpointTraceCopperWidth: s3, ownerTrace: t3, traceWireSegmentsByNetAndLayer: p2(), fullConnectivityMap: u2() }), m3 = c4 !== undefined && IM({ point: r3, endpointTraceCopperWidth: c4, ownerTrace: t3, traceWireSegmentsByNetAndLayer: p2(), fullConnectivityMap: u2() }), f3 = e34 || d3 || s3 !== undefined && bM({ point: n3, width: s3, ownerTrace: t3, index: g2(), connectivity: u2() }), _3 = i3 || m3 || c4 !== undefined && bM({ point: r3, width: c4, ownerTrace: t3, index: g2(), connectivity: u2() }), y3 = n3.route_type === "wire" && r3.route_type === "wire" && n3.layer === r3.layer && Math.hypot(n3.x - r3.x, n3.y - r3.y) <= 0.000000001;
f3 || n3.route_type !== "wire" || o2.push({ type: "pcb_trace_error", message: `Trace [${h3}] has disconnected endpoint at (${n3.x.toFixed(2)}, ${n3.y.toFixed(2)})`, source_trace_id: a3?.source_trace_id || t3.source_trace_id || `!${t3.pcb_trace_id}`, error_type: "pcb_trace_error", pcb_trace_id: t3.pcb_trace_id, pcb_trace_error_id: `disconnected_endpoint_${t3.pcb_trace_id}_start`, center: { x: n3.x, y: n3.y }, pcb_component_ids: [], pcb_port_ids: [] }), _3 || r3.route_type !== "wire" || y3 && !f3 || o2.push({ type: "pcb_trace_error", message: `Trace [${h3}] has disconnected endpoint at (${r3.x.toFixed(2)}, ${r3.y.toFixed(2)})`, source_trace_id: a3?.source_trace_id || t3.source_trace_id || `!${t3.pcb_trace_id}`, error_type: "pcb_trace_error", pcb_trace_id: t3.pcb_trace_id, pcb_trace_error_id: `disconnected_endpoint_${t3.pcb_trace_id}_end`, center: { x: r3.x, y: r3.y }, pcb_component_ids: [], pcb_port_ids: [] });
}
}
return o2;
}
function wM(e33, t2 = {}) {
const n2 = [], o2 = fP(e33);
if (!o2)
return n2;
const i2 = t2.margin ?? _P(o2, "min_board_edge_clearance") ?? pP, r2 = function(e34) {
if (e34.outline && e34.outline.length > 0)
return e34.outline.map((e35) => ({ x: e35.x, y: e35.y }));
if (e34.center && typeof e34.width == "number" && typeof e34.height == "number") {
const t3 = e34.center.x, n3 = e34.center.y, o3 = e34.width / 2, i3 = e34.height / 2;
return [{ x: t3 - o3, y: n3 - i3 }, { x: t3 + o3, y: n3 - i3 }, { x: t3 + o3, y: n3 + i3 }, { x: t3 - o3, y: n3 + i3 }];
}
return null;
}(o2);
if (!r2)
return n2;
const s2 = _C(e33).pcb_trace.list();
for (const e34 of s2)
if (!(e34.route.length < 2))
for (let t3 = 0;t3 < e34.route.length - 1; t3++) {
const o3 = e34.route[t3], s3 = e34.route[t3 + 1];
if (o3.route_type !== "wire" || s3.route_type !== "wire")
continue;
const a2 = "width" in o3 ? o3.width : ("width" in s3) ? s3.width : 0.1, c2 = { x: o3.x, y: o3.y }, l2 = { x: s3.x, y: s3.y };
let h2 = Number.POSITIVE_INFINITY;
for (let e35 = 0;e35 < r2.length; e35++) {
const t4 = kt(c2, l2, r2[e35], r2[(e35 + 1) % r2.length]);
t4 < h2 && (h2 = t4);
}
const d2 = a2 / 2 + i2;
if (h2 < d2) {
const o4 = { type: "pcb_trace_error", error_type: "pcb_trace_error", pcb_trace_error_id: `trace_too_close_to_board_${e34.pcb_trace_id}_segment_${t3}`, message: `Trace too close to board edge (${h2.toFixed(3)}mm < ${d2.toFixed(3)}mm required, margin: ${i2}mm)`, pcb_trace_id: e34.pcb_trace_id, source_trace_id: e34.source_trace_id || "", center: { x: (c2.x + l2.x) / 2, y: (c2.y + l2.y) / 2 }, pcb_component_ids: [], pcb_port_ids: [] };
n2.push(o4);
}
}
return n2;
}
function NM(e33, { connMap: t2, minClearance: n2 } = {}) {
const o2 = MP(e33), i2 = wP(e33);
if (o2.length === 0 || i2.length === 0)
return [];
const r2 = fP(e33);
n2 ??= _P(r2, "min_trace_to_pad_edge_clearance") ?? dP, t2 ??= ni(e33);
const s2 = new lM({ objects: o2, getBounds: yP, getId: (e34) => OC(e34) }), a2 = new Map, c2 = new Set;
for (const o3 of i2) {
const i3 = s2.getObjectsInBounds(dM(o3), n2 + o3.thickness / 2);
for (const r3 of i3) {
const i4 = OC(r3);
if (!cP(r3).includes(o3.layer))
continue;
if (t2.areIdsConnected(o3.pcb_trace_id, i4))
continue;
const s3 = `${i4}_${o3.pcb_trace_id}`, { gap: l2, center: h2 } = TP(o3, r3);
if (RP(l2)) {
a2.delete(s3), c2.add(s3);
continue;
}
if (c2.has(s3))
continue;
if (l2 + gP >= n2)
continue;
const d2 = { type: "pcb_pad_trace_clearance_error", pcb_pad_trace_clearance_error_id: `pad_trace_clearance_${s3}`, error_type: "pcb_pad_trace_clearance_error", message: `Pad ${SC(e33, i4)} and trace ${SC(e33, o3.pcb_trace_id)} are too close (clearance: ${J_(l2)}, minimum: ${J_(n2)})`, pcb_pad_id: i4, pcb_trace_id: o3.pcb_trace_id, minimum_clearance: n2, actual_clearance: l2, center: h2 }, u2 = a2.get(s3);
(!u2 || l2 < u2.gap) && a2.set(s3, { error: d2, gap: l2 });
}
}
return Array.from(a2.values()).map(({ error: e34 }) => e34);
}
function TM(e33, { connMap: t2, minClearance: n2 } = {}) {
const o2 = e33.filter((e34) => e34.type === "pcb_via"), i2 = wP(e33);
if (o2.length === 0 || i2.length === 0)
return [];
const r2 = fP(e33);
n2 ??= _P(r2, "min_trace_to_pad_edge_clearance") ?? dP, t2 ??= ni(e33);
const s2 = new Map, a2 = new Set;
for (const r3 of o2)
for (const o3 of i2) {
if (!cP(r3).includes(o3.layer))
continue;
if (t2.areIdsConnected(o3.pcb_trace_id, r3.pcb_via_id))
continue;
const i3 = `${r3.pcb_via_id}_${o3.pcb_trace_id}`, { gap: c2, center: l2 } = TP(o3, r3);
if (RP(c2)) {
s2.delete(i3), a2.add(i3);
continue;
}
if (a2.has(i3))
continue;
if (c2 + gP >= n2)
continue;
const h2 = { type: "pcb_via_trace_clearance_error", pcb_via_trace_clearance_error_id: `via_trace_clearance_${i3}`, error_type: "pcb_via_trace_clearance_error", message: `Via ${SC(e33, r3.pcb_via_id)} and trace ${SC(e33, o3.pcb_trace_id)} are too close (clearance: ${J_(c2)}, minimum: ${J_(n2)})`, pcb_via_id: r3.pcb_via_id, pcb_trace_id: o3.pcb_trace_id, minimum_clearance: n2, actual_clearance: c2, center: l2 }, d2 = s2.get(i3);
(!d2 || c2 < d2.gap) && s2.set(i3, { error: h2, gap: c2 });
}
return Array.from(s2.values()).map(({ error: e34 }) => e34);
}
var RM = (e33, t2 = {}) => {
const n2 = ((e34) => {
const t3 = ni(e34), n3 = e34.filter((e35) => e35.type === "pcb_via" && typeof e35.pcb_trace_id == "string").map((e35) => [e35.pcb_via_id, e35.pcb_trace_id]);
return t3.addConnections(n3), t3;
})(e33), o2 = Math.max(t2.viaClearance ?? 0.1, 0.1), i2 = pM(e33, { connMap: n2, minClearance: t2.traceClearance }).filter((e34) => e34.type !== "pcb_keepout_overlap_warning"), r2 = t2.includeTypedTraceClearance !== false, s2 = r2 ? TM(e33, { connMap: n2, minClearance: t2.traceClearance }) : [], a2 = r2 ? NM(e33, { connMap: n2, minClearance: t2.traceClearance }) : [], c2 = function(e34, { minClearance: t3 } = {}) {
const n3 = t3 ?? _P(fP(e34), "min_trace_to_hole_edge_clearance") ?? hP;
if (!Number.isFinite(n3) || n3 < 0)
throw new Error("Trace-to-hole clearance must be finite and non-negative");
const o3 = aM(e34);
if (o3.length === 0)
return [];
const i3 = new lM({ objects: o3, getId: (e35) => e35.elementId, getBounds: (e35) => ({ minX: e35.bounds.xmin, minY: e35.bounds.ymin, maxX: e35.bounds.xmax, maxY: e35.bounds.ymax }) }), r3 = new Map, s3 = new Set;
for (const t4 of e34)
if (t4.type === "pcb_trace")
for (let e35 = 1;e35 < t4.route.length; e35++) {
const o4 = t4.route[e35 - 1], a3 = t4.route[e35];
if (o4.route_type !== "wire" && o4.route_type !== "via" || a3.route_type !== "wire" && a3.route_type !== "via")
continue;
if (o4.route_type !== "wire" && a3.route_type !== "wire")
continue;
if (o4.route_type === "wire" && a3.route_type === "wire" && o4.layer !== a3.layer)
continue;
const c3 = Math.max(o4.route_type === "wire" ? o4.width : 0, a3.route_type === "wire" ? a3.width : 0) / 2, l3 = i3.getObjectsInBounds({ minX: Math.min(o4.x, a3.x), minY: Math.min(o4.y, a3.y), maxX: Math.max(o4.x, a3.x), maxY: Math.max(o4.y, a3.y) }, n3 + c3);
for (const e36 of l3) {
const i4 = e36.sourceElement;
if (i4.type !== "pcb_hole")
continue;
const { gap: l4, center: h3 } = cM({ x1: o4.x, y1: o4.y, x2: a3.x, y2: a3.y, thickness: 2 * c3 }, e36), d3 = `${t4.pcb_trace_id}_${i4.pcb_hole_id}`;
RP(l4) ? (r3.delete(d3), s3.add(d3)) : s3.has(d3) || l4 + 0.000001 >= n3 || (r3.get(d3)?.gap ?? 1 / 0) <= l4 || r3.set(d3, { gap: l4, error: { type: "pcb_trace_error", error_type: "pcb_trace_error", pcb_trace_error_id: `overlap_${d3}`, pcb_trace_id: t4.pcb_trace_id, source_trace_id: t4.source_trace_id ?? "", pcb_component_ids: i4.pcb_component_id ? [i4.pcb_component_id] : [], pcb_port_ids: [], center: h3, message: `Trace ${t4.pcb_trace_id} is too close to non-plated hole ${i4.pcb_hole_id} (gap: ${l4.toFixed(6)}mm, required: ${n3}mm)` } });
}
}
return Array.from(r3.values(), ({ error: e35 }) => e35);
}(e33, { minClearance: t2.holeClearance }), l2 = [...fM(e33, { connMap: n2, minClearance: o2 }), ..._M(e33, { connMap: n2, minClearance: o2 })], h2 = [...i2, ...wM(e33), ...t2.includeTraceContinuity === false ? [] : MM(e33), ...s2, ...a2, ...c2, ...l2], d2 = e33.filter((e34) => e34.type === "pcb_via"), u2 = new Map(d2.map((e34) => [e34.pcb_via_id, e34])), p2 = h2.map((e34) => {
if (e34.type === "pcb_via_trace_clearance_error" && typeof e34.pcb_via_id == "string") {
const t3 = u2.get(e34.pcb_via_id);
if (t3)
return { ...e34, center: { x: t3.x, y: t3.y } };
}
if ("center" in e34 && e34.center)
return e34;
if ("pcb_center" in e34 && e34.pcb_center)
return { ...e34, center: e34.pcb_center };
if ("pcb_via_ids" in e34 && Array.isArray(e34.pcb_via_ids)) {
const [t3, n3] = e34.pcb_via_ids, o3 = u2.get(t3), i3 = u2.get(n3);
if (o3 && i3)
return { ...e34, center: { x: (o3.x + i3.x) / 2, y: (o3.y + i3.y) / 2 } };
}
if ("pcb_error_id" in e34 && typeof e34.pcb_error_id == "string" && (e34.pcb_error_id.startsWith("same_net_vias_close_") || e34.pcb_error_id.startsWith("different_net_vias_close_"))) {
const t3 = e34.pcb_error_id.replace("same_net_vias_close_", "").replace("different_net_vias_close_", "").split("_").filter(Boolean);
if (t3.length === 2) {
const n3 = u2.get(t3[0]), o3 = u2.get(t3[1]);
if (n3 && o3)
return { ...e34, center: { x: (n3.x + o3.x) / 2, y: (n3.y + o3.y) / 2 } };
}
}
return e34;
}), m2 = p2.filter((e34) => Boolean(e34.center));
return { errors: h2, errorsWithCenters: p2, locationAwareErrors: m2 };
};
var EM = (e33, t2) => e33 === 0 ? "top" : e33 === t2 - 1 ? "bottom" : `inner${e33}`;
var AM = (e33, t2) => {
if (e33.layers !== undefined)
return e33.layers;
if (!Number.isInteger(t2) || t2 < 1)
throw new Error(`Invalid board layer count: ${t2}`);
const n2 = Array.from({ length: t2 }, (e34, n3) => EM(n3, t2)), o2 = n2.findIndex((t3) => t3 === e33.from_layer), i2 = n2.findIndex((t3) => t3 === e33.to_layer);
if (o2 < 0 || i2 < 0)
throw new Error(`Via span ${e33.from_layer} -> ${e33.to_layer} is outside the board`);
return n2.slice(Math.min(o2, i2), Math.max(o2, i2) + 1);
};
var OM = (e33, t2, n2 = false) => {
const o2 = n2 ? e33 : { from_layer: "top", to_layer: EM(t2 - 1, t2) };
return AM(o2, t2);
};
var kM = 0.005;
var DM = 0.000001;
var LM = (e33, t2) => ({ minX: e33.minX - t2, minY: e33.minY - t2, maxX: e33.maxX + t2, maxY: e33.maxY + t2 });
var zM = (e33) => LM({ minX: Math.min(e33.start.x, e33.end.x), minY: Math.min(e33.start.y, e33.end.y), maxX: Math.max(e33.start.x, e33.end.x), maxY: Math.max(e33.start.y, e33.end.y) }, e33.width / 2);
var BM = (e33) => {
const t2 = e33.diameter / 2;
return { minX: e33.x - t2, minY: e33.y - t2, maxX: e33.x + t2, maxY: e33.y + t2 };
};
var FM = (e33) => Ht(E(e33.localToWorld, [{ x: -e33.width / 2, y: -e33.height / 2 }, { x: e33.width / 2, y: -e33.height / 2 }, { x: e33.width / 2, y: e33.height / 2 }, { x: -e33.width / 2, y: e33.height / 2 }]));
var jM = (e33) => ({ minX: -e33.width / 2, minY: -e33.height / 2, maxX: e33.width / 2, maxY: e33.height / 2 });
var $M = (e33, t2) => `${e33}:${t2}`;
var YM = class {
constructor(e33) {
this.cellSize = e33;
}
cellSize;
cells = new Map;
insert(e33, t2) {
const n2 = Math.floor(t2.minX / this.cellSize), o2 = Math.floor(t2.maxX / this.cellSize), i2 = Math.floor(t2.minY / this.cellSize), r2 = Math.floor(t2.maxY / this.cellSize);
for (let t3 = n2;t3 <= o2; t3 += 1)
for (let n3 = i2;n3 <= r2; n3 += 1) {
const o3 = $M(t3, n3), i3 = this.cells.get(o3);
i3 ? i3.push(e33) : this.cells.set(o3, [e33]);
}
}
query(e33) {
const t2 = Math.floor(e33.minX / this.cellSize), n2 = Math.floor(e33.maxX / this.cellSize), o2 = Math.floor(e33.minY / this.cellSize), i2 = Math.floor(e33.maxY / this.cellSize), r2 = new Set;
for (let e34 = t2;e34 <= n2; e34 += 1)
for (let t3 = o2;t3 <= i2; t3 += 1) {
const n3 = this.cells.get($M(e34, t3));
if (n3)
for (const e35 of n3)
r2.add(e35);
}
return [...r2];
}
};
var XM = (e33, t2) => {
const n2 = It(e33.start, e33.end, t2.start, t2.end);
if (n2)
return n2;
const o2 = [{ left: e33.start, right: Bt(e33.start, t2.start, t2.end) }, { left: e33.end, right: Bt(e33.end, t2.start, t2.end) }, { left: Bt(t2.start, e33.start, e33.end), right: t2.start }, { left: Bt(t2.end, e33.start, e33.end), right: t2.end }];
let i2 = { left: e33.start, right: t2.start }, r2 = Number.POSITIVE_INFINITY;
for (const e34 of o2) {
const t3 = Math.hypot(e34.left.x - e34.right.x, e34.left.y - e34.right.y);
t3 < r2 && (i2 = e34, r2 = t3);
}
return { x: (i2.left.x + i2.right.x) / 2, y: (i2.left.y + i2.right.y) / 2 };
};
var WM = (e33, t2) => {
const n2 = Bt(t2, e33.start, e33.end);
return { x: (n2.x + t2.x) / 2, y: (n2.y + t2.y) / 2 };
};
var VM = (e33, t2) => {
const n2 = Bt({ x: (t2.minX + t2.maxX) / 2, y: (t2.minY + t2.maxY) / 2 }, e33.start, e33.end), o2 = Math.max(t2.minX, Math.min(t2.maxX, n2.x)), i2 = Math.max(t2.minY, Math.min(t2.maxY, n2.y));
return { x: (n2.x + o2) / 2, y: (n2.y + i2) / 2 };
};
var HM = (e33) => {
const t2 = new Set;
for (const n2 of e33.route)
n2.route_type === "wire" && (n2.start_pcb_port_id && t2.add(n2.start_pcb_port_id), n2.end_pcb_port_id && t2.add(n2.end_pcb_port_id));
return [...t2];
};
var GM = (e33, t2, n2) => n2 < 0 ? `PCB trace ${e33} overlaps with ${t2} (accidental contact)` : `PCB trace ${e33} is too close to ${t2} (gap: ${n2.toFixed(3)}mm)`;
var UM = class {
constructor(e33, t2 = {}) {
if (this.srj = e33, this.traceClearance = t2.traceClearance ?? 0.1, this.viaClearance = Math.max(t2.viaClearance ?? 0.1, 0.1), this.viaToPadClearance = t2.viaToPadClearance ?? this.srj.minViaEdgeToPadEdgeClearance ?? 0.1, this.connMap = t2.connMap, this.includeTraceViaOwnerMetadata = t2.includeTraceViaOwnerMetadata ?? false, this.cellSize = t2.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 e33 = Math.max(0, this.srj.bounds.maxX - this.srj.bounds.minX), t2 = Math.max(0, this.srj.bounds.maxY - this.srj.bounds.minY);
return Math.max(0.25, Math.max(e33, t2) / 64, (this.srj.minViaDiameter ?? 0.3) + Math.max(this.traceClearance, this.viaToPadClearance));
}
compileConnectionAliases() {
const e33 = new Map;
for (const t2 of this.srj.connections) {
const n2 = t2.netConnectionName ?? t2.rootConnectionName ?? t2.name, o2 = [t2.name, t2.rootConnectionName, t2.netConnectionName, ...t2.mergedConnectionNames ?? [], ...t2.pointsToConnect.flatMap((e34) => [e34.pointId, e34.pcb_port_id])];
for (const t3 of o2) {
if (!t3)
continue;
this.canonicalNetByAlias.set(t3, n2);
const o3 = this.connMap?.getNetConnectedToId(t3);
if (!o3)
continue;
let i2 = e33.get(n2);
i2 || (i2 = new Set, e33.set(n2, i2)), i2.add(o3);
}
this.canonicalNetByAlias.set(n2, n2);
}
for (const [t2, n2] of e33)
n2.size === 1 && this.connMapNetByCanonicalNet.set(t2, n2.values().next().value);
}
resolveNetId(e33) {
const t2 = this.connMap?.getNetConnectedToId(e33);
if (t2)
return t2;
const n2 = this.canonicalNetByAlias.get(e33);
return n2 ? this.connMapNetByCanonicalNet.get(n2) ?? n2 : e33;
}
areConnected(e33, t2) {
return e33 === t2 || (!!this.connMap?.areIdsConnected(e33, t2) || this.resolveNetId(e33) === this.resolveNetId(t2));
}
compileStaticObstacles() {
const e33 = [], t2 = new Set, n2 = new Set;
for (const o2 of this.srj.obstacles) {
if (o2.layers.length === 0)
continue;
const i2 = o2.connectedTo.find((e34) => e34.startsWith("pcb_smtpad_")), r2 = o2.connectedTo.find((e34) => e34.startsWith("pcb_plated_hole_")), s2 = o2.connectedTo.find((e34) => e34.startsWith("pcb_port_"));
if (!i2 && !r2 && !s2)
continue;
const a2 = o2.layers.length > 1, c2 = a2 ? "pcb_plated_hole" : "pcb_smtpad", l2 = a2 ? r2 ?? `pcb_plated_hole_${o2.center.x.toFixed(3)}_${o2.center.y.toFixed(3)}` : i2 ?? `pcb_smtpad_${o2.center.x.toFixed(3)}_${o2.center.y.toFixed(3)}`, h2 = a2 ? n2 : t2;
if (h2.has(l2))
continue;
h2.add(l2);
const d2 = typeof o2.ccwRotationDegrees == "number" && Number.isFinite(o2.ccwRotationDegrees), u2 = L(k(o2.center.x, o2.center.y), $(d2 ? o2.ccwRotationDegrees : 0)), p2 = !d2 && a2 && Math.abs(o2.width - o2.height) < 0.001;
e33.push({ kind: "obstacle", obstacleType: c2, obstacleId: l2, connectedTo: o2.connectedTo, x: o2.center.x, y: o2.center.y, width: o2.width, height: o2.height, localToWorld: u2, worldToLocal: A(u2), ...p2 ? { radius: Math.max(o2.width, o2.height) / 2 } : {}, layers: o2.layers, ...s2 ? { pcbPortId: s2 } : {} });
}
return e33;
}
indexStaticObstacles() {
for (const e33 of this.obstacles) {
const t2 = LM(FM(e33), Math.max(this.traceClearance, this.viaToPadClearance));
for (const n2 of e33.layers) {
let o2 = this.obstacleIndexesByLayer.get(n2);
o2 || (o2 = new YM(this.cellSize), this.obstacleIndexesByLayer.set(n2, o2)), o2.insert(e33, t2);
}
}
}
collectDynamicGeometry(e33) {
const t2 = [], n2 = [], o2 = new Set;
for (const i2 of e33) {
const e34 = this.resolveNetId(i2.connection_name), r2 = HM(i2);
for (let n3 = 0;n3 < i2.route.length - 1; n3 += 1) {
const o3 = i2.route[n3], s2 = i2.route[n3 + 1];
o3?.route_type === "wire" && s2?.route_type === "wire" && o3.layer === s2.layer && (Math.abs(o3.x - s2.x) <= DM && Math.abs(o3.y - s2.y) <= DM || t2.push({ kind: "trace_segment", order: t2.length, traceId: i2.pcb_trace_id, netId: e34, start: { x: o3.x, y: o3.y }, end: { x: s2.x, y: s2.y }, width: ZM(o3, s2), layer: o3.layer, pcbPortIds: r2 }));
}
for (const t3 of i2.route) {
if (t3.route_type !== "via")
continue;
const r3 = `${t3.x},${t3.y},${t3.from_layer},${t3.to_layer}`;
o2.has(r3) || (o2.add(r3), n2.push({ kind: "via", order: n2.length, viaId: `via_${n2.length}`, traceId: i2.pcb_trace_id, netId: e34, x: t3.x, y: t3.y, diameter: t3.via_diameter ?? this.srj.minViaDiameter ?? 0.3, layers: OM(t3, this.srj.layerCount, this.srj.allowBlindAndBuriedVias) }));
}
}
return { segments: t2, vias: n2 };
}
buildDynamicIndexes(e33, t2) {
const n2 = new Map, o2 = (e34, t3, o3) => {
let i2 = n2.get(e34);
i2 || (i2 = new YM(this.cellSize), n2.set(e34, i2)), i2.insert(t3, LM(o3, this.traceClearance));
};
for (const t3 of e33)
o2(t3.layer, t3, zM(t3));
for (const e34 of t2)
for (const t3 of e34.layers)
o2(t3, e34, BM(e34));
return n2;
}
obstacleSharesNet(e33, t2) {
return t2.connectedTo.some((t3) => this.areConnected(e33, t3));
}
checkTracePair(e33, t2) {
if (this.areConnected(e33.netId, t2.netId))
return;
this.lastRunStats.exactCheckCount += 1;
const n2 = kt(e33.start, e33.end, t2.start, t2.end) - e33.width / 2 - t2.width / 2;
if (n2 > this.traceClearance - kM)
return;
const o2 = `overlap_${e33.traceId}_${t2.traceId}`;
return { type: "pcb_trace_error", error_type: "pcb_trace_error", message: GM(e33.traceId, `PCB trace ${t2.traceId}`, n2), pcb_trace_id: e33.traceId, source_trace_id: "", pcb_trace_error_id: o2, minimum_clearance: this.traceClearance, actual_clearance: n2, pcb_component_ids: [], pcb_port_ids: [...new Set([...e33.pcbPortIds, ...t2.pcbPortIds])], center: XM(e33, t2) };
}
checkTraceVia(e33, t2) {
if (this.areConnected(e33.netId, t2.netId))
return;
this.lastRunStats.exactCheckCount += 1;
const n2 = zt(e33.start, e33.end, { x: t2.x, y: t2.y, radius: t2.diameter / 2 }) - e33.width / 2;
if (n2 > this.traceClearance - kM)
return;
const o2 = `overlap_${e33.traceId}_${t2.viaId}`;
return { type: "pcb_trace_error", error_type: "pcb_trace_error", message: GM(e33.traceId, `pcb_via "${t2.viaId}"`, n2), pcb_trace_id: e33.traceId, ...this.includeTraceViaOwnerMetadata ? { pcb_trace_ids: [e33.traceId, t2.traceId], pcb_via_id: t2.viaId, pcb_via_ids: [t2.viaId] } : {}, source_trace_id: "", pcb_trace_error_id: o2, minimum_clearance: this.traceClearance, actual_clearance: n2, pcb_component_ids: [], pcb_port_ids: e33.pcbPortIds, center: WM(e33, t2) };
}
checkTraceObstacle(e33, t2) {
if (this.obstacleSharesNet(e33.netId, t2))
return;
this.lastRunStats.exactCheckCount += 1;
const n2 = jM(t2), o2 = { ...e33, start: R(t2.worldToLocal, e33.start), end: R(t2.worldToLocal, e33.end) }, i2 = (t2.radius === undefined ? Dt(o2.start, o2.end, n2) : zt(e33.start, e33.end, { x: t2.x, y: t2.y, radius: t2.radius })) - e33.width / 2;
if (i2 + kM >= this.traceClearance)
return;
const r2 = `overlap_${e33.traceId}_${t2.obstacleId}`;
return { type: "pcb_trace_error", error_type: "pcb_trace_error", message: GM(e33.traceId, `${t2.obstacleType} "${t2.obstacleId}"`, i2), pcb_trace_id: e33.traceId, source_trace_id: "", pcb_trace_error_id: r2, minimum_clearance: this.traceClearance, actual_clearance: i2, pcb_component_ids: [], pcb_port_ids: [...new Set([...e33.pcbPortIds, ...t2.pcbPortId ? [t2.pcbPortId] : []])], center: t2.radius === undefined ? R(t2.localToWorld, VM(o2, n2)) : WM(e33, t2) };
}
checkViaObstacle(e33, t2) {
if (this.obstacleSharesNet(e33.netId, t2))
return;
this.lastRunStats.exactCheckCount += 1;
const n2 = jM(t2), o2 = R(t2.worldToLocal, e33), i2 = (t2.radius === undefined ? Math.hypot(Math.max(n2.minX - o2.x, 0, o2.x - n2.maxX), Math.max(n2.minY - o2.y, 0, o2.y - n2.maxY)) : Math.hypot(e33.x - t2.x, e33.y - t2.y) - t2.radius) - e33.diameter / 2;
if (i2 + kM >= this.viaToPadClearance)
return;
const r2 = `via_pad_clearance_${e33.viaId}_${t2.obstacleId}`, s2 = { x: (e33.x + t2.x) / 2, y: (e33.y + t2.y) / 2 };
return { type: "pcb_pad_pad_clearance_error", error_type: "pcb_pad_pad_clearance_error", pcb_pad_pad_clearance_error_id: r2, message: `pcb_via "${e33.viaId}" and ${t2.obstacleType} "${t2.obstacleId}" are too close (gap: ${i2.toFixed(3)}mm)`, pcb_trace_id: e33.traceId, pcb_pad_ids: [e33.viaId, t2.obstacleId], pcb_via_ids: [e33.viaId], minimum_clearance: this.viaToPadClearance, actual_clearance: i2, center: s2 };
}
checkViaPairs(e33) {
if (e33.length < 2)
return [];
const t2 = [], n2 = new YM(this.cellSize);
for (const t3 of e33)
n2.insert(t3, LM(BM(t3), this.viaClearance));
for (const o2 of e33)
for (const e34 of n2.query(BM(o2))) {
if (this.lastRunStats.broadPhaseCandidateCount += 1, e34.order <= o2.order)
continue;
this.lastRunStats.exactCheckCount += 1;
const n3 = Math.hypot(o2.x - e34.x, o2.y - e34.y);
if (n3 <= DM)
continue;
const i2 = n3 - o2.diameter / 2 - e34.diameter / 2;
if (i2 + kM >= this.viaClearance)
continue;
const r2 = this.areConnected(o2.netId, e34.netId), s2 = [o2.viaId, e34.viaId].sort().join("_"), a2 = { x: (o2.x + e34.x) / 2, y: (o2.y + e34.y) / 2 };
t2.push({ type: "pcb_via_clearance_error", error_type: "pcb_via_clearance_error", pcb_error_id: `${r2 ? "same_net" : "different_net"}_vias_close_${s2}`, message: `Vias ${o2.viaId} and ${e34.viaId}${r2 ? "" : " from different nets"} are too close together (gap: ${i2.toFixed(3)}mm)`, pcb_via_ids: [o2.viaId, e34.viaId], ...this.includeTraceViaOwnerMetadata ? { pcb_trace_ids: [o2.traceId, e34.traceId] } : {}, pcb_via_pair_net_relation: r2 ? "same_net" : "different_net", minimum_clearance: this.viaClearance, actual_clearance: i2, pcb_center: a2, center: a2 });
}
return t2;
}
evaluate(e33) {
return this.evaluateInternal(e33, true);
}
evaluateLegacy(e33) {
return this.evaluateInternal(e33, false);
}
evaluateInternal(e33, t2) {
const { segments: n2, vias: o2 } = this.collectDynamicGeometry(e33), i2 = this.buildDynamicIndexes(n2, o2), r2 = [], s2 = [];
this.lastRunStats = { traceCount: e33.length, segmentCount: n2.length, viaCount: o2.length, obstacleCount: this.obstacles.length, broadPhaseCandidateCount: 0, exactCheckCount: 0 };
for (const e34 of n2) {
const t3 = zM(e34), n3 = i2.get(e34.layer)?.query(t3) ?? [], o3 = this.obstacleIndexesByLayer.get(e34.layer)?.query(t3) ?? [];
for (const t4 of n3) {
if (this.lastRunStats.broadPhaseCandidateCount += 1, t4.kind === "trace_segment" && t4.order <= e34.order)
continue;
const n4 = t4.kind === "trace_segment" ? this.checkTracePair(e34, t4) : this.checkTraceVia(e34, t4);
n4 && r2.push(n4);
}
for (const t4 of o3) {
this.lastRunStats.broadPhaseCandidateCount += 1;
const n4 = this.checkTraceObstacle(e34, t4);
n4 && r2.push(n4);
}
}
const a2 = this.checkViaPairs(o2);
if (t2)
for (const e34 of o2) {
const t3 = new Set;
for (const n3 of e34.layers) {
const o3 = this.obstacleIndexesByLayer.get(n3)?.query(BM(e34)) ?? [];
for (const n4 of o3) {
if (t3.has(n4))
continue;
t3.add(n4), this.lastRunStats.broadPhaseCandidateCount += 1;
const o4 = this.checkViaObstacle(e34, n4);
o4 && s2.push(o4);
}
}
}
const c2 = new Map;
for (const e34 of r2) {
const t3 = String(e34.pcb_trace_error_id), n3 = c2.get(t3), o3 = Number(e34.actual_clearance);
if (!n3) {
c2.set(t3, { ...e34, first_contact_center: e34.center, first_contact_message: e34.message, first_actual_clearance: o3, worst_contact_center: e34.center, worst_contact_message: e34.message, worst_actual_clearance: o3 });
continue;
}
const i3 = Number(n3.worst_actual_clearance);
(o3 < i3 || !Number.isFinite(i3)) && (n3.worst_contact_center = e34.center, n3.worst_contact_message = e34.message, n3.worst_actual_clearance = o3);
}
const l2 = [...c2.values()].map((e34) => ({ ...e34, center: typeof e34.worst_contact_center == "object" ? e34.worst_contact_center : e34.center, message: typeof e34.worst_contact_message == "string" ? e34.worst_contact_message : e34.message, actual_clearance: typeof e34.worst_actual_clearance == "number" ? e34.worst_actual_clearance : e34.actual_clearance }));
l2.push(...s2), l2.push(...a2);
const h2 = l2.filter((e34) => e34.center);
return { errors: l2, errorsWithCenters: h2, locationAwareErrors: h2 };
}
};
var ZM = (e33, t2) => e33.width ?? t2.width ?? 0.1;
var qM = [1, 1.75, -1];
var JM = [1, 1.75, -1];
var QM = 8 / 3;
var KM = 0.000001;
var ew = 0.001;
var tw = 0.14;
var nw = 0.035;
var ow = 0.015;
var iw = (e33) => e33.minTraceToPadEdgeClearance ?? 0.16;
var rw = (e33) => e33.minViaEdgeToPadEdgeClearance ?? 0.1;
var sw = (e33) => Math.max(48, Math.round(48 * Math.max(1, e33)));
var aw = (e33) => e33 >= 2 ? qM : JM;
var cw = class {
netMap;
idToNetMap;
constructor(e33) {
this.netMap = e33, this.idToNetMap = {};
for (const [t2, n2] of Object.entries(e33))
for (const e34 of n2)
this.idToNetMap[e34] = t2;
}
addConnections(e33) {
for (const t2 of e33) {
const e34 = new Set;
for (const n3 of t2) {
const t3 = this.idToNetMap[n3];
t3 && e34.add(t3);
}
let n2;
if (e34.size === 0)
n2 = `connectivity_net${Object.keys(this.netMap).length}`, this.netMap[n2] = [];
else if (e34.size === 1)
n2 = e34.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
else {
n2 = e34.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
for (const t3 of e34)
if (t3 !== n2) {
this.netMap[n2].push(...this.netMap[t3]), this.netMap[t3] = this.netMap[n2];
for (const e35 of this.netMap[n2])
this.idToNetMap[e35] = n2;
}
}
for (const e35 of t2)
this.netMap[n2].includes(e35) || this.netMap[n2].push(e35), this.idToNetMap[e35] = n2;
}
}
getIdsConnectedToNet(e33) {
return this.netMap[e33] || [];
}
getNetConnectedToId(e33) {
return this.idToNetMap[e33];
}
areIdsConnected(e33, t2) {
if (e33 === t2)
return true;
const n2 = this.getNetConnectedToId(e33);
if (!n2)
return false;
const o2 = this.getNetConnectedToId(t2);
return !!o2 && (n2 === o2 || o2 === e33 || o2 === e33);
}
areAllIdsConnected(e33) {
const t2 = this.getNetConnectedToId(e33[0]);
for (const n2 of e33) {
const e34 = this.getNetConnectedToId(n2);
if (e34 === undefined)
return false;
if (e34 !== t2)
return false;
}
return true;
}
};
var lw = (e33) => {
const t2 = [];
for (const n3 of e33)
if (n3.type === "source_trace")
t2.push([n3.source_trace_id, ...n3.connected_source_port_ids ?? [], ...n3.connected_source_net_ids ?? []].filter(Boolean));
else if (n3.type === "pcb_port") {
const { pcb_port_id: e34, source_port_id: o2 } = n3;
o2 && e34 && t2.push([o2, e34]);
} else if (n3.type === "pcb_smtpad") {
const { pcb_smtpad_id: e34, pcb_port_id: o2 } = n3;
o2 && e34 && t2.push([e34, o2]);
} else if (n3.type === "pcb_plated_hole") {
const { pcb_plated_hole_id: e34, pcb_port_id: o2 } = n3;
o2 && e34 && t2.push([e34, o2]);
} else if (n3.type === "pcb_trace") {
const { pcb_trace_id: e34, source_trace_id: o2 } = n3, i2 = Array.isArray(n3.route) ? n3.route.filter((e35) => e35 && e35.route_type === "wire") : [];
if (o2 && e34 && t2.push([e34, o2]), Array.isArray(i2)) {
const n4 = i2.find((e35) => e35?.start_pcb_port_id)?.start_pcb_port_id, o3 = i2.find((e35) => e35?.end_pcb_port_id)?.end_pcb_port_id;
n4 && e34 && o3 && t2.push([n4, e34, o3]);
}
} else if (n3.type === "pcb_via") {
const { pcb_via_id: e34, pcb_trace_id: o2 } = n3;
o2 && e34 && t2.push([e34, o2]);
} else if (n3.type === "source_component" && n3.internally_connected_source_port_ids)
for (const e34 of n3.internally_connected_source_port_ids)
t2.push(e34);
const n2 = function(e34) {
const t3 = new Map;
let n3 = 0;
function o2(e35) {
for (const [, n4] of t3)
if (n4.has(e35))
return n4;
const o3 = new Set;
return t3.set("connectivity_net" + n3++, o3), o3;
}
for (const n4 of e34) {
let e35 = null;
for (const i2 of n4) {
if (e35) {
if (!e35.has(i2)) {
const n5 = o2(i2);
if (n5 !== e35) {
for (const t4 of n5)
e35.add(t4);
t3.delete(Array.from(t3.entries()).find(([, e36]) => e36 === n5)[0]);
}
}
} else
e35 = o2(i2);
e35.add(i2);
}
}
return Object.fromEntries(Array.from(t3.entries()).map(([e35, t4]) => [e35, Array.from(t4)]));
}(t2);
return new cw(n2);
};
var hw = {};
a(hw, { all_layers: () => UN, any_circuit_element: () => aA, any_soup_element: () => cA, any_source_component: () => FN, asset: () => zw, base_circuit_json_error: () => Kw, battery_capacity: () => Nw, brep_shape: () => zT, cadModelDefaultDirectionMap: () => XE, cad_component: () => WE, cad_model_axis_directions: () => YE, cad_model_formats: () => $E, capacitance: () => fw, circuit_json_footprint_load_error: () => mE, current: () => Iw, distance: () => vw, duration_ms: () => Sw, experiment_type: () => eA, external_footprint_load_error: () => pE, frequency: () => xw, getZodPrefixedIdWithDefault: () => kw, inductance: () => _w, kicadAt: () => Bw, kicadEffects: () => jw, kicadFont: () => Fw, kicadFootprintAttributes: () => Xw, kicadFootprintMetadata: () => Hw, kicadFootprintModel: () => Vw, kicadFootprintPad: () => Ww, kicadFootprintProperties: () => Yw, kicadProperty: () => $w, kicadSymbolEffects: () => Zw, kicadSymbolMetadata: () => Qw, kicadSymbolPinNames: () => Uw, kicadSymbolPinNumbers: () => Gw, kicadSymbolProperties: () => Jw, kicadSymbolProperty: () => qw, layer_ref: () => qN, layer_string: () => ZN, length: () => bw, manufacturing_drc_properties: () => $T, ms: () => Pw, ninePointAnchor: () => Dw, pcbRenderLayer: () => Lw, pcb_autorouting_error: () => fE, pcb_board: () => DR, pcb_breakout_point: () => vE, pcb_component: () => YT, pcb_component_invalid_layer_error: () => AE, pcb_component_not_on_board_edge_error: () => EE, pcb_component_outside_board_error: () => RE, pcb_connector_not_in_accessible_orientation_warning: () => bE, pcb_copper_pour: () => TE, pcb_copper_pour_brep: () => wE, pcb_copper_pour_polygon: () => NE, pcb_copper_pour_rect: () => ME, pcb_copper_text: () => XR, pcb_courtyard_circle: () => jE, pcb_courtyard_outline: () => BE, pcb_courtyard_overlap_error: () => iE, pcb_courtyard_polygon: () => FE, pcb_courtyard_rect: () => zE, pcb_cutout: () => dE, pcb_cutout_circle: () => cE, pcb_cutout_path: () => hE, pcb_cutout_polygon: () => lE, pcb_cutout_rect: () => aE, pcb_fabrication_note_dimension: () => JR, pcb_fabrication_note_path: () => ZR, pcb_fabrication_note_rect: () => qR, pcb_fabrication_note_text: () => UR, pcb_footprint_overlap_error: () => oE, pcb_ground_plane: () => IE, pcb_ground_plane_region: () => SE, pcb_group: () => gE, pcb_hole: () => tR, pcb_hole_circle_or_square_shape: () => UT, pcb_hole_circle_shape: () => WT, pcb_hole_oval_shape: () => qT, pcb_hole_pill_shape: () => QT, pcb_hole_rect_shape: () => HT, pcb_hole_rotated_pill_shape: () => eR, pcb_keepout: () => rE, pcb_manual_edit_conflict_warning: () => _E, pcb_missing_footprint_error: () => uE, pcb_net: () => OR, pcb_note_dimension: () => nE, pcb_note_line: () => tE, pcb_note_path: () => eE, pcb_note_rect: () => KR, pcb_note_text: () => QR, pcb_pad_pad_clearance_error: () => DE, pcb_pad_trace_clearance_error: () => LE, pcb_panel: () => LR, pcb_panelization_placement_error: () => BR, pcb_placement_error: () => zR, pcb_plated_hole: () => cR, pcb_port: () => lR, pcb_port_not_connected_error: () => AR, pcb_port_not_matched_error: () => ER, pcb_route_hint: () => BT, pcb_route_hints: () => FT, pcb_silkscreen_circle: () => VR, pcb_silkscreen_line: () => jR, pcb_silkscreen_oval: () => HR, pcb_silkscreen_path: () => $R, pcb_silkscreen_pill: () => GR, pcb_silkscreen_rect: () => WR, pcb_silkscreen_text: () => YR, pcb_smtpad: () => fR, pcb_smtpad_pill: () => pR, pcb_solder_paste: () => IR, pcb_text: () => SR, pcb_thermal_spoke: () => CE, pcb_trace: () => wR, pcb_trace_error: () => TR, pcb_trace_hint: () => FR, pcb_trace_missing_error: () => RR, pcb_trace_route_point: () => MR, pcb_trace_route_point_via: () => PR, pcb_trace_route_point_wire: () => CR, pcb_trace_warning: () => NR, pcb_via: () => kR, pcb_via_clearance_error: () => OE, pcb_via_trace_clearance_error: () => kE, point: () => Tw, point3: () => Ew, point_with_bulge: () => DT, port_arrangement: () => lT, position: () => Rw, position3: () => Aw, resistance: () => gw, ring: () => LT, rotation: () => ww, route_hint_point: () => jT, schematic_arc: () => fT, schematic_box: () => iT, schematic_circle: () => gT, schematic_component: () => hT, schematic_component_port_arrangement_by_sides: () => cT, schematic_component_port_arrangement_by_size: () => aT, schematic_debug_line: () => MT, schematic_debug_object: () => NT, schematic_debug_object_base: () => CT, schematic_debug_point: () => wT, schematic_debug_rect: () => PT, schematic_error: () => IT, schematic_group: () => ET, schematic_layout_error: () => ST, schematic_line: () => pT, schematic_manual_edit_conflict_warning: () => RT, schematic_net_label: () => vT, schematic_path: () => rT, schematic_pin_styles: () => sT, schematic_port: () => xT, schematic_rect: () => mT, schematic_sheet: () => kT, schematic_symbol: () => uT, schematic_table: () => AT, schematic_table_cell: () => OT, schematic_text: () => bT, schematic_trace: () => _T, schematic_voltage_probe: () => TT, simulation_ac_current_source: () => QE, simulation_ac_voltage_source: () => UE, simulation_current_source: () => KE, simulation_dc_current_source: () => JE, simulation_dc_voltage_source: () => GE, simulation_experiment: () => tA, simulation_op_amp: () => sA, simulation_switch: () => oA, simulation_transient_voltage_graph: () => nA, simulation_unknown_experiment_error: () => rA, simulation_voltage_probe: () => iA, simulation_voltage_source: () => ZE, size: () => Ow, source_ambiguous_port_reference: () => HN, source_board: () => VN, source_component_base: () => tN, source_component_internal_connection: () => $N, source_component_pins_underspecified_warning: () => tT, source_failed_to_create_component_error: () => TN, source_group: () => XN, source_i2c_misconfigured_error: () => zN, source_interconnect: () => LN, source_invalid_component_property_error: () => RN, source_manually_placed_via: () => QN, source_missing_manufacturer_part_number_warning: () => kN, source_missing_property_error: () => NN, source_net: () => WN, source_no_ground_pin_defined_warning: () => eT, source_no_power_pin_defined_warning: () => KN, source_pcb_ground_plane: () => GN, source_pin_attributes: () => dN, source_pin_missing_trace_warning: () => ON, source_pin_must_be_connected_error: () => nT, source_port: () => jN, source_project_metadata: () => wN, source_property_ignored_warning: () => AN, source_simple_battery: () => pN, source_simple_capacitor: () => nN, source_simple_chip: () => cN, source_simple_connector: () => bN, source_simple_crystal: () => _N, source_simple_current_source: () => hN, source_simple_diode: () => iN, source_simple_fiducial: () => rN, source_simple_ground: () => aN, source_simple_inductor: () => mN, source_simple_led: () => sN, source_simple_mosfet: () => CN, source_simple_op_amp: () => PN, source_simple_pin_header: () => yN, source_simple_pinout: () => xN, source_simple_potentiometer: () => fN, source_simple_power_source: () => lN, source_simple_push_button: () => gN, source_simple_resistor: () => oN, source_simple_resonator: () => vN, source_simple_switch: () => MN, source_simple_test_point: () => SN, source_simple_transistor: () => IN, source_simple_voltage_probe: () => DN, source_simple_voltage_source: () => BN, source_trace: () => YN, source_trace_not_connected_error: () => EN, supplier_footprint_mismatch_warning: () => xE, supplier_name: () => eN, time: () => Cw, timestamp: () => Mw, unknown_error_finding_part: () => oT, visible_layer: () => JN, voltage: () => yw, wave_shape: () => VE });
var dw = { Hz: { baseUnit: "Hz", variants: { MHz: 1e6, kHz: 1000, Hz: 1 } }, g: { baseUnit: "g", variants: { kg: 1000, g: 1 } }, "Ω": { baseUnit: "Ω", variants: { "mΩ": 0.001, "Ω": 1, "kΩ": 1000, "KΩ": 1000, kohm: 1000, "MΩ": 1e6, "GΩ": 1e9, "TΩ": 1000000000000 } }, V: { baseUnit: "V", variants: { mV: 0.001, V: 1, kV: 1000, KV: 1000, MV: 1e6, GV: 1e9, TV: 1000000000000 } }, A: { baseUnit: "A", variants: { "µA": 0.000001, mA: 0.001, ma: 0.001, A: 1, kA: 1000, MA: 1e6 } }, F: { baseUnit: "F", variants: { pF: 0.000000000001, nF: 0.000000001, "µF": 0.000001, uF: 0.000001, mF: 0.001, F: 1 } }, ml: { baseUnit: "ml", variants: { ml: 1, mL: 1, l: 1000, L: 1000 } }, deg: { baseUnit: "deg", variants: { rad: 180 / Math.PI } }, ms: { baseUnit: "ms", variants: { fs: 0.000000000001, ps: 0.000000001, ns: 0.000001, us: 0.001, "µs": 0.001, ms: 1, s: 1000 } }, mm: { baseUnit: "mm", variants: { nm: 0.000001, "µm": 0.001, um: 0.001, mm: 1, cm: 10, dm: 100, m: 1000, km: 1e6, in: 25.4, ft: 304.8, IN: 25.4, FT: 304.8, yd: 914.4, mi: 1609344, mil: 0.0254 } } };
var uw = new Set;
for (const [e33, t2] of Object.entries(dw)) {
uw.add(e33);
for (const e34 of Object.keys(t2.variants))
uw.add(e34);
}
var pw = { tera: 1000000000000, T: 1000000000000, giga: 1e9, G: 1e9, mega: 1e6, M: 1e6, kilo: 1000, k: 1000, deci: 0.1, d: 0.1, centi: 0.01, c: 0.01, milli: 0.001, m: 0.001, micro: 0.000001, u: 0.000001, "µ": 0.000001, nano: 0.000000001, n: 0.000000001, pico: 0.000000000001, p: 0.000000000001 };
function mw(e33) {
if (e33 == null)
return { parsedUnit: null, unitOfValue: null, value: null };
if (typeof e33 == "string" && e33.match(/^-?[\d\.]+$/))
return { value: Number.parseFloat(e33), parsedUnit: null, unitOfValue: null };
if (typeof e33 == "number")
return { value: e33, parsedUnit: null, unitOfValue: null };
if (typeof e33 == "object" && "x" in e33 && "y" in e33) {
const { parsedUnit: t3, unitOfValue: n3 } = mw(e33.x), o3 = mw(e33.x), i3 = mw(e33.y);
return o3.value === null || i3.value === null ? { parsedUnit: null, unitOfValue: null, value: null } : { parsedUnit: t3, unitOfValue: n3, value: { x: o3.value, y: i3.value } };
}
const t2 = e33.toString().split("").reverse().join(""), n2 = t2.match(/[^\d\s]+/)?.[0];
if (!n2)
throw new Error(`Could not determine unit: "${e33}"`);
const o2 = n2.split("").reverse().join(""), i2 = e33.slice(0, -o2.length);
if (o2 in pw && !uw.has(o2)) {
const e34 = pw[o2];
return { parsedUnit: null, unitOfValue: null, value: Number.parseFloat(i2) * e34 };
}
const { baseUnit: r2, conversionFactor: s2 } = function(e34) {
for (const [t3, n3] of Object.entries(dw))
if (e34 in n3.variants)
return { baseUnit: n3.baseUnit, conversionFactor: n3.variants[e34] };
return { baseUnit: e34, conversionFactor: 1 };
}(o2);
return { parsedUnit: o2, unitOfValue: r2, value: s2 * Number.parseFloat(i2) };
}
var gw = ha.string().or(ha.number()).transform((e33) => mw(e33).value);
var fw = ha.string().or(ha.number()).transform((e33) => mw(e33).value).transform((e33) => Number.parseFloat(e33.toPrecision(12)));
var _w = ha.string().or(ha.number()).transform((e33) => mw(e33).value);
var yw = ha.string().or(ha.number()).transform((e33) => mw(e33).value);
var bw = ha.string().or(ha.number()).transform((e33) => mw(e33).value);
var xw = ha.string().or(ha.number()).transform((e33) => mw(e33).value);
var vw = bw;
var Iw = ha.string().or(ha.number()).transform((e33) => mw(e33).value);
var Sw = ha.string().or(ha.number()).transform((e33) => mw(e33).value);
var Cw = Sw;
var Pw = Sw;
var Mw = ha.string().datetime();
var ww = ha.string().or(ha.number()).transform((e33) => typeof e33 == "number" ? e33 : e33.endsWith("deg") ? Number.parseFloat(e33.split("deg")[0]) : e33.endsWith("rad") ? 180 * Number.parseFloat(e33.split("rad")[0]) / Math.PI : Number.parseFloat(e33));
var Nw = ha.number().or(ha.string().endsWith("mAh")).transform((e33) => {
if (typeof e33 == "string") {
const t2 = e33.replace("mAh", ""), n2 = Number.parseFloat(t2);
if (Number.isNaN(n2))
throw new Error("Invalid capacity");
return n2;
}
return e33;
}).describe("Battery capacity in mAh");
var Tw = ha.object({ x: vw, y: vw });
var Rw = Tw;
var Ew = ha.object({ x: vw, y: vw, z: vw });
var Aw = Ew;
var Ow = ha.object({ width: ha.number(), height: ha.number() });
var kw = (e33) => ha.string().optional().default(() => `${e33}_${((e34) => {
const t2 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return Array.from({ length: e34 }, () => t2[Math.floor(62 * Math.random())]).join("");
})(10)}`);
var Dw = ha.enum(["top_left", "top_center", "top_right", "center_left", "center", "center_right", "bottom_left", "bottom_center", "bottom_right"]);
var Lw = ha.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"]);
var zw = ha.object({ project_relative_path: ha.string(), url: ha.string(), mimetype: ha.string() });
var Bw = Tw.extend({ rotation: ww.optional() });
var Fw = ha.object({ size: Tw.optional(), thickness: vw.optional() });
var jw = ha.object({ font: Fw.optional() });
var $w = ha.object({ value: ha.string(), at: Bw.optional(), layer: ha.string().optional(), uuid: ha.string().optional(), hide: ha.boolean().optional(), effects: jw.optional() });
var Yw = ha.object({ Reference: $w.optional(), Value: $w.optional(), Datasheet: $w.optional(), Description: $w.optional() });
var Xw = ha.object({ through_hole: ha.boolean().optional(), smd: ha.boolean().optional(), exclude_from_pos_files: ha.boolean().optional(), exclude_from_bom: ha.boolean().optional() });
var Ww = ha.object({ name: ha.string(), type: ha.string(), shape: ha.string().optional(), at: Bw.optional(), size: Tw.optional(), drill: vw.optional(), layers: ha.array(ha.string()).optional(), removeUnusedLayers: ha.boolean().optional(), uuid: ha.string().optional() });
var Vw = ha.object({ path: ha.string(), offset: Ew.optional(), scale: Ew.optional(), rotate: Ew.optional() });
var Hw = ha.object({ footprintName: ha.string().optional(), version: ha.union([ha.number(), ha.string()]).optional(), generator: ha.string().optional(), generatorVersion: ha.union([ha.number(), ha.string()]).optional(), layer: ha.string().optional(), properties: Yw.optional(), attributes: Xw.optional(), pads: ha.array(Ww).optional(), embeddedFonts: ha.boolean().optional(), model: Vw.optional() });
var Gw = ha.object({ hide: ha.boolean().optional() });
var Uw = ha.object({ offset: vw.optional(), hide: ha.boolean().optional() });
var Zw = ha.object({ font: Fw.optional(), justify: ha.union([ha.string(), ha.array(ha.string())]).optional(), hide: ha.boolean().optional() });
var qw = ha.object({ value: ha.string(), id: ha.union([ha.number(), ha.string()]).optional(), at: Bw.optional(), effects: Zw.optional() });
var Jw = ha.object({ Reference: qw.optional(), Value: qw.optional(), Footprint: qw.optional(), Datasheet: qw.optional(), Description: qw.optional(), ki_keywords: qw.optional(), ki_fp_filters: qw.optional() });
var Qw = ha.object({ symbolName: ha.string().optional(), extends: ha.string().optional(), pinNumbers: Gw.optional(), pinNames: Uw.optional(), excludeFromSim: ha.boolean().optional(), inBom: ha.boolean().optional(), onBoard: ha.boolean().optional(), properties: Jw.optional(), embeddedFonts: ha.boolean().optional() });
var Kw = ha.object({ error_type: ha.string(), message: ha.string(), is_fatal: ha.boolean().optional() });
var eN = ha.enum(["jlcpcb", "macrofab", "pcbway", "digikey", "mouser", "lcsc"]);
var tN = ha.object({ type: ha.literal("source_component"), ftype: ha.string().optional(), source_component_id: ha.string(), name: ha.string(), manufacturer_part_number: ha.string().optional(), supplier_part_numbers: ha.record(eN, ha.array(ha.string())).optional(), display_value: ha.string().optional(), display_name: ha.string().optional(), are_pins_interchangeable: ha.boolean().optional(), internally_connected_source_port_ids: ha.array(ha.array(ha.string())).optional(), source_group_id: ha.string().optional(), subcircuit_id: ha.string().optional() });
var nN = tN.extend({ ftype: ha.literal("simple_capacitor"), capacitance: fw, max_voltage_rating: yw.optional(), display_capacitance: ha.string().optional(), max_decoupling_trace_length: vw.optional() });
var oN = tN.extend({ ftype: ha.literal("simple_resistor"), resistance: gw, display_resistance: ha.string().optional() });
var iN = tN.extend({ ftype: ha.literal("simple_diode") });
var rN = tN.extend({ ftype: ha.literal("simple_fiducial") });
var sN = iN.extend({ ftype: ha.literal("simple_led"), color: ha.string().optional(), wavelength: ha.string().optional() });
var aN = tN.extend({ ftype: ha.literal("simple_ground") });
var cN = tN.extend({ ftype: ha.literal("simple_chip") });
var lN = tN.extend({ ftype: ha.literal("simple_power_source"), voltage: yw });
var hN = tN.extend({ ftype: ha.literal("simple_current_source"), current: Iw, frequency: xw.optional(), peak_to_peak_current: Iw.optional(), wave_shape: ha.enum(["sine", "square", "triangle", "sawtooth", "dc"]).optional().default("dc"), phase: ha.number().optional(), duty_cycle: ha.number().min(0).max(1).optional() });
var dN = ha.object({ must_be_connected: ha.boolean().optional(), provides_power: ha.boolean().optional(), requires_power: ha.boolean().optional(), provides_ground: ha.boolean().optional(), requires_ground: ha.boolean().optional(), provides_voltage: ha.union([ha.string(), ha.number()]).optional(), requires_voltage: ha.union([ha.string(), ha.number()]).optional(), do_not_connect: ha.boolean().optional(), include_in_board_pinout: ha.boolean().optional(), can_use_internal_pullup: ha.boolean().optional(), is_using_internal_pullup: ha.boolean().optional(), needs_external_pullup: ha.boolean().optional(), can_use_internal_pulldown: ha.boolean().optional(), is_using_internal_pulldown: ha.boolean().optional(), needs_external_pulldown: ha.boolean().optional(), can_use_open_drain: ha.boolean().optional(), is_using_open_drain: ha.boolean().optional(), can_use_push_pull: ha.boolean().optional(), is_using_push_pull: ha.boolean().optional(), should_have_decoupling_capacitor: ha.boolean().optional(), recommended_decoupling_capacitor_capacitance: ha.union([ha.string(), ha.number()]).optional(), is_configured_for_i2c_sda: ha.boolean().optional(), is_configured_for_i2c_scl: ha.boolean().optional(), is_configured_for_spi_mosi: ha.boolean().optional(), is_configured_for_spi_miso: ha.boolean().optional(), is_configured_for_spi_sck: ha.boolean().optional(), is_configured_for_spi_cs: ha.boolean().optional(), is_configured_for_uart_tx: ha.boolean().optional(), is_configured_for_uart_rx: ha.boolean().optional(), supports_i2c_sda: ha.boolean().optional(), supports_i2c_scl: ha.boolean().optional(), supports_spi_mosi: ha.boolean().optional(), supports_spi_miso: ha.boolean().optional(), supports_spi_sck: ha.boolean().optional(), supports_spi_cs: ha.boolean().optional(), supports_uart_tx: ha.boolean().optional(), supports_uart_rx: ha.boolean().optional() });
var uN = tN.extend({ ftype: ha.literal("simple_fuse"), current_rating_amps: ha.number().describe("Nominal current in amps the fuse is rated for"), voltage_rating_volts: ha.number().describe("Voltage rating in volts, e.g. ±5V would be 5") });
var pN = tN.extend({ ftype: ha.literal("simple_battery"), capacity: Nw });
var mN = tN.extend({ ftype: ha.literal("simple_inductor"), inductance: _w, display_inductance: ha.string().optional(), max_current_rating: ha.number().optional() });
var gN = tN.extend({ ftype: ha.literal("simple_push_button") });
var fN = tN.extend({ ftype: ha.literal("simple_potentiometer"), max_resistance: gw, display_max_resistance: ha.string().optional() });
var _N = tN.extend({ ftype: ha.literal("simple_crystal"), frequency: ha.number().describe("Frequency in Hz"), load_capacitance: ha.number().optional().describe("Load capacitance in pF"), pin_variant: ha.enum(["two_pin", "four_pin"]).optional() });
var yN = tN.extend({ ftype: ha.literal("simple_pin_header"), pin_count: ha.number(), gender: ha.enum(["male", "female"]).optional().default("male") });
var bN = tN.extend({ ftype: ha.literal("simple_connector"), standard: ha.enum(["usb_c", "m2"]).optional() });
var xN = tN.extend({ ftype: ha.literal("simple_pinout") });
var vN = tN.extend({ ftype: ha.literal("simple_resonator"), load_capacitance: fw, equivalent_series_resistance: gw.optional(), frequency: xw });
var IN = tN.extend({ ftype: ha.literal("simple_transistor"), transistor_type: ha.enum(["npn", "pnp"]) });
var SN = tN.extend({ ftype: ha.literal("simple_test_point"), footprint_variant: ha.enum(["pad", "through_hole"]).optional(), pad_shape: ha.enum(["rect", "circle"]).optional(), pad_diameter: ha.union([ha.number(), ha.string()]).optional(), hole_diameter: ha.union([ha.number(), ha.string()]).optional(), width: ha.union([ha.number(), ha.string()]).optional(), height: ha.union([ha.number(), ha.string()]).optional() });
var CN = tN.extend({ ftype: ha.literal("simple_mosfet"), channel_type: ha.enum(["n", "p"]), mosfet_mode: ha.enum(["enhancement", "depletion"]) });
var PN = tN.extend({ ftype: ha.literal("simple_op_amp") });
var MN = tN.extend({ ftype: ha.literal("simple_switch") });
var wN = ha.object({ type: ha.literal("source_project_metadata"), name: ha.string().optional(), software_used_string: ha.string().optional(), project_url: ha.string().optional(), created_at: Mw.optional() });
var NN = Kw.extend({ type: ha.literal("source_missing_property_error"), source_missing_property_error_id: kw("source_missing_property_error"), source_component_id: ha.string(), property_name: ha.string(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_missing_property_error").default("source_missing_property_error") }).describe("The source code is missing a property");
var TN = Kw.extend({ type: ha.literal("source_failed_to_create_component_error"), source_failed_to_create_component_error_id: kw("source_failed_to_create_component_error"), error_type: ha.literal("source_failed_to_create_component_error").default("source_failed_to_create_component_error"), component_name: ha.string().optional(), subcircuit_id: ha.string().optional(), parent_source_component_id: ha.string().optional(), pcb_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), schematic_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional() }).describe("Error emitted when a component fails to be constructed");
var RN = Kw.extend({ type: ha.literal("source_invalid_component_property_error"), source_invalid_component_property_error_id: kw("source_invalid_component_property_error"), source_component_id: ha.string(), property_name: ha.string(), property_value: ha.unknown().optional(), expected_format: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_invalid_component_property_error").default("source_invalid_component_property_error") }).describe("The source component property is invalid");
var EN = Kw.extend({ type: ha.literal("source_trace_not_connected_error"), source_trace_not_connected_error_id: kw("source_trace_not_connected_error"), error_type: ha.literal("source_trace_not_connected_error").default("source_trace_not_connected_error"), subcircuit_id: ha.string().optional(), source_group_id: ha.string().optional(), source_trace_id: ha.string().optional(), connected_source_port_ids: ha.array(ha.string()).optional(), selectors_not_found: ha.array(ha.string()).optional() }).describe("Occurs when a source trace selector does not match any ports");
var AN = ha.object({ type: ha.literal("source_property_ignored_warning"), source_property_ignored_warning_id: kw("source_property_ignored_warning"), source_component_id: ha.string(), property_name: ha.string(), subcircuit_id: ha.string().optional(), error_type: ha.literal("source_property_ignored_warning").default("source_property_ignored_warning"), message: ha.string() }).describe("The source property was ignored");
var ON = ha.object({ type: ha.literal("source_pin_missing_trace_warning"), source_pin_missing_trace_warning_id: kw("source_pin_missing_trace_warning"), warning_type: ha.literal("source_pin_missing_trace_warning").default("source_pin_missing_trace_warning"), message: ha.string(), source_component_id: ha.string(), source_port_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a source component pin is missing a trace connection");
var kN = ha.object({ type: ha.literal("source_missing_manufacturer_part_number_warning"), source_missing_manufacturer_part_number_warning_id: kw("source_missing_manufacturer_part_number_warning"), warning_type: ha.literal("source_missing_manufacturer_part_number_warning").default("source_missing_manufacturer_part_number_warning"), message: ha.string(), source_component_id: ha.string(), standard: ha.string(), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a standard connector is missing manufacturer part number");
var DN = tN.extend({ ftype: ha.literal("simple_voltage_probe") });
var LN = tN.extend({ ftype: ha.literal("interconnect") });
var zN = Kw.extend({ type: ha.literal("source_i2c_misconfigured_error"), source_i2c_misconfigured_error_id: kw("source_i2c_misconfigured_error"), error_type: ha.literal("source_i2c_misconfigured_error").default("source_i2c_misconfigured_error"), source_port_ids: ha.array(ha.string()) }).describe("Error emitted when incompatible I2C pins (e.g. SDA and SCL) are connected to the same net");
var BN = tN.extend({ ftype: ha.literal("simple_voltage_source"), voltage: yw, frequency: xw.optional(), peak_to_peak_voltage: yw.optional(), wave_shape: ha.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(), phase: ww.optional(), duty_cycle: ha.number().optional().describe("Duty cycle as a fraction (0 to 1)") });
var FN = ha.union([oN, nN, iN, rN, sN, aN, cN, lN, hN, pN, mN, gN, fN, _N, yN, bN, xN, vN, MN, IN, SN, CN, PN, uN, DN, LN, BN, wN, NN, RN, TN, EN, AN, ON, kN, zN]);
var jN = ha.object({ type: ha.literal("source_port"), pin_number: ha.number().optional(), port_hints: ha.array(ha.string()).optional(), name: ha.string(), source_port_id: ha.string(), source_component_id: ha.string().optional(), source_group_id: ha.string().optional(), most_frequently_referenced_by_name: ha.string().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() }).merge(dN);
var $N = ha.object({ type: ha.literal("source_component_internal_connection"), source_component_internal_connection_id: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() });
var YN = ha.object({ type: ha.literal("source_trace"), source_trace_id: ha.string(), connected_source_port_ids: ha.array(ha.string()), connected_source_net_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), max_length: ha.number().optional(), min_trace_thickness: ha.number().optional(), display_name: ha.string().optional() });
var XN = ha.object({ type: ha.literal("source_group"), source_group_id: ha.string(), subcircuit_id: ha.string().optional(), parent_subcircuit_id: ha.string().optional(), parent_source_group_id: ha.string().optional(), is_subcircuit: ha.boolean().optional(), show_as_schematic_box: ha.boolean().optional(), name: ha.string().optional(), was_automatically_named: ha.boolean().optional() });
var WN = ha.object({ type: ha.literal("source_net"), source_net_id: ha.string(), name: ha.string(), member_source_group_ids: ha.array(ha.string()), is_power: ha.boolean().optional(), is_ground: ha.boolean().optional(), is_digital_signal: ha.boolean().optional(), is_analog_signal: ha.boolean().optional(), is_positive_voltage_source: ha.boolean().optional(), trace_width: ha.number().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() });
var VN = ha.object({ type: ha.literal("source_board"), source_board_id: ha.string(), source_group_id: ha.string(), title: ha.string().optional() }).describe("Defines a board in the source domain");
var HN = Kw.extend({ type: ha.literal("source_ambiguous_port_reference"), source_ambiguous_port_reference_id: kw("source_ambiguous_port_reference"), error_type: ha.literal("source_ambiguous_port_reference").default("source_ambiguous_port_reference"), source_port_id: ha.string().optional(), source_component_id: ha.string().optional() }).describe("Error emitted when a port hint matches multiple non-overlapping pads, making the port reference ambiguous");
var GN = ha.object({ type: ha.literal("source_pcb_ground_plane"), source_pcb_ground_plane_id: ha.string(), source_group_id: ha.string(), source_net_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Defines a ground plane in the source domain");
var UN = ["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"];
var ZN = ha.enum(UN);
var qN = ZN.or(ha.object({ name: ZN })).transform((e33) => typeof e33 == "string" ? e33 : e33.name);
var JN = ha.enum(["top", "bottom"]);
var QN = ha.object({ type: ha.literal("source_manually_placed_via"), source_manually_placed_via_id: ha.string(), source_group_id: ha.string(), source_net_id: ha.string(), subcircuit_id: ha.string().optional(), source_trace_id: ha.string().optional() }).describe("Defines a via that is manually placed in the source domain");
var KN = ha.object({ type: ha.literal("source_no_power_pin_defined_warning"), source_no_power_pin_defined_warning_id: kw("source_no_power_pin_defined_warning"), warning_type: ha.literal("source_no_power_pin_defined_warning").default("source_no_power_pin_defined_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a chip has no source ports with requires_power=true");
var eT = ha.object({ type: ha.literal("source_no_ground_pin_defined_warning"), source_no_ground_pin_defined_warning_id: kw("source_no_ground_pin_defined_warning"), warning_type: ha.literal("source_no_ground_pin_defined_warning").default("source_no_ground_pin_defined_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when a chip has no source ports marked as ground pins");
var tT = ha.object({ type: ha.literal("source_component_pins_underspecified_warning"), source_component_pins_underspecified_warning_id: kw("source_component_pins_underspecified_warning"), warning_type: ha.literal("source_component_pins_underspecified_warning").default("source_component_pins_underspecified_warning"), message: ha.string(), source_component_id: ha.string(), source_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Warning emitted when all ports on a source component are underspecified");
var nT = Kw.extend({ type: ha.literal("source_pin_must_be_connected_error"), source_pin_must_be_connected_error_id: kw("source_pin_must_be_connected_error"), error_type: ha.literal("source_pin_must_be_connected_error").default("source_pin_must_be_connected_error"), source_component_id: ha.string(), source_port_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a pin with mustBeConnected attribute is not connected to any trace");
var oT = Kw.extend({ type: ha.literal("unknown_error_finding_part"), unknown_error_finding_part_id: kw("unknown_error_finding_part"), error_type: ha.literal("unknown_error_finding_part").default("unknown_error_finding_part"), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when an unexpected error occurs while finding a part");
var iT = ha.object({ type: ha.literal("schematic_box"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), width: vw, height: vw, is_dashed: ha.boolean().default(false), x: vw, y: vw, subcircuit_id: ha.string().optional() }).describe("Draws a box on the schematic");
var rT = ha.object({ type: ha.literal("schematic_path"), schematic_path_id: kw("schematic_path"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), fill_color: ha.string().optional(), is_filled: ha.boolean().optional(), stroke_width: vw.nullable().optional(), stroke_color: ha.string().optional(), points: ha.array(Tw), subcircuit_id: ha.string().optional() });
var sT = ha.record(ha.object({ left_margin: bw.optional(), right_margin: bw.optional(), top_margin: bw.optional(), bottom_margin: bw.optional() }));
var aT = ha.object({ left_size: ha.number(), right_size: ha.number(), top_size: ha.number().optional(), bottom_size: ha.number().optional() });
var cT = ha.object({ left_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["top-to-bottom", "bottom-to-top"]).optional() }).optional(), right_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["top-to-bottom", "bottom-to-top"]).optional() }).optional(), top_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["left-to-right", "right-to-left"]).optional() }).optional(), bottom_side: ha.object({ pins: ha.array(ha.number()), direction: ha.enum(["left-to-right", "right-to-left"]).optional() }).optional() });
var lT = ha.union([aT, cT]);
var hT = ha.object({ type: ha.literal("schematic_component"), size: Ow, center: Tw, source_component_id: ha.string().optional(), schematic_component_id: ha.string(), schematic_symbol_id: ha.string().optional(), pin_spacing: bw.optional(), pin_styles: sT.optional(), box_width: bw.optional(), symbol_name: ha.string().optional(), port_arrangement: lT.optional(), port_labels: ha.record(ha.string()).optional(), symbol_display_value: ha.string().optional(), subcircuit_id: ha.string().optional(), schematic_group_id: ha.string().optional(), is_schematic_group: ha.boolean().optional(), source_group_id: ha.string().optional(), is_box_with_pins: ha.boolean().optional().default(true) });
var dT = ha.object({ kicad_symbol: Qw.optional() }).catchall(ha.unknown());
var uT = ha.object({ type: ha.literal("schematic_symbol"), schematic_symbol_id: ha.string(), name: ha.string().optional(), metadata: dT.optional() }).describe("Defines a named schematic symbol that can be referenced by components.");
var pT = ha.object({ type: ha.literal("schematic_line"), schematic_line_id: kw("schematic_line"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), x1: vw, y1: vw, x2: vw, y2: vw, stroke_width: vw.nullable().optional(), color: ha.string().default("#000000"), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled line on the schematic");
var mT = ha.object({ type: ha.literal("schematic_rect"), schematic_rect_id: kw("schematic_rect"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: Tw, width: vw, height: vw, rotation: ww.default(0), stroke_width: vw.nullable().optional(), color: ha.string().default("#000000"), is_filled: ha.boolean().default(false), fill_color: ha.string().optional(), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled rectangle on the schematic");
var gT = ha.object({ type: ha.literal("schematic_circle"), schematic_circle_id: kw("schematic_circle"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: Tw, radius: vw, stroke_width: vw.nullable().optional(), color: ha.string().default("#000000"), is_filled: ha.boolean().default(false), fill_color: ha.string().optional(), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled circle on the schematic");
var fT = ha.object({ type: ha.literal("schematic_arc"), schematic_arc_id: kw("schematic_arc"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), center: Tw, radius: vw, start_angle_degrees: ww, end_angle_degrees: ww, direction: ha.enum(["clockwise", "counterclockwise"]).default("counterclockwise"), stroke_width: vw.nullable().optional(), color: ha.string().default("#000000"), is_dashed: ha.boolean().default(false), subcircuit_id: ha.string().optional() }).describe("Draws a styled arc on the schematic");
var _T = ha.object({ type: ha.literal("schematic_trace"), schematic_trace_id: ha.string(), source_trace_id: ha.string().optional(), junctions: ha.array(ha.object({ x: ha.number(), y: ha.number() })), edges: ha.array(ha.object({ from: ha.object({ x: ha.number(), y: ha.number() }), to: ha.object({ x: ha.number(), y: ha.number() }), is_crossing: ha.boolean().optional(), from_schematic_port_id: ha.string().optional(), to_schematic_port_id: ha.string().optional() })), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional() });
var yT = ha.enum(["center", "left", "right", "top", "bottom"]);
var bT = ha.object({ type: ha.literal("schematic_text"), schematic_component_id: ha.string().optional(), schematic_symbol_id: ha.string().optional(), schematic_text_id: ha.string(), text: ha.string(), font_size: ha.number().default(0.18), position: ha.object({ x: vw, y: vw }), rotation: ha.number().default(0), anchor: ha.union([yT.describe("legacy"), Dw]).default("center"), color: ha.string().default("#000000"), subcircuit_id: ha.string().optional() });
var xT = ha.object({ type: ha.literal("schematic_port"), schematic_port_id: ha.string(), source_port_id: ha.string(), schematic_component_id: ha.string().optional(), center: Tw, facing_direction: ha.enum(["up", "down", "left", "right"]).optional(), distance_from_component_edge: ha.number().optional(), side_of_component: ha.enum(["top", "bottom", "left", "right"]).optional(), true_ccw_index: ha.number().optional(), pin_number: ha.number().optional(), display_pin_label: ha.string().optional(), subcircuit_id: ha.string().optional(), is_connected: ha.boolean().optional(), has_input_arrow: ha.boolean().optional(), has_output_arrow: ha.boolean().optional(), is_drawn_with_inversion_circle: ha.boolean().optional() }).describe("Defines a port on a schematic component");
var vT = ha.object({ type: ha.literal("schematic_net_label"), schematic_net_label_id: kw("schematic_net_label"), schematic_trace_id: ha.string().optional(), source_trace_id: ha.string().optional(), source_net_id: ha.string(), center: Tw, anchor_position: Tw.optional(), anchor_side: ha.enum(["top", "bottom", "left", "right"]), text: ha.string(), symbol_name: ha.string().optional(), is_movable: ha.boolean().optional(), subcircuit_id: ha.string().optional() });
var IT = Kw.extend({ type: ha.literal("schematic_error"), schematic_error_id: ha.string(), error_type: ha.literal("schematic_port_not_found").default("schematic_port_not_found"), subcircuit_id: ha.string().optional() }).describe("Defines a schematic error on the schematic");
var ST = Kw.extend({ type: ha.literal("schematic_layout_error"), schematic_layout_error_id: kw("schematic_layout_error"), error_type: ha.literal("schematic_layout_error").default("schematic_layout_error"), source_group_id: ha.string(), schematic_group_id: ha.string(), subcircuit_id: ha.string().optional() }).describe("Error emitted when schematic layout fails for a group");
var CT = ha.object({ type: ha.literal("schematic_debug_object"), label: ha.string().optional(), subcircuit_id: ha.string().optional() });
var PT = CT.extend({ shape: ha.literal("rect"), center: Tw, size: Ow });
var MT = CT.extend({ shape: ha.literal("line"), start: Tw, end: Tw });
var wT = CT.extend({ shape: ha.literal("point"), center: Tw });
var NT = ha.discriminatedUnion("shape", [PT, MT, wT]);
var TT = ha.object({ type: ha.literal("schematic_voltage_probe"), schematic_voltage_probe_id: ha.string(), source_component_id: ha.string().optional(), name: ha.string().optional(), position: Tw, schematic_trace_id: ha.string(), voltage: yw.optional(), subcircuit_id: ha.string().optional(), color: ha.string().optional(), label_alignment: Dw.optional() }).describe("Defines a voltage probe measurement point on a schematic trace");
var RT = ha.object({ type: ha.literal("schematic_manual_edit_conflict_warning"), schematic_manual_edit_conflict_warning_id: kw("schematic_manual_edit_conflict_warning"), warning_type: ha.literal("schematic_manual_edit_conflict_warning").default("schematic_manual_edit_conflict_warning"), message: ha.string(), schematic_component_id: ha.string(), schematic_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_component_id: ha.string() }).describe("Warning emitted when a component has both manual placement and explicit schX/schY coordinates");
var ET = ha.object({ type: ha.literal("schematic_group"), schematic_group_id: kw("schematic_group"), source_group_id: ha.string(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), width: bw, height: bw, center: Tw, schematic_component_ids: ha.array(ha.string()), show_as_schematic_box: ha.boolean().optional(), name: ha.string().optional(), description: ha.string().optional() }).describe("Defines a group of components on the schematic");
var AT = ha.object({ type: ha.literal("schematic_table"), schematic_table_id: kw("schematic_table"), anchor_position: Tw, column_widths: ha.array(vw), row_heights: ha.array(vw), cell_padding: vw.optional(), border_width: vw.optional(), subcircuit_id: ha.string().optional(), schematic_component_id: ha.string().optional(), anchor: Dw.optional() }).describe("Defines a table on the schematic");
var OT = ha.object({ type: ha.literal("schematic_table_cell"), schematic_table_cell_id: kw("schematic_table_cell"), schematic_table_id: ha.string(), start_row_index: ha.number(), end_row_index: ha.number(), start_column_index: ha.number(), end_column_index: ha.number(), text: ha.string().optional(), center: Tw, width: vw, height: vw, horizontal_align: ha.enum(["left", "center", "right"]).optional(), vertical_align: ha.enum(["top", "middle", "bottom"]).optional(), font_size: vw.optional(), subcircuit_id: ha.string().optional() }).describe("Defines a cell within a schematic_table");
var kT = ha.object({ type: ha.literal("schematic_sheet"), schematic_sheet_id: kw("schematic_sheet"), name: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a schematic sheet or page that components can be placed on");
var DT = ha.object({ x: vw, y: vw, bulge: ha.number().optional() });
var LT = ha.object({ vertices: ha.array(DT) });
var zT = ha.object({ outer_ring: LT, inner_rings: ha.array(LT).default([]) });
var BT = ha.object({ x: vw, y: vw, via: ha.boolean().optional(), via_to_layer: qN.optional() });
var FT = ha.array(BT);
var jT = ha.object({ x: vw, y: vw, via: ha.boolean().optional(), to_layer: qN.optional(), trace_width: vw.optional() });
var $T = ha.object({ min_trace_width: bw.optional(), min_board_edge_clearance: bw.optional(), min_via_hole_edge_to_via_hole_edge_clearance: bw.optional(), min_plated_hole_drill_edge_to_drill_edge_clearance: bw.optional(), min_trace_to_pad_edge_clearance: bw.optional(), min_pad_edge_to_pad_edge_clearance: bw.optional(), min_same_net_trace_edge_to_trace_edge_clearance: bw.optional(), min_different_net_trace_edge_to_trace_edge_clearance: bw.optional(), min_via_hole_diameter: bw.optional(), min_via_pad_diameter: bw.optional() });
var YT = ha.object({ type: ha.literal("pcb_component"), pcb_component_id: kw("pcb_component"), source_component_id: ha.string(), center: Tw, layer: qN, rotation: ww, display_offset_x: ha.string().optional().describe("How to display the x offset for this part, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this part, usually corresponding with how the user specified it"), width: bw, height: bw, do_not_place: ha.boolean().optional(), is_allowed_to_be_off_board: ha.boolean().optional(), subcircuit_id: ha.string().optional(), pcb_group_id: ha.string().optional(), position_mode: ha.enum(["packed", "relative_to_group_anchor", "relative_to_another_component", "none"]).optional(), anchor_position: Tw.optional(), anchor_alignment: Dw.optional(), positioned_relative_to_pcb_group_id: ha.string().optional(), positioned_relative_to_pcb_board_id: ha.string().optional(), cable_insertion_center: Tw.optional(), insertion_direction: ha.enum(["from_above", "from_left", "from_right", "from_front", "from_back"]).optional(), metadata: ha.object({ kicad_footprint: Hw.optional() }).optional(), obstructs_within_bounds: ha.boolean().default(true).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");
var XT = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: kw("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("circle"), hole_diameter: ha.number(), x: vw, y: vw, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var WT = XT.describe("Defines a circular hole on the PCB");
var VT = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: kw("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), x: vw, y: vw, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var HT = VT.describe("Defines a rectangular (square-capable) hole on the PCB. Use equal width/height for square.");
var GT = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: kw("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.enum(["circle", "square"]), hole_diameter: ha.number(), x: vw, y: vw, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var UT = GT.describe("Defines a circular or square hole on the PCB");
var ZT = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: kw("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("oval"), hole_width: ha.number(), hole_height: ha.number(), x: vw, y: vw, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var qT = ZT.describe("Defines an oval hole on the PCB");
var JT = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: kw("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("pill"), hole_width: ha.number(), hole_height: ha.number(), x: vw, y: vw, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var QT = JT.describe("Defines a pill-shaped hole on the PCB");
var KT = ha.object({ type: ha.literal("pcb_hole"), pcb_hole_id: kw("pcb_hole"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_component_id: ha.string().optional(), hole_shape: ha.literal("rotated_pill"), hole_width: ha.number(), hole_height: ha.number(), x: vw, y: vw, ccw_rotation: ww, is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var eR = KT.describe("Defines a rotated pill-shaped hole on the PCB");
var tR = GT.or(ZT).or(JT).or(KT).or(XT).or(VT);
var nR = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("circle"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), outer_diameter: ha.number(), hole_diameter: ha.number(), is_covered_with_solder_mask: ha.boolean().optional(), x: vw, y: vw, layers: ha.array(qN), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: kw("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var oR = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.enum(["oval", "pill"]), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), outer_width: ha.number(), outer_height: ha.number(), hole_width: ha.number(), hole_height: ha.number(), is_covered_with_solder_mask: ha.boolean().optional(), x: vw, y: vw, ccw_rotation: ww, layers: ha.array(qN), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: kw("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var iR = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("circular_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("circle"), pad_shape: ha.literal("rect"), hole_diameter: ha.number(), rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), hole_offset_x: vw.default(0), hole_offset_y: vw.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: vw, y: vw, layers: ha.array(qN), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: kw("pcb_plated_hole"), soldermask_margin: ha.number().optional(), rect_ccw_rotation: ww.optional() });
var rR = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("pill_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("pill"), pad_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), hole_offset_x: vw.default(0), hole_offset_y: vw.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: vw, y: vw, layers: ha.array(qN), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: kw("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var sR = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("rotated_pill_hole_with_rect_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.literal("rotated_pill"), pad_shape: ha.literal("rect"), hole_width: ha.number(), hole_height: ha.number(), hole_ccw_rotation: ww, rect_pad_width: ha.number(), rect_pad_height: ha.number(), rect_border_radius: ha.number().optional(), rect_ccw_rotation: ww, hole_offset_x: vw.default(0), hole_offset_y: vw.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: vw, y: vw, layers: ha.array(qN), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: kw("pcb_plated_hole"), soldermask_margin: ha.number().optional() });
var aR = ha.object({ type: ha.literal("pcb_plated_hole"), shape: ha.literal("hole_with_polygon_pad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), hole_shape: ha.enum(["circle", "oval", "pill", "rotated_pill"]), hole_diameter: ha.number().optional(), hole_width: ha.number().optional(), hole_height: ha.number().optional(), pad_outline: ha.array(ha.object({ x: vw, y: vw })).min(3), hole_offset_x: vw.default(0), hole_offset_y: vw.default(0), is_covered_with_solder_mask: ha.boolean().optional(), x: vw, y: vw, layers: ha.array(qN), port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), pcb_plated_hole_id: kw("pcb_plated_hole"), soldermask_margin: ha.number().optional(), ccw_rotation: ww.optional() });
var cR = ha.union([nR, oR, iR, rR, sR, aR]);
var lR = ha.object({ type: ha.literal("pcb_port"), pcb_port_id: kw("pcb_port"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_port_id: ha.string(), pcb_component_id: ha.string().optional(), x: vw, y: vw, layers: ha.array(qN), is_board_pinout: ha.boolean().optional() }).describe("Defines a port on the PCB");
var hR = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("circle"), pcb_smtpad_id: kw("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, radius: ha.number(), layer: qN, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var dR = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rect"), pcb_smtpad_id: kw("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), rect_border_radius: ha.number().optional(), corner_radius: ha.number().optional(), layer: qN, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), soldermask_margin_left: ha.number().optional(), soldermask_margin_top: ha.number().optional(), soldermask_margin_right: ha.number().optional(), soldermask_margin_bottom: ha.number().optional() });
var uR = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rotated_rect"), pcb_smtpad_id: kw("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), rect_border_radius: ha.number().optional(), corner_radius: ha.number().optional(), ccw_rotation: ww, layer: qN, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional(), soldermask_margin_left: ha.number().optional(), soldermask_margin_top: ha.number().optional(), soldermask_margin_right: ha.number().optional(), soldermask_margin_bottom: ha.number().optional() });
var pR = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("pill"), pcb_smtpad_id: kw("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), radius: ha.number(), layer: qN, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var mR = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("rotated_pill"), pcb_smtpad_id: kw("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), radius: ha.number(), ccw_rotation: ww, layer: qN, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var gR = ha.object({ type: ha.literal("pcb_smtpad"), shape: ha.literal("polygon"), pcb_smtpad_id: kw("pcb_smtpad"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), points: ha.array(Tw), layer: qN, port_hints: ha.array(ha.string()).optional(), pcb_component_id: ha.string().optional(), pcb_port_id: ha.string().optional(), is_covered_with_solder_mask: ha.boolean().optional(), soldermask_margin: ha.number().optional() });
var fR = ha.discriminatedUnion("shape", [hR, dR, uR, mR, pR, gR]).describe("Defines an SMT pad on the PCB");
var _R = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("circle"), pcb_solder_paste_id: kw("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, radius: ha.number(), layer: qN, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var yR = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("rect"), pcb_solder_paste_id: kw("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), layer: qN, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var bR = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("pill"), pcb_solder_paste_id: kw("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), radius: ha.number(), layer: qN, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var xR = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("rotated_rect"), pcb_solder_paste_id: kw("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), ccw_rotation: vw, layer: qN, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var vR = ha.object({ type: ha.literal("pcb_solder_paste"), shape: ha.literal("oval"), pcb_solder_paste_id: kw("pcb_solder_paste"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), x: vw, y: vw, width: ha.number(), height: ha.number(), layer: qN, pcb_component_id: ha.string().optional(), pcb_smtpad_id: ha.string().optional() });
var IR = ha.union([_R, yR, bR, xR, vR]).describe("Defines solderpaste on the PCB");
var SR = ha.object({ type: ha.literal("pcb_text"), pcb_text_id: kw("pcb_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), text: ha.string(), center: Tw, layer: qN, width: bw, height: bw, lines: ha.number(), align: ha.enum(["bottom-left"]) }).describe("Defines text on the PCB");
var CR = ha.object({ route_type: ha.literal("wire"), x: vw, y: vw, width: vw, copper_pour_id: ha.string().optional(), is_inside_copper_pour: ha.boolean().optional(), start_pcb_port_id: ha.string().optional(), end_pcb_port_id: ha.string().optional(), layer: qN });
var PR = ha.object({ route_type: ha.literal("via"), x: vw, y: vw, copper_pour_id: ha.string().optional(), is_inside_copper_pour: ha.boolean().optional(), hole_diameter: vw.optional(), outer_diameter: vw.optional(), from_layer: qN, to_layer: qN });
var MR = ha.union([CR, PR]);
var wR = ha.object({ type: ha.literal("pcb_trace"), source_trace_id: ha.string().optional(), pcb_component_id: ha.string().optional(), pcb_trace_id: kw("pcb_trace"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), route_thickness_mode: ha.enum(["constant", "interpolated"]).default("constant").optional(), route_order_index: ha.number().optional(), should_round_corners: ha.boolean().optional(), trace_length: ha.number().optional(), highlight_color: ha.string().optional(), route: ha.array(MR) }).describe("Defines a trace on the PCB");
var NR = ha.object({ type: ha.literal("pcb_trace_warning"), pcb_trace_warning_id: kw("pcb_trace_warning"), warning_type: ha.literal("pcb_trace_warning").default("pcb_trace_warning"), message: ha.string(), center: Tw.optional(), pcb_trace_id: ha.string(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace warning on the PCB");
var TR = Kw.extend({ type: ha.literal("pcb_trace_error"), pcb_trace_error_id: kw("pcb_trace_error"), error_type: ha.literal("pcb_trace_error").default("pcb_trace_error"), center: Tw.optional(), pcb_trace_id: ha.string(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace error on the PCB");
var RR = Kw.extend({ type: ha.literal("pcb_trace_missing_error"), pcb_trace_missing_error_id: kw("pcb_trace_missing_error"), error_type: ha.literal("pcb_trace_missing_error").default("pcb_trace_missing_error"), center: Tw.optional(), source_trace_id: ha.string(), pcb_component_ids: ha.array(ha.string()), pcb_port_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines an error when a source trace has no corresponding PCB trace");
var ER = Kw.extend({ type: ha.literal("pcb_port_not_matched_error"), pcb_error_id: kw("pcb_error"), error_type: ha.literal("pcb_port_not_matched_error").default("pcb_port_not_matched_error"), pcb_component_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines a trace error on the PCB where a port is not matched");
var AR = Kw.extend({ type: ha.literal("pcb_port_not_connected_error"), pcb_port_not_connected_error_id: kw("pcb_port_not_connected_error"), error_type: ha.literal("pcb_port_not_connected_error").default("pcb_port_not_connected_error"), pcb_port_ids: ha.array(ha.string()), pcb_component_ids: ha.array(ha.string()), subcircuit_id: ha.string().optional() }).describe("Defines an error when a pcb port is not connected to any trace");
var OR = ha.object({ type: ha.literal("pcb_net"), pcb_net_id: kw("pcb_net"), source_net_id: ha.string().optional(), highlight_color: ha.string().optional() }).describe("Defines a net on the PCB");
var kR = ha.object({ type: ha.literal("pcb_via"), pcb_via_id: kw("pcb_via"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), x: vw, y: vw, outer_diameter: vw.default("0.6mm"), hole_diameter: vw.default("0.25mm"), from_layer: qN.optional(), to_layer: qN.optional(), layers: ha.array(qN), pcb_trace_id: ha.string().optional(), net_is_assignable: ha.boolean().optional(), net_assigned: ha.boolean().optional(), is_tented: ha.boolean().optional() }).describe("Defines a via on the PCB");
var DR = ha.object({ type: ha.literal("pcb_board"), pcb_board_id: kw("pcb_board"), pcb_panel_id: ha.string().optional(), carrier_pcb_board_id: ha.string().optional(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), is_mounted_to_carrier_board: ha.boolean().optional(), width: bw.optional(), height: bw.optional(), center: Tw, display_offset_x: ha.string().optional().describe("How to display the x offset for this board, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this board, usually corresponding with how the user specified it"), thickness: bw.optional().default(1.4), num_layers: ha.number().optional().default(4), outline: ha.array(Tw).optional(), shape: ha.enum(["rect", "polygon"]).optional(), material: ha.enum(["fr4", "fr1"]).default("fr4"), anchor_position: Tw.optional(), anchor_alignment: Dw.optional(), position_mode: ha.enum(["relative_to_panel_anchor", "none"]).optional() }).merge($T).describe("Defines the board outline of the PCB");
var LR = ha.object({ type: ha.literal("pcb_panel"), pcb_panel_id: kw("pcb_panel"), width: bw, height: bw, center: Tw, thickness: bw.optional().default(1.4), covered_with_solder_mask: ha.boolean().optional().default(true) }).describe("Defines a PCB panel that can contain multiple boards");
var zR = Kw.extend({ type: ha.literal("pcb_placement_error"), pcb_placement_error_id: kw("pcb_placement_error"), error_type: ha.literal("pcb_placement_error").default("pcb_placement_error"), subcircuit_id: ha.string().optional() }).describe("Defines a placement error on the PCB");
var BR = Kw.extend({ type: ha.literal("pcb_panelization_placement_error"), pcb_panelization_placement_error_id: kw("pcb_panelization_placement_error"), error_type: ha.literal("pcb_panelization_placement_error").default("pcb_panelization_placement_error"), pcb_panel_id: ha.string().optional(), pcb_board_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a panelization placement error on the PCB");
var FR = ha.object({ type: ha.literal("pcb_trace_hint"), pcb_trace_hint_id: kw("pcb_trace_hint"), pcb_port_id: ha.string(), pcb_component_id: ha.string(), route: ha.array(jT), subcircuit_id: ha.string().optional() }).describe("A hint that can be used during generation of a PCB trace");
var jR = ha.object({ type: ha.literal("pcb_silkscreen_line"), pcb_silkscreen_line_id: kw("pcb_silkscreen_line"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), stroke_width: vw.default("0.1mm"), x1: vw, y1: vw, x2: vw, y2: vw, layer: JN }).describe("Defines a silkscreen line on the PCB");
var $R = ha.object({ type: ha.literal("pcb_silkscreen_path"), pcb_silkscreen_path_id: kw("pcb_silkscreen_path"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: JN, route: ha.array(Tw), stroke_width: bw }).describe("Defines a silkscreen path on the PCB");
var YR = ha.object({ type: ha.literal("pcb_silkscreen_text"), pcb_silkscreen_text_id: kw("pcb_silkscreen_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: vw.default("0.2mm"), pcb_component_id: ha.string(), text: ha.string(), is_knockout: ha.boolean().default(false).optional(), knockout_padding: ha.object({ left: bw, top: bw, bottom: bw, right: bw }).default({ left: "0.2mm", top: "0.2mm", bottom: "0.2mm", right: "0.2mm" }).optional(), ccw_rotation: ha.number().optional(), layer: qN, is_mirrored: ha.boolean().default(false).optional(), anchor_position: Tw.default({ x: 0, y: 0 }), anchor_alignment: Dw.default("center") }).describe("Defines silkscreen text on the PCB");
var XR = ha.object({ type: ha.literal("pcb_copper_text"), pcb_copper_text_id: kw("pcb_copper_text"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: vw.default("0.2mm"), pcb_component_id: ha.string(), text: ha.string(), is_knockout: ha.boolean().default(false).optional(), knockout_padding: ha.object({ left: bw, top: bw, bottom: bw, right: bw }).default({ left: "0.2mm", top: "0.2mm", bottom: "0.2mm", right: "0.2mm" }).optional(), ccw_rotation: ha.number().optional(), layer: qN, is_mirrored: ha.boolean().default(false).optional(), anchor_position: Tw.default({ x: 0, y: 0 }), anchor_alignment: Dw.default("center") }).describe("Defines copper text on the PCB");
var WR = ha.object({ type: ha.literal("pcb_silkscreen_rect"), pcb_silkscreen_rect_id: kw("pcb_silkscreen_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, width: bw, height: bw, layer: qN, stroke_width: bw.default("1mm"), corner_radius: bw.optional(), is_filled: ha.boolean().default(true).optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), ccw_rotation: ha.number().optional() }).describe("Defines a silkscreen rect on the PCB");
var VR = ha.object({ type: ha.literal("pcb_silkscreen_circle"), pcb_silkscreen_circle_id: kw("pcb_silkscreen_circle"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, radius: bw, layer: JN, stroke_width: bw.default("1mm"), is_filled: ha.boolean().optional() }).describe("Defines a silkscreen circle on the PCB");
var HR = ha.object({ type: ha.literal("pcb_silkscreen_oval"), pcb_silkscreen_oval_id: kw("pcb_silkscreen_oval"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, radius_x: vw, radius_y: vw, layer: JN, ccw_rotation: ww.optional() }).describe("Defines a silkscreen oval on the PCB");
var GR = ha.object({ type: ha.literal("pcb_silkscreen_pill"), pcb_silkscreen_pill_id: kw("pcb_silkscreen_pill"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, width: bw, height: bw, layer: qN, ccw_rotation: ha.number().optional() }).describe("Defines a silkscreen pill on the PCB");
var UR = ha.object({ type: ha.literal("pcb_fabrication_note_text"), pcb_fabrication_note_text_id: kw("pcb_fabrication_note_text"), subcircuit_id: ha.string().optional(), pcb_group_id: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: vw.default("1mm"), pcb_component_id: ha.string(), text: ha.string(), layer: JN, anchor_position: Tw.default({ x: 0, y: 0 }), anchor_alignment: ha.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center"), color: ha.string().optional() }).describe("Defines a fabrication note in text on the PCB, useful for leaving notes for assemblers or fabricators");
var ZR = ha.object({ type: ha.literal("pcb_fabrication_note_path"), pcb_fabrication_note_path_id: kw("pcb_fabrication_note_path"), pcb_component_id: ha.string(), subcircuit_id: ha.string().optional(), layer: qN, route: ha.array(Tw), stroke_width: bw, color: ha.string().optional() }).describe("Defines a fabrication path on the PCB for fabricators or assemblers");
var qR = ha.object({ type: ha.literal("pcb_fabrication_note_rect"), pcb_fabrication_note_rect_id: kw("pcb_fabrication_note_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, width: bw, height: bw, layer: JN, stroke_width: bw.default("0.1mm"), corner_radius: bw.optional(), is_filled: ha.boolean().optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a fabrication note rectangle on the PCB");
var JR = ha.object({ type: ha.literal("pcb_fabrication_note_dimension"), pcb_fabrication_note_dimension_id: kw("pcb_fabrication_note_dimension"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: JN, from: Tw, to: Tw, text: ha.string().optional(), text_ccw_rotation: ha.number().optional(), offset: bw.optional(), offset_distance: bw.optional(), offset_direction: ha.object({ x: ha.number(), y: ha.number() }).optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: bw.default("1mm"), color: ha.string().optional(), arrow_size: bw.default("1mm") }).describe("Defines a measurement annotation within PCB fabrication notes");
var QR = ha.object({ type: ha.literal("pcb_note_text"), pcb_note_text_id: kw("pcb_note_text"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: vw.default("1mm"), text: ha.string().optional(), anchor_position: Tw.default({ x: 0, y: 0 }), anchor_alignment: ha.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).default("center"), layer: JN.default("top"), is_mirrored_from_top_view: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a documentation note in text on the PCB");
var KR = ha.object({ type: ha.literal("pcb_note_rect"), pcb_note_rect_id: kw("pcb_note_rect"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), center: Tw, width: bw, height: bw, layer: JN.default("top"), stroke_width: bw.default("0.1mm"), corner_radius: bw.optional(), is_filled: ha.boolean().optional(), has_stroke: ha.boolean().optional(), is_stroke_dashed: ha.boolean().optional(), color: ha.string().optional() }).describe("Defines a rectangular documentation note on the PCB");
var eE = ha.object({ type: ha.literal("pcb_note_path"), pcb_note_path_id: kw("pcb_note_path"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), route: ha.array(Tw), layer: JN.default("top"), stroke_width: bw.default("0.1mm"), color: ha.string().optional() }).describe("Defines a polyline documentation note on the PCB");
var tE = ha.object({ type: ha.literal("pcb_note_line"), pcb_note_line_id: kw("pcb_note_line"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), text: ha.string().optional(), x1: vw, y1: vw, x2: vw, y2: vw, layer: JN.default("top"), stroke_width: vw.default("0.1mm"), color: ha.string().optional(), is_dashed: ha.boolean().optional() }).describe("Defines a straight documentation note line on the PCB");
var nE = ha.object({ type: ha.literal("pcb_note_dimension"), pcb_note_dimension_id: kw("pcb_note_dimension"), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), name: ha.string().optional(), from: Tw, to: Tw, text: ha.string().optional(), text_ccw_rotation: ha.number().optional(), offset_distance: bw.optional(), offset_direction: ha.object({ x: ha.number(), y: ha.number() }).optional(), font: ha.literal("tscircuit2024").default("tscircuit2024"), font_size: bw.default("1mm"), layer: JN.default("top"), color: ha.string().optional(), arrow_size: bw.default("1mm") }).describe("Defines a measurement annotation within PCB documentation notes");
var oE = Kw.extend({ type: ha.literal("pcb_footprint_overlap_error"), pcb_error_id: kw("pcb_error"), error_type: ha.literal("pcb_footprint_overlap_error").default("pcb_footprint_overlap_error"), pcb_smtpad_ids: ha.array(ha.string()).optional(), pcb_plated_hole_ids: ha.array(ha.string()).optional(), pcb_hole_ids: ha.array(ha.string()).optional(), pcb_keepout_ids: ha.array(ha.string()).optional() }).describe("Error emitted when a pcb footprint overlaps with another element");
var iE = Kw.extend({ type: ha.literal("pcb_courtyard_overlap_error"), pcb_error_id: kw("pcb_error"), error_type: ha.literal("pcb_courtyard_overlap_error").default("pcb_courtyard_overlap_error"), pcb_component_ids: ha.tuple([ha.string(), ha.string()]) }).describe("Error emitted when the courtyard (CrtYd) of one PCB component overlaps with the courtyard of another");
var rE = ha.object({ type: ha.literal("pcb_keepout"), shape: ha.literal("rect"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, width: vw, height: vw, pcb_keepout_id: ha.string(), layers: ha.array(ha.string()), description: ha.string().optional() }).or(ha.object({ type: ha.literal("pcb_keepout"), shape: ha.literal("circle"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, radius: vw, pcb_keepout_id: ha.string(), layers: ha.array(ha.string()), description: ha.string().optional() }));
var sE = ha.object({ type: ha.literal("pcb_cutout"), pcb_cutout_id: kw("pcb_cutout"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), pcb_board_id: ha.string().optional(), pcb_panel_id: ha.string().optional() });
var aE = sE.extend({ shape: ha.literal("rect"), center: Tw, width: bw, height: bw, rotation: ww.optional(), corner_radius: bw.optional() });
var cE = sE.extend({ shape: ha.literal("circle"), center: Tw, radius: bw });
var lE = sE.extend({ shape: ha.literal("polygon"), points: ha.array(Tw) });
var hE = sE.extend({ shape: ha.literal("path"), route: ha.array(Tw), slot_width: bw, slot_length: bw.optional(), space_between_slots: bw.optional(), slot_corner_radius: bw.optional() });
var dE = ha.discriminatedUnion("shape", [aE, cE, lE, hE]).describe("Defines a cutout on the PCB, removing board material.");
var uE = Kw.extend({ type: ha.literal("pcb_missing_footprint_error"), pcb_missing_footprint_error_id: kw("pcb_missing_footprint_error"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("pcb_missing_footprint_error").default("pcb_missing_footprint_error"), source_component_id: ha.string() }).describe("Defines a missing footprint error on the PCB");
var pE = Kw.extend({ type: ha.literal("external_footprint_load_error"), external_footprint_load_error_id: kw("external_footprint_load_error"), pcb_component_id: ha.string(), source_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), footprinter_string: ha.string().optional(), error_type: ha.literal("external_footprint_load_error").default("external_footprint_load_error") }).describe("Defines an error when an external footprint fails to load");
var mE = Kw.extend({ type: ha.literal("circuit_json_footprint_load_error"), circuit_json_footprint_load_error_id: kw("circuit_json_footprint_load_error"), pcb_component_id: ha.string(), source_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), error_type: ha.literal("circuit_json_footprint_load_error").default("circuit_json_footprint_load_error"), circuit_json: ha.array(ha.any()).optional() }).describe("Defines an error when a circuit JSON footprint fails to load");
var gE = ha.object({ type: ha.literal("pcb_group"), pcb_group_id: kw("pcb_group"), source_group_id: ha.string(), is_subcircuit: ha.boolean().optional(), subcircuit_id: ha.string().optional(), width: bw.optional(), height: bw.optional(), center: Tw, display_offset_x: ha.string().optional().describe("How to display the x offset for this group, usually corresponding with how the user specified it"), display_offset_y: ha.string().optional().describe("How to display the y offset for this group, usually corresponding with how the user specified it"), outline: ha.array(Tw).optional(), anchor_position: Tw.optional(), anchor_alignment: Dw.default("center"), position_mode: ha.enum(["packed", "relative_to_group_anchor", "none"]).optional(), positioned_relative_to_pcb_group_id: ha.string().optional(), positioned_relative_to_pcb_board_id: ha.string().optional(), pcb_component_ids: ha.array(ha.string()), child_layout_mode: ha.enum(["packed", "none"]).optional(), name: ha.string().optional(), description: ha.string().optional(), layout_mode: ha.string().optional(), autorouter_configuration: ha.object({ trace_clearance: bw }).optional(), autorouter_used_string: ha.string().optional() }).describe("Defines a group of components on the PCB");
var fE = Kw.extend({ type: ha.literal("pcb_autorouting_error"), pcb_error_id: kw("pcb_autorouting_error"), error_type: ha.literal("pcb_autorouting_error").default("pcb_autorouting_error"), subcircuit_id: ha.string().optional() }).describe("The autorouting has failed to route a portion of the board");
var _E = ha.object({ type: ha.literal("pcb_manual_edit_conflict_warning"), pcb_manual_edit_conflict_warning_id: kw("pcb_manual_edit_conflict_warning"), warning_type: ha.literal("pcb_manual_edit_conflict_warning").default("pcb_manual_edit_conflict_warning"), message: ha.string(), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), source_component_id: ha.string() }).describe("Warning emitted when a component has both manual placement and explicit pcbX/pcbY coordinates");
var yE = ha.enum(["x-", "x+", "y+", "y-"]);
var bE = ha.object({ type: ha.literal("pcb_connector_not_in_accessible_orientation_warning"), pcb_connector_not_in_accessible_orientation_warning_id: kw("pcb_connector_not_in_accessible_orientation_warning"), warning_type: ha.literal("pcb_connector_not_in_accessible_orientation_warning").default("pcb_connector_not_in_accessible_orientation_warning"), message: ha.string(), pcb_component_id: ha.string(), source_component_id: ha.string().optional(), pcb_board_id: ha.string().optional(), facing_direction: yE, recommended_facing_direction: yE, subcircuit_id: ha.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");
var xE = ha.object({ type: ha.literal("supplier_footprint_mismatch_warning"), supplier_footprint_mismatch_warning_id: kw("supplier_footprint_mismatch_warning"), warning_type: ha.literal("supplier_footprint_mismatch_warning").default("supplier_footprint_mismatch_warning"), message: ha.string(), source_component_id: ha.string(), pcb_component_id: ha.string().optional(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), supplier_name: eN.optional(), supplier_part_number: ha.string().optional(), supplier_footprint_url: ha.string().optional(), footprint_copper_intersection_over_union: ha.number() }).describe("Warning emitted when a supplier part footprint does not match the expected footprint");
var vE = ha.object({ type: ha.literal("pcb_breakout_point"), pcb_breakout_point_id: kw("pcb_breakout_point"), pcb_group_id: ha.string(), subcircuit_id: ha.string().optional(), source_trace_id: ha.string().optional(), source_port_id: ha.string().optional(), source_net_id: ha.string().optional(), x: vw, y: vw }).describe("Defines a routing target within a pcb_group for a source_trace or source_net");
var IE = ha.object({ type: ha.literal("pcb_ground_plane"), pcb_ground_plane_id: kw("pcb_ground_plane"), source_pcb_ground_plane_id: ha.string(), source_net_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Defines a ground plane on the PCB");
var SE = ha.object({ type: ha.literal("pcb_ground_plane_region"), pcb_ground_plane_region_id: kw("pcb_ground_plane_region"), pcb_ground_plane_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: qN, points: ha.array(Tw) }).describe("Defines a polygon region of a ground plane");
var CE = ha.object({ type: ha.literal("pcb_thermal_spoke"), pcb_thermal_spoke_id: kw("pcb_thermal_spoke"), pcb_ground_plane_id: ha.string(), shape: ha.string(), spoke_count: ha.number(), spoke_thickness: vw, spoke_inner_diameter: vw, spoke_outer_diameter: vw, pcb_plated_hole_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Pattern for connecting a ground plane to a plated hole");
var PE = ha.object({ type: ha.literal("pcb_copper_pour"), pcb_copper_pour_id: kw("pcb_copper_pour"), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: qN, source_net_id: ha.string().optional(), covered_with_solder_mask: ha.boolean().optional().default(true) });
var ME = PE.extend({ shape: ha.literal("rect"), center: Tw, width: bw, height: bw, rotation: ww.optional() });
var wE = PE.extend({ shape: ha.literal("brep"), brep_shape: zT });
var NE = PE.extend({ shape: ha.literal("polygon"), points: ha.array(Tw) });
var TE = ha.discriminatedUnion("shape", [ME, wE, NE]).describe("Defines a copper pour on the PCB.");
var RE = Kw.extend({ type: ha.literal("pcb_component_outside_board_error"), pcb_component_outside_board_error_id: kw("pcb_component_outside_board_error"), error_type: ha.literal("pcb_component_outside_board_error").default("pcb_component_outside_board_error"), pcb_component_id: ha.string(), pcb_board_id: ha.string(), component_center: Tw, component_bounds: ha.object({ min_x: ha.number(), max_x: ha.number(), min_y: ha.number(), max_y: ha.number() }), subcircuit_id: ha.string().optional(), source_component_id: ha.string().optional() }).describe("Error emitted when a PCB component is placed outside the board boundaries");
var EE = Kw.extend({ type: ha.literal("pcb_component_not_on_board_edge_error"), pcb_component_not_on_board_edge_error_id: kw("pcb_component_not_on_board_edge_error"), error_type: ha.literal("pcb_component_not_on_board_edge_error").default("pcb_component_not_on_board_edge_error"), pcb_component_id: ha.string(), pcb_board_id: ha.string(), component_center: Tw, pad_to_nearest_board_edge_distance: ha.number(), source_component_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a component that must be placed on the board edge is centered away from the edge");
var AE = Kw.extend({ type: ha.literal("pcb_component_invalid_layer_error"), pcb_component_invalid_layer_error_id: kw("pcb_component_invalid_layer_error"), error_type: ha.literal("pcb_component_invalid_layer_error").default("pcb_component_invalid_layer_error"), pcb_component_id: ha.string().optional(), source_component_id: ha.string(), layer: qN, subcircuit_id: ha.string().optional() }).describe("Error emitted when a component is placed on an invalid layer (components can only be on 'top' or 'bottom' layers)");
var OE = Kw.extend({ type: ha.literal("pcb_via_clearance_error"), pcb_error_id: kw("pcb_error"), error_type: ha.literal("pcb_via_clearance_error").default("pcb_via_clearance_error"), pcb_via_ids: ha.array(ha.string()).min(2), minimum_clearance: vw.optional(), actual_clearance: vw.optional(), pcb_center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when vias are closer than the allowed clearance");
var kE = Kw.extend({ type: ha.literal("pcb_via_trace_clearance_error"), pcb_via_trace_clearance_error_id: kw("pcb_via_trace_clearance_error"), error_type: ha.literal("pcb_via_trace_clearance_error").default("pcb_via_trace_clearance_error"), pcb_via_id: ha.string(), pcb_trace_id: ha.string(), minimum_clearance: vw.optional(), actual_clearance: vw.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a via and trace are closer than the allowed clearance");
var DE = Kw.extend({ type: ha.literal("pcb_pad_pad_clearance_error"), pcb_pad_pad_clearance_error_id: kw("pcb_pad_pad_clearance_error"), error_type: ha.literal("pcb_pad_pad_clearance_error").default("pcb_pad_pad_clearance_error"), pcb_pad_ids: ha.array(ha.string()).min(2), minimum_clearance: vw.optional(), actual_clearance: vw.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when pads are closer than the allowed clearance");
var LE = Kw.extend({ type: ha.literal("pcb_pad_trace_clearance_error"), pcb_pad_trace_clearance_error_id: kw("pcb_pad_trace_clearance_error"), error_type: ha.literal("pcb_pad_trace_clearance_error").default("pcb_pad_trace_clearance_error"), pcb_pad_id: ha.string(), pcb_trace_id: ha.string(), minimum_clearance: vw.optional(), actual_clearance: vw.optional(), center: ha.object({ x: ha.number().optional(), y: ha.number().optional() }).optional(), subcircuit_id: ha.string().optional() }).describe("Error emitted when a pad and trace are closer than allowed clearance");
var zE = ha.object({ type: ha.literal("pcb_courtyard_rect"), pcb_courtyard_rect_id: kw("pcb_courtyard_rect"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, width: bw, height: bw, layer: JN, ccw_rotation: ww.optional(), color: ha.string().optional() }).describe("Defines a courtyard rectangle on the PCB");
var BE = ha.object({ type: ha.literal("pcb_courtyard_outline"), pcb_courtyard_outline_id: kw("pcb_courtyard_outline"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: JN, outline: ha.array(Tw).min(2) }).describe("Defines a courtyard outline on the PCB");
var FE = ha.object({ type: ha.literal("pcb_courtyard_polygon"), pcb_courtyard_polygon_id: kw("pcb_courtyard_polygon"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), layer: JN, points: ha.array(Tw).min(3), color: ha.string().optional() }).describe("Defines a courtyard polygon on the PCB");
var jE = ha.object({ type: ha.literal("pcb_courtyard_circle"), pcb_courtyard_circle_id: kw("pcb_courtyard_circle"), pcb_component_id: ha.string(), pcb_group_id: ha.string().optional(), subcircuit_id: ha.string().optional(), center: Tw, radius: bw, layer: JN, color: ha.string().optional() }).describe("Defines a courtyard circle on the PCB");
var $E = ["obj", "stl", "3mf", "gltf", "glb", "step", "wrl"];
var YE = ["x+", "x-", "y+", "y-", "z+", "z-"];
var XE = { obj: "z+", stl: "z+", "3mf": "z+", gltf: "y+", glb: "y+", step: "z+", wrl: "y+" };
var WE = ha.object({ type: ha.literal("cad_component"), cad_component_id: ha.string(), pcb_component_id: ha.string(), source_component_id: ha.string(), position: Ew, rotation: Ew.optional(), size: Ew.optional(), layer: qN.optional(), subcircuit_id: ha.string().optional(), footprinter_string: ha.string().optional(), model_obj_url: ha.string().optional(), model_stl_url: ha.string().optional(), model_3mf_url: ha.string().optional(), model_gltf_url: ha.string().optional(), model_glb_url: ha.string().optional(), model_step_url: ha.string().optional(), model_wrl_url: ha.string().optional(), model_asset: zw.optional(), model_unit_to_mm_scale_factor: ha.number().optional(), model_board_normal_direction: ha.enum(YE).optional().describe(`The direction in the model's coordinate space that is considered "up" or "coming out of the board surface"`), model_origin_position: Ew.optional(), model_origin_alignment: ha.enum(["unknown", "center", "center_of_component_on_board_surface", "bottom_center_of_component"]).optional(), model_object_fit: ha.enum(["contain_within_bounds", "fill_bounds"]).optional().default("contain_within_bounds"), model_jscad: ha.any().optional(), show_as_translucent_model: ha.boolean().optional(), anchor_alignment: ha.enum(["center", "center_of_component_on_board_surface"]).optional().default("center") }).describe("Defines a component on the PCB");
var VE = ha.enum(["sinewave", "square", "triangle", "sawtooth"]);
var HE = ha.union([ha.string(), ha.number()]).transform((e33) => typeof e33 == "string" ? e33.endsWith("%") ? parseFloat(e33.slice(0, -1)) / 100 : parseFloat(e33) : e33).pipe(ha.number().min(0, "Duty cycle must be non-negative").max(1, "Duty cycle cannot be greater than 100%"));
var GE = ha.object({ type: ha.literal("simulation_voltage_source"), simulation_voltage_source_id: kw("simulation_voltage_source"), is_dc_source: ha.literal(true).optional().default(true), positive_source_port_id: ha.string().optional(), negative_source_port_id: ha.string().optional(), positive_source_net_id: ha.string().optional(), negative_source_net_id: ha.string().optional(), voltage: yw }).describe("Defines a DC voltage source for simulation");
var UE = ha.object({ type: ha.literal("simulation_voltage_source"), simulation_voltage_source_id: kw("simulation_voltage_source"), is_dc_source: ha.literal(false), terminal1_source_port_id: ha.string().optional(), terminal2_source_port_id: ha.string().optional(), terminal1_source_net_id: ha.string().optional(), terminal2_source_net_id: ha.string().optional(), voltage: yw.optional(), frequency: xw.optional(), peak_to_peak_voltage: yw.optional(), wave_shape: VE.optional(), phase: ww.optional(), duty_cycle: HE.optional() }).describe("Defines an AC voltage source for simulation");
var ZE = ha.union([GE, UE]).describe("Defines a voltage source for simulation");
var qE = ha.union([ha.string(), ha.number()]).transform((e33) => typeof e33 == "string" ? e33.endsWith("%") ? parseFloat(e33.slice(0, -1)) / 100 : parseFloat(e33) : e33).pipe(ha.number().min(0, "Duty cycle must be non-negative").max(1, "Duty cycle cannot be greater than 100%"));
var JE = ha.object({ type: ha.literal("simulation_current_source"), simulation_current_source_id: kw("simulation_current_source"), is_dc_source: ha.literal(true).optional().default(true), positive_source_port_id: ha.string().optional(), negative_source_port_id: ha.string().optional(), positive_source_net_id: ha.string().optional(), negative_source_net_id: ha.string().optional(), current: Iw }).describe("Defines a DC current source for simulation");
var QE = ha.object({ type: ha.literal("simulation_current_source"), simulation_current_source_id: kw("simulation_current_source"), is_dc_source: ha.literal(false), terminal1_source_port_id: ha.string().optional(), terminal2_source_port_id: ha.string().optional(), terminal1_source_net_id: ha.string().optional(), terminal2_source_net_id: ha.string().optional(), current: Iw.optional(), frequency: xw.optional(), peak_to_peak_current: Iw.optional(), wave_shape: VE.optional(), phase: ww.optional(), duty_cycle: qE.optional() }).describe("Defines an AC current source for simulation");
var KE = ha.union([JE, QE]).describe("Defines a current source for simulation");
var eA = ha.union([ha.literal("spice_dc_sweep"), ha.literal("spice_dc_operating_point"), ha.literal("spice_transient_analysis"), ha.literal("spice_ac_analysis")]);
var tA = ha.object({ type: ha.literal("simulation_experiment"), simulation_experiment_id: kw("simulation_experiment"), name: ha.string(), experiment_type: eA, time_per_step: Sw.optional(), start_time_ms: Pw.optional(), end_time_ms: Pw.optional() }).describe("Defines a simulation experiment configuration");
var nA = ha.object({ type: ha.literal("simulation_transient_voltage_graph"), simulation_transient_voltage_graph_id: kw("simulation_transient_voltage_graph"), simulation_experiment_id: ha.string(), timestamps_ms: ha.array(ha.number()).optional(), voltage_levels: ha.array(ha.number()), source_component_id: ha.string().optional(), subcircuit_connectivity_map_key: ha.string().optional(), time_per_step: Sw, start_time_ms: Pw, end_time_ms: Pw, name: ha.string().optional(), color: ha.string().optional() }).describe("Stores voltage measurements over time for a simulation");
var oA = ha.object({ type: ha.literal("simulation_switch"), simulation_switch_id: kw("simulation_switch"), source_component_id: ha.string().optional(), closes_at: Pw.optional(), opens_at: Pw.optional(), starts_closed: ha.boolean().optional(), switching_frequency: xw.optional() }).describe("Defines a switch for simulation timing control");
var iA = ha.object({ type: ha.literal("simulation_voltage_probe"), simulation_voltage_probe_id: kw("simulation_voltage_probe"), source_component_id: ha.string().optional(), name: ha.string().optional(), signal_input_source_port_id: ha.string().optional(), signal_input_source_net_id: ha.string().optional(), reference_input_source_port_id: ha.string().optional(), reference_input_source_net_id: ha.string().optional(), subcircuit_id: ha.string().optional(), color: ha.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((e33, t2) => {
if (e33.reference_input_source_port_id || e33.reference_input_source_net_id) {
const n2 = !!e33.signal_input_source_port_id || !!e33.reference_input_source_port_id, o2 = !!e33.signal_input_source_net_id || !!e33.reference_input_source_net_id;
n2 && o2 ? t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Cannot mix port and net connections in a differential probe." }) : n2 ? e33.signal_input_source_port_id && e33.reference_input_source_port_id || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id." }) : o2 && (e33.signal_input_source_net_id && e33.reference_input_source_net_id || t2.addIssue({ code: ha.ZodIssueCode.custom, message: "Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id." }));
} else
!!e33.signal_input_source_port_id == !!e33.signal_input_source_net_id && t2.addIssue({ code: ha.ZodIssueCode.custom, message: "A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id." });
});
var rA = Kw.extend({ type: ha.literal("simulation_unknown_experiment_error"), simulation_unknown_experiment_error_id: kw("simulation_unknown_experiment_error"), error_type: ha.literal("simulation_unknown_experiment_error").default("simulation_unknown_experiment_error"), simulation_experiment_id: ha.string().optional(), subcircuit_id: ha.string().optional() }).describe("An unknown error occurred during the simulation experiment.");
var sA = ha.object({ type: ha.literal("simulation_op_amp"), simulation_op_amp_id: kw("simulation_op_amp"), source_component_id: ha.string().optional(), inverting_input_source_port_id: ha.string(), non_inverting_input_source_port_id: ha.string(), output_source_port_id: ha.string(), positive_supply_source_port_id: ha.string(), negative_supply_source_port_id: ha.string() }).describe("Defines a simple ideal operational amplifier for simulation");
var aA = ha.union([YN, jN, $N, FN, WN, XN, cN, nN, iN, sN, oN, lN, pN, mN, yN, xN, vN, MN, IN, SN, CN, PN, fN, gN, GN, QN, VN, wN, RN, EN, ON, kN, KN, eT, tT, nT, oT, zN, HN, YT, tR, uE, pE, mE, _E, bE, xE, cR, rE, lR, OR, SR, wR, NR, kR, fR, IR, DR, LR, gE, FR, jR, $R, YR, GR, XR, WR, VR, HR, TR, RR, zR, BR, ER, AR, OE, kE, DE, LE, ZR, UR, qR, JR, QR, KR, eE, tE, nE, fE, oE, iE, vE, dE, IE, SE, CE, TE, RE, EE, AE, zE, BE, FE, jE, iT, bT, pT, mT, gT, fT, hT, uT, xT, _T, rT, IT, ST, vT, NT, TT, RT, ET, kT, AT, OT, WE, ZE, KE, tA, nA, oA, iA, rA, sA]);
var cA = aA;
function lA(e33, t2, n2) {
if (!t2 || !n2)
return;
let o2 = e33.get(t2);
o2 || (o2 = new Set, e33.set(t2, o2)), o2.add(n2);
let i2 = e33.get(n2);
i2 || (i2 = new Set, e33.set(n2, i2)), i2.add(t2);
}
var hA = (e33, t2 = {}) => {
const n2 = e33;
let o2 = n2._internal_store;
if (!o2) {
o2 = { counts: {}, editCount: 0 }, n2._internal_store = o2;
for (const e34 of n2) {
const t3 = e34.type, n3 = e34[`${t3}_id`];
if (!n3)
continue;
const i3 = Number.parseInt(n3.split("_").pop());
Number.isNaN(i3) || (o2.counts[t3] = Math.max(o2.counts[t3] ?? 0, i3));
}
}
const i2 = new Proxy({}, { get: (e34, r2) => {
if (r2 === "toArray")
return () => (n2.editCount = o2.editCount, n2);
if (r2 === "editCount")
return o2.editCount;
if (r2 === "subtree")
return (e35) => hA(function(e36, t3) {
if (!t3.subcircuit_id && !t3.source_group_id)
return [...e36];
let n3 = t3;
if (t3.subcircuit_id) {
const o4 = new Set([t3.subcircuit_id]), i4 = new Map, r4 = new Map;
for (const t4 of e36)
if (t4.type === "source_group") {
const { source_group_id: e37, subcircuit_id: n4 } = t4;
n4 && r4.set(e37, n4);
const o5 = t4.parent_source_group_id;
o5 && (i4.has(o5) || i4.set(o5, []), i4.get(o5).push(e37));
}
let s4;
for (const [e37, n4] of r4)
if (n4 === t3.subcircuit_id) {
s4 = e37;
break;
}
if (s4) {
const e37 = (t4) => {
const n4 = i4.get(t4) || [];
for (const t5 of n4) {
const n5 = r4.get(t5);
n5 && o4.add(n5), e37(t5);
}
};
e37(s4), n3 = { ...t3, subcircuit_ids: Array.from(o4) };
}
}
const o3 = new Map;
for (const t4 of e36) {
const e37 = t4[`${t4.type}_id`];
typeof e37 == "string" && o3.set(e37, t4);
}
const i3 = new Map;
for (const t4 of e36) {
const e37 = Object.entries(t4);
for (const [n4, r4] of e37)
if (n4 !== "parent_source_group_id") {
if (n4.endsWith("_id") && typeof r4 == "string")
lA(i3, t4, o3.get(r4));
else if (n4.endsWith("_ids") && Array.isArray(r4))
for (const e38 of r4)
typeof e38 == "string" && lA(i3, t4, o3.get(e38));
}
}
const r3 = [], s3 = new Set;
for (const t4 of e36) {
let e37 = false;
(n3.subcircuit_id && ("subcircuit_id" in t4) && t4.subcircuit_id === n3.subcircuit_id || n3.subcircuit_ids && ("subcircuit_id" in t4) && t4.subcircuit_id && n3.subcircuit_ids.includes(t4.subcircuit_id) || n3.source_group_id && ("source_group_id" in t4) && t4.source_group_id === n3.source_group_id || n3.source_group_id && ("member_source_group_ids" in t4) && Array.isArray(t4.member_source_group_ids) && t4.member_source_group_ids.includes(n3.source_group_id)) && (e37 = true), e37 && (r3.push(t4), s3.add(t4));
}
for (;r3.length > 0; ) {
const e37 = r3.shift(), t4 = i3.get(e37);
if (t4)
for (const e38 of t4)
s3.has(e38) || (s3.add(e38), r3.push(e38));
}
return e36.filter((e37) => s3.has(e37));
}(n2, e35), t2);
if (r2 === "insert")
return (e35) => {
const i3 = e35.type;
if (!i3)
throw new Error("insert requires an element with a type");
o2.counts[i3] ??= -1, o2.counts[i3]++;
const r3 = o2.counts[i3], s3 = { ...e35, type: i3, [`${i3}_id`]: `${i3}_${r3}` };
if (t2.validateInserts) {
(hw[i3] ?? cA).parse(s3);
}
return n2.push(s3), o2.editCount++, s3;
};
if (r2 === "insertAll")
return (e35) => e35.map((e36) => i2.insert(e36));
const s2 = r2;
return { get: (e35) => n2.find((t3) => t3.type === s2 && t3[`${s2}_id`] === e35), getUsing: (e35) => {
const t3 = Object.keys(e35);
if (t3.length !== 1)
throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");
const o3 = t3[0], i3 = o3.replace("_id", ""), r3 = n2.find((t4) => t4.type === i3 && t4[o3] === e35[o3]);
return r3 ? n2.find((e36) => e36.type === s2 && e36[`${s2}_id`] === r3[`${s2}_id`]) : null;
}, getWhere: (e35) => {
const t3 = Object.keys(e35);
return n2.find((n3) => n3.type === s2 && t3.every((t4) => n3[t4] === e35[t4]));
}, list: (e35) => {
const t3 = e35 ? Object.keys(e35) : [];
return n2.filter((n3) => n3.type === s2 && t3.every((t4) => n3[t4] === e35[t4]));
}, insert: (e35) => {
o2.counts[s2] ??= -1, o2.counts[s2]++;
const i3 = o2.counts[s2], r3 = { type: s2, [`${s2}_id`]: `${s2}_${i3}`, ...e35 };
if (t2.validateInserts) {
(hw[s2] ?? cA).parse(r3);
}
return n2.push(r3), o2.editCount++, r3;
}, delete: (e35) => {
const t3 = n2.find((t4) => t4[`${s2}_id`] === e35);
t3 && (n2.splice(n2.indexOf(t3), 1), o2.editCount++);
}, update: (e35, t3) => {
const i3 = n2.find((t4) => t4.type === s2 && t4[`${s2}_id`] === e35);
return i3 ? (Object.assign(i3, t3), o2.editCount++, i3) : null;
}, select: (e35) => {
if (s2 === "source_component")
return n2.find((t3) => t3.type === "source_component" && t3.name === e35.replace(/\./g, ""));
if (s2 === "pcb_port" || s2 === "source_port" || s2 === "schematic_port") {
const [t3, o3] = e35.replace(/\./g, "").split(/[\s\>]+/), i3 = n2.find((e36) => e36.type === "source_component" && e36.name === t3);
if (!i3)
return null;
const r3 = n2.find((e36) => e36.type === "source_port" && e36.source_component_id === i3.source_component_id && (e36.name === o3 || (e36.port_hints ?? []).includes(o3)));
if (!r3)
return null;
if (s2 === "source_port")
return r3;
if (s2 === "pcb_port")
return n2.find((e36) => e36.type === "pcb_port" && e36.source_port_id === r3.source_port_id);
if (s2 === "schematic_port")
return n2.find((e36) => e36.type === "schematic_port" && e36.source_port_id === r3.source_port_id);
}
} };
} });
return i2;
};
hA.unparsed = hA;
var dA = hA;
function uA(e33) {
const t2 = e33.type;
return `${t2}:${e33[`${t2}_id`]}`;
}
var pA = (e33, t2 = {}) => {
let n2 = e33._internal_store_indexed;
if (!n2) {
n2 = { counts: {}, editCount: 0, indexes: {} };
for (const t3 of e33) {
const e34 = t3.type, o3 = t3[`${e34}_id`];
if (!o3)
continue;
const i3 = Number.parseInt(o3.split("_").pop() || "");
Number.isNaN(i3) || (n2.counts[e34] = Math.max(n2.counts[e34] ?? 0, i3));
}
const o2 = t2.indexConfig || {}, i2 = n2.indexes;
if (o2.byId && (i2.byId = new Map), o2.byType && (i2.byType = new Map), o2.byRelation && (i2.byRelation = new Map), o2.bySubcircuit && (i2.bySubcircuit = new Map), o2.byCustomField && o2.byCustomField.length > 0) {
i2.byCustomField = new Map;
for (const e34 of o2.byCustomField)
i2.byCustomField.set(e34, new Map);
}
for (const t3 of e33) {
if (o2.byId) {
const e34 = uA(t3);
i2.byId.set(e34, t3);
}
if (o2.byType) {
const e34 = i2.byType.get(t3.type) || [];
e34.push(t3), i2.byType.set(t3.type, e34);
}
if (o2.byRelation) {
const e34 = Object.entries(t3);
for (const [n3, o3] of e34)
if (n3.endsWith("_id") && n3 !== `${t3.type}_id` && typeof o3 == "string") {
const e35 = i2.byRelation.get(n3) || new Map, r2 = e35.get(o3) || [];
r2.push(t3), e35.set(o3, r2), i2.byRelation.set(n3, e35);
}
}
if (o2.bySubcircuit && "subcircuit_id" in t3) {
const e34 = t3.subcircuit_id;
if (e34 && typeof e34 == "string") {
const n3 = i2.bySubcircuit.get(e34) || [];
n3.push(t3), i2.bySubcircuit.set(e34, n3);
}
}
if (o2.byCustomField && i2.byCustomField) {
for (const e34 of o2.byCustomField)
if (e34 in t3) {
const n3 = t3[e34];
if (n3 !== undefined && (typeof n3 == "string" || typeof n3 == "number")) {
const o3 = String(n3), r2 = i2.byCustomField.get(e34), s2 = r2.get(o3) || [];
s2.push(t3), r2.set(o3, s2);
}
}
}
}
e33._internal_store_indexed = n2;
}
return new Proxy({}, { get: (o2, i2) => {
if (i2 === "toArray")
return () => (e33.editCount = n2.editCount, e33);
if (i2 === "editCount")
return n2.editCount;
const r2 = i2;
return { get: (o3) => {
const i3 = t2.indexConfig || {};
if (i3.byId && n2.indexes.byId)
return n2.indexes.byId.get(`${r2}:${o3}`) || null;
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e34) => e34[`${r2}_id`] === o3) || null;
}
return e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === o3) || null;
}, getUsing: (o3) => {
const i3 = t2.indexConfig || {}, s2 = Object.keys(o3);
if (s2.length !== 1)
throw new Error("getUsing requires exactly one key, e.g. { pcb_component_id }");
const a2 = s2[0], c2 = a2.replace("_id", "");
if (i3.byRelation && n2.indexes.byRelation) {
const t3 = n2.indexes.byRelation.get(a2);
if (t3) {
const s3 = (t3.get(o3[a2]) || []).find((e34) => e34.type === c2);
if (!s3)
return null;
const l3 = s3[`${r2}_id`];
if (i3.byId && n2.indexes.byId)
return n2.indexes.byId.get(`${r2}:${l3}`) || null;
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e34) => e34[`${r2}_id`] === l3) || null;
}
return e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === l3) || null;
}
}
const l2 = e33.find((e34) => e34.type === c2 && e34[a2] === o3[a2]);
return l2 && e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === l2[`${r2}_id`]) || null;
}, getWhere: (o3) => {
const i3 = t2.indexConfig || {}, s2 = Object.keys(o3);
if (s2.length === 1 && i3.byCustomField && n2.indexes.byCustomField) {
const e34 = s2[0], t3 = n2.indexes.byCustomField.get(e34);
if (t3) {
const n3 = String(o3[e34]);
return (t3.get(n3) || []).find((e35) => e35.type === r2) || null;
}
}
if ("subcircuit_id" in o3 && i3.bySubcircuit && n2.indexes.bySubcircuit) {
const e34 = o3.subcircuit_id;
return (n2.indexes.bySubcircuit.get(e34) || []).find((e35) => e35.type === r2 && s2.every((t3) => e35[t3] === o3[t3])) || null;
}
if (i3.byType && n2.indexes.byType) {
return (n2.indexes.byType.get(r2) || []).find((e34) => s2.every((t3) => e34[t3] === o3[t3])) || null;
}
return e33.find((e34) => e34.type === r2 && s2.every((t3) => e34[t3] === o3[t3])) || null;
}, list: (o3) => {
const i3 = t2.indexConfig || {}, s2 = o3 ? Object.keys(o3) : [];
if (s2.length === 0 && i3.byType && n2.indexes.byType)
return n2.indexes.byType.get(r2) || [];
if (s2.length === 1 && s2[0] === "subcircuit_id" && i3.bySubcircuit && n2.indexes.bySubcircuit) {
const e34 = o3.subcircuit_id;
return (n2.indexes.bySubcircuit.get(e34) || []).filter((e35) => e35.type === r2);
}
let a2;
return a2 = i3.byType && n2.indexes.byType ? n2.indexes.byType.get(r2) || [] : e33.filter((e34) => e34.type === r2), s2.length > 0 ? a2.filter((e34) => s2.every((t3) => e34[t3] === o3[t3])) : a2;
}, insert: (o3) => {
n2.counts[r2] ??= -1, n2.counts[r2]++;
const i3 = n2.counts[r2], s2 = { type: r2, [`${r2}_id`]: `${r2}_${i3}`, ...o3 };
if (t2.validateInserts) {
(hw[r2] ?? cA).parse(s2);
}
e33.push(s2), n2.editCount++;
const a2 = t2.indexConfig || {};
if (a2.byId && n2.indexes.byId) {
const e34 = uA(s2);
n2.indexes.byId.set(e34, s2);
}
if (a2.byType && n2.indexes.byType) {
const e34 = n2.indexes.byType.get(r2) || [];
e34.push(s2), n2.indexes.byType.set(r2, e34);
}
if (a2.byRelation && n2.indexes.byRelation) {
const e34 = Object.entries(s2);
for (const [t3, o4] of e34)
if (t3.endsWith("_id") && t3 !== `${s2.type}_id` && typeof o4 == "string") {
const e35 = n2.indexes.byRelation.get(t3) || new Map, i4 = e35.get(o4) || [];
i4.push(s2), e35.set(o4, i4), n2.indexes.byRelation.set(t3, e35);
}
}
if (a2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in s2) {
const e34 = s2.subcircuit_id;
if (e34 && typeof e34 == "string") {
const t3 = n2.indexes.bySubcircuit.get(e34) || [];
t3.push(s2), n2.indexes.bySubcircuit.set(e34, t3);
}
}
if (a2.byCustomField && n2.indexes.byCustomField) {
for (const e34 of a2.byCustomField)
if (e34 in s2) {
const t3 = s2[e34];
if (t3 !== undefined && (typeof t3 == "string" || typeof t3 == "number")) {
const o4 = String(t3), i4 = n2.indexes.byCustomField.get(e34), r3 = i4.get(o4) || [];
r3.push(s2), i4.set(o4, r3);
}
}
}
return s2;
}, delete: (o3) => {
const i3 = t2.indexConfig || {};
let s2;
if (i3.byId && n2.indexes.byId)
s2 = n2.indexes.byId.get(`${r2}:${o3}`);
else if (i3.byType && n2.indexes.byType) {
const e34 = n2.indexes.byType.get(r2) || [];
s2 = e34.find((e35) => e35[`${r2}_id`] === o3);
} else
s2 = e33.find((e34) => e34[`${r2}_id`] === o3);
if (!s2)
return;
const a2 = e33.indexOf(s2);
if (a2 >= 0 && (e33.splice(a2, 1), n2.editCount++), i3.byId && n2.indexes.byId) {
const e34 = uA(s2);
n2.indexes.byId.delete(e34);
}
if (i3.byType && n2.indexes.byType) {
const e34 = (n2.indexes.byType.get(r2) || []).filter((e35) => e35[`${r2}_id`] !== o3);
n2.indexes.byType.set(r2, e34);
}
if (i3.byRelation && n2.indexes.byRelation)
for (const [e34, t3] of n2.indexes.byRelation.entries())
for (const [e35, n3] of t3.entries()) {
const o4 = n3.filter((e36) => e36 !== s2);
o4.length === 0 ? t3.delete(e35) : t3.set(e35, o4);
}
if (i3.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in s2) {
const e34 = s2.subcircuit_id;
if (e34) {
const t3 = (n2.indexes.bySubcircuit.get(e34) || []).filter((e35) => e35 !== s2);
t3.length === 0 ? n2.indexes.bySubcircuit.delete(e34) : n2.indexes.bySubcircuit.set(e34, t3);
}
}
if (i3.byCustomField && n2.indexes.byCustomField)
for (const e34 of n2.indexes.byCustomField.values())
for (const [t3, n3] of e34.entries()) {
const o4 = n3.filter((e35) => e35 !== s2);
o4.length === 0 ? e34.delete(t3) : e34.set(t3, o4);
}
}, update: (o3, i3) => {
const s2 = t2.indexConfig || {};
let a2;
if (s2.byId && n2.indexes.byId)
a2 = n2.indexes.byId.get(`${r2}:${o3}`);
else if (s2.byType && n2.indexes.byType) {
const e34 = n2.indexes.byType.get(r2) || [];
a2 = e34.find((e35) => e35[`${r2}_id`] === o3);
} else
a2 = e33.find((e34) => e34.type === r2 && e34[`${r2}_id`] === o3);
if (!a2)
return null;
if (s2.byRelation && n2.indexes.byRelation) {
const e34 = Object.entries(a2);
for (const [t3, o4] of e34)
if (t3.endsWith("_id") && t3 !== `${a2.type}_id` && typeof o4 == "string" && t3 in i3 && i3[t3] !== o4) {
const e35 = n2.indexes.byRelation.get(t3);
if (e35) {
const t4 = (e35.get(o4) || []).filter((e36) => e36 !== a2);
t4.length === 0 ? e35.delete(o4) : e35.set(o4, t4);
}
}
}
if (s2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in a2 && "subcircuit_id" in i3) {
const e34 = a2.subcircuit_id;
if (e34 !== i3.subcircuit_id) {
const t3 = (n2.indexes.bySubcircuit.get(e34) || []).filter((e35) => e35 !== a2);
t3.length === 0 ? n2.indexes.bySubcircuit.delete(e34) : n2.indexes.bySubcircuit.set(e34, t3);
}
}
if (s2.byCustomField && n2.indexes.byCustomField) {
for (const e34 of s2.byCustomField)
if (e34 in a2 && e34 in i3 && a2[e34] !== i3[e34]) {
const t3 = n2.indexes.byCustomField.get(e34);
if (t3) {
const n3 = String(a2[e34]), o4 = (t3.get(n3) || []).filter((e35) => e35 !== a2);
o4.length === 0 ? t3.delete(n3) : t3.set(n3, o4);
}
}
}
if (Object.assign(a2, i3), n2.editCount++, s2.byRelation && n2.indexes.byRelation) {
const e34 = Object.entries(a2);
for (const [t3, o4] of e34)
if (t3.endsWith("_id") && t3 !== `${a2.type}_id` && typeof o4 == "string" && t3 in i3) {
const e35 = n2.indexes.byRelation.get(t3) || new Map, i4 = e35.get(o4) || [];
i4.includes(a2) || (i4.push(a2), e35.set(o4, i4), n2.indexes.byRelation.set(t3, e35));
}
}
if (s2.bySubcircuit && n2.indexes.bySubcircuit && "subcircuit_id" in a2 && "subcircuit_id" in i3) {
const e34 = a2.subcircuit_id;
if (e34 && typeof e34 == "string") {
const t3 = n2.indexes.bySubcircuit.get(e34) || [];
t3.includes(a2) || (t3.push(a2), n2.indexes.bySubcircuit.set(e34, t3));
}
}
if (s2.byCustomField && n2.indexes.byCustomField) {
for (const e34 of s2.byCustomField)
if (e34 in a2 && e34 in i3) {
const t3 = a2[e34];
if (t3 !== undefined && (typeof t3 == "string" || typeof t3 == "number")) {
const o4 = String(t3), i4 = n2.indexes.byCustomField.get(e34), r3 = i4.get(o4) || [];
r3.includes(a2) || (r3.push(a2), i4.set(o4, r3));
}
}
}
return a2;
}, select: (t3) => {
if (r2 === "source_component")
return e33.find((e34) => e34.type === "source_component" && e34.name === t3.replace(/\./g, "")) || null;
if (r2 === "pcb_port" || r2 === "source_port" || r2 === "schematic_port") {
const [n3, o3] = t3.replace(/\./g, "").split(/[\s\>]+/), i3 = e33.find((e34) => e34.type === "source_component" && e34.name === n3);
if (!i3)
return null;
const s2 = e33.find((e34) => e34.type === "source_port" && e34.source_component_id === i3.source_component_id && (e34.name === o3 || (e34.port_hints ?? []).includes(o3)));
if (!s2)
return null;
if (r2 === "source_port")
return s2;
if (r2 === "pcb_port")
return e33.find((e34) => e34.type === "pcb_port" && e34.source_port_id === s2.source_port_id) || null;
if (r2 === "schematic_port")
return e33.find((e34) => e34.type === "schematic_port" && e34.source_port_id === s2.source_port_id) || null;
}
return null;
} };
} });
};
pA.unparsed = pA;
var mA = (e33) => e33[`${e33.type}_id`];
function gA(e33, t2) {
const n2 = hA(e33).pcb_trace.get(t2);
if (!n2)
return `trace[${t2}]`;
const o2 = n2.route.flatMap((e34) => [e34.start_pcb_port_id, e34.end_pcb_port_id]).filter(Boolean);
if (o2.length === 0)
return `trace[${t2}]`;
return `trace[${o2.map((t3) => {
const n3 = function(t4) {
const n4 = hA(e33).pcb_port.get(t4);
if (!n4)
return null;
const o3 = n4.pcb_component_id ? hA(e33).pcb_component.get(n4.pcb_component_id) : undefined;
if (!o3)
return null;
const i2 = hA(e33).source_component.get(o3.source_component_id);
if (!i2)
return null;
const r2 = hA(e33).source_port.get(n4.source_port_id), s2 = r2?.port_hints ? r2.port_hints[1] : "";
return { componentName: i2.name, portHint: s2 };
}(t3);
return n3 ? `.${n3.componentName} > port.${n3.portHint}` : `port[${t3}]`;
}).join(", ")}]`;
}
var fA = (e33, t2) => {
const n2 = hA(e33).pcb_port.get(t2);
if (!n2)
return `pcb_port[#${t2}]`;
const o2 = n2.pcb_component_id ? hA(e33).pcb_component.get(n2.pcb_component_id) : undefined;
if (!o2)
return `pcb_port[#${t2}]`;
const i2 = hA(e33).source_component.get(o2.source_component_id);
if (!i2)
return `pcb_port[#${t2}]`;
const r2 = hA(e33).source_port.get(n2.source_port_id);
if (!r2)
return `pcb_port[#${t2}]`;
let s2;
return s2 = r2?.port_hints && r2.port_hints.length > 0 || r2.port_hints && r2.port_hints.length > 0 ? r2.port_hints[0] : t2, `pcb_port[.${i2.name} > .${s2}]`;
};
var _A = (e33, t2) => {
if (typeof t2 == "string") {
const n2 = ((e34, t3) => e34.find((e35) => mA(e35) === t3) ?? null)(e33, t2);
return _A(e33, n2);
}
switch (t2.type) {
case "pcb_port":
return fA(e33, t2.pcb_port_id);
case "pcb_smtpad":
return function(e34, t3) {
const n2 = hA(e34).pcb_smtpad.get(t3);
return n2 && n2.pcb_port_id ? fA(e34, n2.pcb_port_id) : `smtpad[${t3}]`;
}(e33, t2.pcb_smtpad_id);
case "pcb_trace":
return gA(e33, t2.pcb_trace_id);
case "source_component":
return `source_component[${t2.name}]`;
default:
return `${t2.type}[#${mA(t2)}]`;
}
};
var yA = (e33, t2) => ({ minX: Math.min(e33.minX, t2.minX), minY: Math.min(e33.minY, t2.minY), maxX: Math.max(e33.maxX, t2.maxX), maxY: Math.max(e33.maxY, t2.maxY) });
var bA = (e33, t2, n2) => {
const o2 = n2 / 2;
return { minX: e33 - o2, minY: t2 - o2, maxX: e33 + o2, maxY: t2 + o2 };
};
var xA = (e33, t2, n2, o2, i2) => {
const r2 = n2 / 2, s2 = o2 / 2, a2 = i2 * Math.PI / 180, c2 = Math.cos(a2), l2 = Math.sin(a2), h2 = [{ x: -r2, y: -s2 }, { x: r2, y: -s2 }, { x: r2, y: s2 }, { x: -r2, y: s2 }].map((n3) => ({ x: e33 + n3.x * c2 - n3.y * l2, y: t2 + n3.x * l2 + n3.y * c2 }));
return { minX: Math.min(...h2.map((e34) => e34.x)), minY: Math.min(...h2.map((e34) => e34.y)), maxX: Math.max(...h2.map((e34) => e34.x)), maxY: Math.max(...h2.map((e34) => e34.y)) };
};
var vA = (e33) => e33[`${e33.type}_id`];
function IA(e33, t2, n2, o2) {
return Math.sqrt((n2 - e33) ** 2 + (o2 - t2) ** 2);
}
var SA = class {
buckets;
objectsById;
getBounds;
getId;
CELL_SIZE = 0.4;
constructor({ objects: e33, getBounds: t2, getId: n2, CELL_SIZE: o2 }) {
this.buckets = new Map, this.objectsById = new Map, this.getBounds = t2, this.getId = n2 ?? (() => this._getNextId()), this.CELL_SIZE = o2 ?? this.CELL_SIZE;
for (const t3 of e33)
this.addObject(t3);
}
_idCounter = 0;
_getNextId() {
return "" + this._idCounter++;
}
addObject(e33) {
const t2 = this.getBounds(e33), n2 = this.getId(e33), o2 = { ...e33, spatialIndexId: n2 };
this.objectsById.set(n2, o2);
const i2 = Math.floor(t2.minX / this.CELL_SIZE), r2 = Math.floor(t2.minY / this.CELL_SIZE), s2 = Math.floor(t2.maxX / this.CELL_SIZE), a2 = Math.floor(t2.maxY / this.CELL_SIZE);
for (let e34 = i2;e34 <= s2; e34++)
for (let t3 = r2;t3 <= a2; t3++) {
const n3 = `${e34}x${t3}`, i3 = this.buckets.get(n3);
i3 ? i3.push(o2) : this.buckets.set(n3, [o2]);
}
}
removeObject(e33) {
const t2 = this.objectsById.get(e33);
if (!t2)
return false;
this.objectsById.delete(e33);
const n2 = this.getBounds(t2), o2 = Math.floor(n2.minX / this.CELL_SIZE), i2 = Math.floor(n2.minY / this.CELL_SIZE), r2 = Math.floor(n2.maxX / this.CELL_SIZE), s2 = Math.floor(n2.maxY / this.CELL_SIZE);
for (let t3 = o2;t3 <= r2; t3++)
for (let n3 = i2;n3 <= s2; n3++) {
const o3 = `${t3}x${n3}`, i3 = this.buckets.get(o3);
if (i3) {
const t4 = i3.findIndex((t5) => t5.spatialIndexId === e33);
t4 !== -1 && (i3.splice(t4, 1), i3.length === 0 && this.buckets.delete(o3));
}
}
return true;
}
getBucketKey(e33, t2) {
return `${Math.floor(e33 / this.CELL_SIZE)}x${Math.floor(t2 / this.CELL_SIZE)}`;
}
getObjectsInBounds(e33, t2 = 0) {
const n2 = [], o2 = new Set, i2 = Math.floor((e33.minX - t2) / this.CELL_SIZE), r2 = Math.floor((e33.minY - t2) / this.CELL_SIZE), s2 = Math.floor((e33.maxX + t2) / this.CELL_SIZE), a2 = Math.floor((e33.maxY + t2) / this.CELL_SIZE);
for (let e34 = i2;e34 <= s2; e34++)
for (let t3 = r2;t3 <= a2; t3++) {
const i3 = `${e34}x${t3}`, r3 = this.buckets.get(i3) || [];
for (const e35 of r3) {
const t4 = e35.spatialIndexId;
o2.has(t4) || (o2.add(t4), n2.push(e35));
}
}
return n2;
}
};
var CA = 0.1;
var PA = 0.1;
var MA = CA;
var wA = CA;
var NA = 0.005;
function TA(e33) {
return e33.type === "pcb_trace_segment" || e33.type === "pcb_smtpad" ? [e33.layer] : e33.type === "pcb_plated_hole" ? Array.isArray(e33.layers) ? e33.layers : [...UN] : e33.type === "pcb_hole" ? [...UN] : e33.type === "pcb_via" ? Array.isArray(e33.layers) ? e33.layers : [...UN] : e33.type === "pcb_keepout" && Array.isArray(e33.layers) ? e33.layers : [];
}
var RA = (e33, t2) => {
const n2 = { x: e33.x1, y: e33.y1 }, o2 = { x: e33.x2, y: e33.y2 }, i2 = t2.minX, r2 = t2.minY, s2 = t2.maxX, a2 = t2.maxY;
if (n2.x === o2.x && n2.y === o2.y) {
const e34 = Math.max(i2, Math.min(s2, n2.x)), t3 = Math.max(r2, Math.min(a2, n2.y));
return e34 === n2.x && t3 === n2.y ? { x: n2.x, y: n2.y } : { x: e34, y: t3 };
}
const c2 = o2.x - n2.x, l2 = o2.y - n2.y, h2 = c2 !== 0 ? (i2 - n2.x) / c2 : Number.NEGATIVE_INFINITY, d2 = c2 !== 0 ? (s2 - n2.x) / c2 : Number.POSITIVE_INFINITY, u2 = l2 !== 0 ? (r2 - n2.y) / l2 : Number.NEGATIVE_INFINITY, p2 = l2 !== 0 ? (a2 - n2.y) / l2 : Number.POSITIVE_INFINITY, m2 = Math.max(Math.min(h2, d2), Math.min(u2, p2)), g2 = Math.min(Math.max(h2, d2), Math.max(u2, p2));
if (m2 <= g2 && g2 >= 0 && m2 <= 1) {
const e34 = Math.max(0, Math.min(1, m2));
return { x: n2.x + e34 * c2, y: n2.y + e34 * l2 };
}
const f2 = { x: Math.max(i2, Math.min(s2, n2.x)), y: Math.max(r2, Math.min(a2, n2.y)) }, _2 = { x: Math.max(i2, Math.min(s2, o2.x)), y: Math.max(r2, Math.min(a2, o2.y)) }, y2 = (f2.x - n2.x) ** 2 + (f2.y - n2.y) ** 2, b2 = (_2.x - o2.x) ** 2 + (_2.y - o2.y) ** 2, x2 = [{ start: { x: i2, y: r2 }, end: { x: s2, y: r2 } }, { start: { x: s2, y: r2 }, end: { x: s2, y: a2 } }, { start: { x: s2, y: a2 }, end: { x: i2, y: a2 } }, { start: { x: i2, y: a2 }, end: { x: i2, y: r2 } }];
let v2 = Math.min(y2, b2), I2 = y2 <= b2 ? f2 : _2;
const S2 = (e34, t3, n3) => Math.max(t3, Math.min(n3, e34));
for (const e34 of x2) {
const t3 = { x: o2.x - n2.x, y: o2.y - n2.y }, i3 = { x: e34.end.x - e34.start.x, y: e34.end.y - e34.start.y }, r3 = { x: n2.x - e34.start.x, y: n2.y - e34.start.y }, s3 = t3.x * t3.x + t3.y * t3.y, a3 = t3.x * i3.x + t3.y * i3.y, c3 = t3.x * r3.x + t3.y * r3.y, l3 = i3.x * i3.x + i3.y * i3.y, h3 = i3.x * r3.x + i3.y * r3.y, d3 = s3 * l3 - a3 * a3;
if (Math.abs(d3) < 0.0000000001)
continue;
let u3 = (a3 * h3 - l3 * c3) / d3, p3 = (s3 * h3 - a3 * c3) / d3;
u3 = S2(u3, 0, 1), p3 = S2(p3, 0, 1);
const m3 = { x: n2.x + u3 * t3.x, y: n2.y + u3 * t3.y }, g3 = { x: e34.start.x + p3 * i3.x, y: e34.start.y + p3 * i3.y }, f3 = m3.x - g3.x, _3 = m3.y - g3.y, y3 = f3 * f3 + _3 * _3;
y3 < v2 && (v2 = y3, I2 = { x: (m3.x + g3.x) / 2, y: (m3.y + g3.y) / 2 });
}
return I2;
};
var EA = (e33, t2) => {
const n2 = { x: e33.x1, y: e33.y1 }, o2 = { x: e33.x2, y: e33.y2 }, i2 = { x: t2.x1, y: t2.y1 }, r2 = { x: t2.x2, y: t2.y2 }, s2 = { x: o2.x - n2.x, y: o2.y - n2.y }, a2 = { x: r2.x - i2.x, y: r2.y - i2.y }, c2 = s2.x * s2.x + s2.y * s2.y, l2 = a2.x * a2.x + a2.y * a2.y;
if (c2 === 0 || l2 === 0) {
if (c2 === 0 && l2 === 0)
return { x: (n2.x + i2.x) / 2, y: (n2.y + i2.y) / 2 };
if (c2 === 0) {
const e35 = OA(((n2.x - i2.x) * a2.x + (n2.y - i2.y) * a2.y) / l2, 0, 1), t4 = { x: i2.x + e35 * a2.x, y: i2.y + e35 * a2.y };
return { x: (n2.x + t4.x) / 2, y: (n2.y + t4.y) / 2 };
}
const e34 = OA(((i2.x - n2.x) * s2.x + (i2.y - n2.y) * s2.y) / c2, 0, 1), t3 = { x: n2.x + e34 * s2.x, y: n2.y + e34 * s2.y };
return { x: (t3.x + i2.x) / 2, y: (t3.y + i2.y) / 2 };
}
const h2 = n2.x - i2.x, d2 = n2.y - i2.y, u2 = s2.x * s2.x + s2.y * s2.y, p2 = s2.x * a2.x + s2.y * a2.y, m2 = s2.x * h2 + s2.y * d2, g2 = a2.x * a2.x + a2.y * a2.y, f2 = a2.x * h2 + a2.y * d2, _2 = u2 * g2 - p2 * p2;
if (_2 < 0.0000000001)
return AA(n2, o2, i2, r2, s2, a2, c2, l2);
let y2 = (p2 * f2 - g2 * m2) / _2, b2 = (u2 * f2 - p2 * m2) / _2;
y2 = OA(y2, 0, 1), b2 = OA(b2, 0, 1), b2 = (y2 * p2 + f2) / g2, b2 = OA(b2, 0, 1), y2 = (b2 * p2 - m2) / u2, y2 = OA(y2, 0, 1);
const x2 = n2.x + y2 * s2.x, v2 = n2.y + y2 * s2.y, I2 = i2.x + b2 * a2.x, S2 = i2.y + b2 * a2.y;
return { x: (x2 + I2) / 2, y: (v2 + S2) / 2 };
};
var AA = (e33, t2, n2, o2, i2, r2, s2, a2) => {
let c2 = ((n2.x - e33.x) * i2.x + (n2.y - e33.y) * i2.y) / s2;
c2 = OA(c2, 0, 1);
const l2 = { x: e33.x + c2 * i2.x, y: e33.y + c2 * i2.y };
let h2 = ((o2.x - e33.x) * i2.x + (o2.y - e33.y) * i2.y) / s2;
h2 = OA(h2, 0, 1);
const d2 = { x: e33.x + h2 * i2.x, y: e33.y + h2 * i2.y };
let u2 = ((e33.x - n2.x) * r2.x + (e33.y - n2.y) * r2.y) / a2;
u2 = OA(u2, 0, 1);
const p2 = { x: n2.x + u2 * r2.x, y: n2.y + u2 * r2.y };
let m2 = ((t2.x - n2.x) * r2.x + (t2.y - n2.y) * r2.y) / a2;
m2 = OA(m2, 0, 1);
const g2 = { x: n2.x + m2 * r2.x, y: n2.y + m2 * r2.y }, f2 = [{ pointA: l2, pointB: n2, distance: Math.sqrt((l2.x - n2.x) ** 2 + (l2.y - n2.y) ** 2) }, { pointA: d2, pointB: o2, distance: Math.sqrt((d2.x - o2.x) ** 2 + (d2.y - o2.y) ** 2) }, { pointA: e33, pointB: p2, distance: Math.sqrt((e33.x - p2.x) ** 2 + (e33.y - p2.y) ** 2) }, { pointA: t2, pointB: g2, distance: Math.sqrt((t2.x - g2.x) ** 2 + (t2.y - g2.y) ** 2) }].reduce((e34, t3) => t3.distance < e34.distance ? t3 : e34);
return { x: (f2.pointA.x + f2.pointB.x) / 2, y: (f2.pointA.y + f2.pointB.y) / 2 };
};
var OA = (e33, t2, n2) => Math.max(t2, Math.min(n2, e33));
var kA = (e33) => e33.type === "pcb_trace_segment" ? { minX: Math.min(e33.x1, e33.x2), minY: Math.min(e33.y1, e33.y2), maxX: Math.max(e33.x1, e33.x2), maxY: Math.max(e33.y1, e33.y2) } : ((e34) => {
let { POSITIVE_INFINITY: t2, POSITIVE_INFINITY: n2, NEGATIVE_INFINITY: o2, NEGATIVE_INFINITY: i2 } = Number;
for (const r2 of e34) {
if (!r2.type.startsWith("pcb_"))
continue;
if (r2.type === "pcb_smtpad" && r2.shape === "polygon" && Array.isArray(r2.points)) {
for (const e36 of r2.points)
t2 = Math.min(t2, e36.x), n2 = Math.min(n2, e36.y), o2 = Math.max(o2, e36.x), i2 = Math.max(i2, e36.y);
continue;
}
if (r2.type === "pcb_hole" && r2.hole_shape === "circle") {
const e36 = bA(r2.x, r2.y, r2.hole_diameter);
t2 = Math.min(t2, e36.minX), n2 = Math.min(n2, e36.minY), o2 = Math.max(o2, e36.maxX), i2 = Math.max(i2, e36.maxY);
continue;
}
if (r2.type === "pcb_plated_hole") {
let e36;
if ("outer_diameter" in r2 && typeof r2.outer_diameter == "number" ? e36 = bA(r2.x, r2.y, r2.outer_diameter) : ("hole_diameter" in r2) && typeof r2.hole_diameter == "number" && (e36 = bA(r2.x, r2.y, r2.hole_diameter)), "rect_pad_width" in r2 && typeof r2.rect_pad_width == "number" && "rect_pad_height" in r2 && typeof r2.rect_pad_height == "number") {
const t3 = xA(r2.x, r2.y, r2.rect_pad_width, r2.rect_pad_height, "rect_ccw_rotation" in r2 ? r2.rect_ccw_rotation ?? 0 : 0);
e36 = e36 ? yA(e36, t3) : t3;
}
if ("hole_diameter" in r2 && typeof r2.hole_diameter == "number") {
const t3 = bA(r2.x + ("hole_offset_x" in r2 ? r2.hole_offset_x ?? 0 : 0), r2.y + ("hole_offset_y" in r2 ? r2.hole_offset_y ?? 0 : 0), r2.hole_diameter);
e36 = e36 ? yA(e36, t3) : t3;
}
if (e36) {
t2 = Math.min(t2, e36.minX), n2 = Math.min(n2, e36.minY), o2 = Math.max(o2, e36.maxX), i2 = Math.max(i2, e36.maxY);
continue;
}
}
let e35, s2, a2, c2;
if ("x" in r2 && "y" in r2 && (e35 = Number(r2.x), s2 = Number(r2.y)), "outer_diameter" in r2 && (a2 = Number(r2.outer_diameter), c2 = Number(r2.outer_diameter)), "width" in r2 && (a2 = Number(r2.width)), "height" in r2 && (c2 = Number(r2.height)), "center" in r2 && (e35 = r2.center.x, s2 = r2.center.y), e35 !== undefined && s2 !== undefined)
t2 = Math.min(t2, e35), n2 = Math.min(n2, s2), o2 = Math.max(o2, e35), i2 = Math.max(i2, s2), a2 !== undefined && c2 !== undefined && (t2 = Math.min(t2, e35 - a2 / 2), n2 = Math.min(n2, s2 - c2 / 2), o2 = Math.max(o2, e35 + a2 / 2), i2 = Math.max(i2, s2 + c2 / 2)), "radius" in r2 && (t2 = Math.min(t2, e35 - r2.radius), n2 = Math.min(n2, s2 - r2.radius), o2 = Math.max(o2, e35 + r2.radius), i2 = Math.max(i2, s2 + r2.radius));
else if (r2.type === "pcb_trace")
for (const e36 of r2.route)
t2 = Math.min(t2, e36.x), n2 = Math.min(n2, e36.y), o2 = Math.max(o2, e36.x), i2 = Math.max(i2, e36.y);
else if (r2.type === "pcb_courtyard_outline")
for (const e36 of r2.outline)
t2 = Math.min(t2, e36.x), n2 = Math.min(n2, e36.y), o2 = Math.max(o2, e36.x), i2 = Math.max(i2, e36.y);
else if (r2.type === "pcb_courtyard_polygon")
for (const e36 of r2.points)
t2 = Math.min(t2, e36.x), n2 = Math.min(n2, e36.y), o2 = Math.max(o2, e36.x), i2 = Math.max(i2, e36.y);
}
return { minX: t2, minY: n2, maxX: o2, maxY: i2 };
})([e33]);
function DA(e33) {
const t2 = new Set;
for (const n2 of e33.route)
n2.route_type === "wire" && (n2.start_pcb_port_id && t2.add(n2.start_pcb_port_id), n2.end_pcb_port_id && t2.add(n2.end_pcb_port_id));
return Array.from(t2);
}
function LA(e33) {
const t2 = new Set;
for (const n2 of e33)
for (const e34 of DA(n2))
t2.add(e34);
return Array.from(t2);
}
var zA = (e33) => {
if (e33.type === "pcb_via")
return e33.outer_diameter / 2;
if (e33.type === "pcb_plated_hole" && e33.shape === "circle")
return e33.outer_diameter / 2;
if (e33.type === "pcb_hole" && e33.hole_shape === "circle")
return e33.hole_diameter / 2;
if (e33.type === "pcb_smtpad" && e33.shape === "circle")
return e33.radius;
throw new Error(`Could not determine radius of element: ${JSON.stringify(e33)}`);
};
function BA(e33, { connMap: t2, minClearance: n2 = 0.1 } = {}) {
const o2 = [];
((e34) => {
const t3 = e34.filter((e35) => e35.type === "pcb_port"), n3 = e34.filter((e35) => e35.type === "pcb_smtpad"), o3 = e34.filter((e35) => e35.type === "pcb_trace");
function i3(e35, o4 = {}) {
const i4 = o4.traceWidth || 0, r3 = t3.find((t4) => IA(t4.x, t4.y, e35.x, e35.y) < 0.01);
if (r3)
return r3.pcb_port_id;
if (o4.isFirstOrLastPoint) {
const t4 = n3.find((t5) => t5.shape === "rect" ? Math.abs(e35.x - t5.x) < t5.width / 2 + i4 / 2 && Math.abs(e35.y - t5.y) < t5.height / 2 + i4 / 2 : t5.shape === "circle" ? IA(e35.x, e35.y, t5.x, t5.y) < t5.radius : undefined);
if (t4)
return t4.pcb_port_id ?? null;
}
return null;
}
for (const e35 of o3)
for (let t4 = 0;t4 < e35.route.length; t4++) {
const n4 = e35.route[t4], o4 = t4 === 0 || t4 === e35.route.length - 1;
if (n4.route_type === "wire") {
if (!n4.start_pcb_port_id && t4 === 0) {
const e36 = i3(n4, { isFirstOrLastPoint: o4, traceWidth: n4.width });
e36 && (n4.start_pcb_port_id = e36);
}
if (!n4.end_pcb_port_id && t4 === e35.route.length - 1) {
const e36 = i3(n4, { isFirstOrLastPoint: o4, traceWidth: n4.width });
e36 && (n4.end_pcb_port_id = e36);
}
}
}
})(e33), t2 ??= lw(e33);
const i2 = dA(e33).pcb_trace.list().flatMap((e34) => {
const t3 = [];
for (let n3 = 0;n3 < e34.route.length - 1; n3++) {
const o3 = e34.route[n3], i3 = e34.route[n3 + 1];
o3.route_type === "wire" && (i3.route_type === "wire" && o3.layer === i3.layer && t3.push({ type: "pcb_trace_segment", pcb_trace_id: e34.pcb_trace_id, _pcbTrace: e34, thickness: "width" in o3 ? o3.width : ("width" in i3) ? i3.width : PA, layer: o3.layer, x1: o3.x, y1: o3.y, x2: i3.x, y2: i3.y }));
}
return t3;
}), r2 = dA(e33).pcb_smtpad.list(), s2 = dA(e33).pcb_plated_hole.list(), a2 = dA(e33).pcb_hole.list(), c2 = dA(e33).pcb_via.list(), l2 = dA(e33).pcb_keepout.list(), h2 = [...i2, ...r2, ...s2, ...a2, ...c2, ...l2], d2 = new SA({ objects: h2, getBounds: kA }), u2 = (t3) => _A(e33, t3), p2 = (e34, t3, n3) => n3 < 0 ? `PCB trace ${e34} overlaps with ${t3} (accidental contact)` : `PCB trace ${e34} is too close to ${t3} (gap: ${n3.toFixed(3)}mm)`, m2 = new Set;
for (const e34 of i2) {
const i3 = n2, r3 = kA(e34), s3 = d2.getObjectsInBounds(r3, i3 + e34.thickness / 2);
if (e34.x1 !== e34.x2 || e34.y1 !== e34.y2)
for (const r4 of s3) {
if (!TA(r4).includes(e34.layer))
continue;
if (r4.type === "pcb_trace_segment") {
const i4 = r4;
if (e34.layer !== i4.layer)
continue;
if (t2.areIdsConnected(e34.pcb_trace_id, i4.pcb_trace_id))
continue;
const s5 = kt({ x: e34.x1, y: e34.y1 }, { x: e34.x2, y: e34.y2 }, { x: i4.x1, y: i4.y1 }, { x: i4.x2, y: i4.y2 }) - e34.thickness / 2 - i4.thickness / 2;
if (s5 > n2 - NA)
continue;
const a4 = `overlap_${e34.pcb_trace_id}_${i4.pcb_trace_id}`, c3 = `overlap_${i4.pcb_trace_id}_${e34.pcb_trace_id}`;
if (m2.has(a4))
continue;
if (m2.has(c3))
continue;
m2.add(a4), o2.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", message: p2(u2(e34.pcb_trace_id), u2(i4.pcb_trace_id), s5), pcb_trace_id: e34.pcb_trace_id, source_trace_id: "", pcb_trace_error_id: a4, pcb_component_ids: [], center: EA(e34, i4), pcb_port_ids: LA([e34._pcbTrace, i4._pcbTrace]) });
continue;
}
const s4 = vA(r4);
if (t2.areIdsConnected(e34.pcb_trace_id, "pcb_trace_id" in r4 ? r4.pcb_trace_id : s4))
continue;
if (r4.type === "pcb_via" || r4.type === "pcb_plated_hole" && r4.shape === "circle" || r4.type === "pcb_hole" || r4.type === "pcb_smtpad" && r4.shape === "circle") {
const t3 = zA(r4), i4 = zt({ x: e34.x1, y: e34.y1 }, { x: e34.x2, y: e34.y2 }, { x: r4.x, y: r4.y, radius: t3 }) - e34.thickness / 2;
if (i4 > n2 - NA)
continue;
const a4 = `overlap_${e34.pcb_trace_id}_${s4}`;
if (m2.has(a4))
continue;
m2.add(a4), o2.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", message: p2(u2(e34.pcb_trace_id), `${r4.type} "${u2(vA(r4))}"`, i4), pcb_trace_id: e34.pcb_trace_id, center: RA(e34, kA(r4)), source_trace_id: "", pcb_trace_error_id: a4, pcb_component_ids: ["pcb_component_id" in r4 ? r4.pcb_component_id : undefined].filter(Boolean), pcb_port_ids: [...LA([e34._pcbTrace]), "pcb_port_id" in r4 ? r4.pcb_port_id : undefined].filter(Boolean) });
}
const a3 = Dt({ x: e34.x1, y: e34.y1 }, { x: e34.x2, y: e34.y2 }, kA(r4)) - e34.thickness / 2;
if (a3 + NA < i3) {
const t3 = `overlap_${e34.pcb_trace_id}_${s4}`;
if (m2.has(t3))
continue;
m2.add(t3), o2.push({ type: "pcb_trace_error", error_type: "pcb_trace_error", message: p2(u2(e34.pcb_trace_id), `${r4.type} "${u2(vA(r4))}"`, a3), pcb_trace_id: e34.pcb_trace_id, source_trace_id: "", pcb_trace_error_id: t3, pcb_component_ids: ["pcb_component_id" in r4 ? r4.pcb_component_id : undefined].filter(Boolean), center: RA(e34, kA(r4)), pcb_port_ids: [...LA([e34._pcbTrace]), "pcb_port_id" in r4 ? r4.pcb_port_id : undefined].filter(Boolean) });
}
}
}
return o2;
}
function FA(e33, t2) {
return Math.hypot(e33.x - t2.x, e33.y - t2.y);
}
function jA(e33, t2) {
return FA(e33, t2) <= NA;
}
function $A(e33, { connMap: t2, minClearance: n2 = MA } = {}) {
const o2 = e33.filter((e34) => e34.type === "pcb_via");
if (o2.length < 2)
return [];
t2 ??= lw(e33);
const i2 = [], r2 = new Set;
for (let s2 = 0;s2 < o2.length; s2++)
for (let a2 = s2 + 1;a2 < o2.length; a2++) {
const c2 = o2[s2], l2 = o2[a2];
if (jA(c2, l2))
continue;
if (!t2.areIdsConnected(c2.pcb_via_id, l2.pcb_via_id))
continue;
const h2 = FA(c2, l2) - c2.outer_diameter / 2 - l2.outer_diameter / 2;
if (h2 + NA >= n2)
continue;
const d2 = [c2.pcb_via_id, l2.pcb_via_id].sort().join("_");
r2.has(d2) || (r2.add(d2), i2.push({ type: "pcb_via_clearance_error", pcb_error_id: `same_net_vias_close_${d2}`, message: `Vias ${_A(e33, c2.pcb_via_id)} and ${_A(e33, l2.pcb_via_id)} are too close together (gap: ${h2.toFixed(3)}mm)`, error_type: "pcb_via_clearance_error", pcb_via_ids: [c2.pcb_via_id, l2.pcb_via_id], minimum_clearance: n2, actual_clearance: h2, pcb_center: { x: (c2.x + l2.x) / 2, y: (c2.y + l2.y) / 2 } }));
}
return i2;
}
function YA(e33, { connMap: t2, minClearance: n2 = wA } = {}) {
const o2 = e33.filter((e34) => e34.type === "pcb_via");
if (o2.length < 2)
return [];
t2 ??= lw(e33);
const i2 = [], r2 = new Set;
for (let s2 = 0;s2 < o2.length; s2++)
for (let a2 = s2 + 1;a2 < o2.length; a2++) {
const c2 = o2[s2], l2 = o2[a2];
if (jA(c2, l2))
continue;
if (t2.areIdsConnected(c2.pcb_via_id, l2.pcb_via_id))
continue;
const h2 = FA(c2, l2) - c2.outer_diameter / 2 - l2.outer_diameter / 2;
if (h2 + NA >= n2)
continue;
const d2 = [c2.pcb_via_id, l2.pcb_via_id].sort().join("_");
r2.has(d2) || (r2.add(d2), i2.push({ type: "pcb_via_clearance_error", pcb_error_id: `different_net_vias_close_${d2}`, message: `Vias ${_A(e33, c2.pcb_via_id)} and ${_A(e33, l2.pcb_via_id)} from different nets are too close together (gap: ${h2.toFixed(3)}mm)`, error_type: "pcb_via_clearance_error", pcb_via_ids: [c2.pcb_via_id, l2.pcb_via_id], minimum_clearance: n2, actual_clearance: h2, pcb_center: { x: (c2.x + l2.x) / 2, y: (c2.y + l2.y) / 2 } }));
}
return i2;
}
var XA = (e33) => ({ minSpacing: e33, minClearance: e33 });
var WA = { traceClearance: 0.1, viaClearance: 0.1 };
var VA = (e33) => ((e34) => ("layer" in e34))(e33) ? [e33.layer] : e33.layers;
function HA(e33, t2, n2) {
let o2, i2 = Number.POSITIVE_INFINITY;
for (const r2 of t2) {
const t3 = n2.get(r2);
if (!t3)
continue;
const s2 = Math.hypot(t3.x - e33.x, t3.y - e33.y);
s2 < i2 && (i2 = s2, o2 = r2);
}
return o2 ?? t2[0];
}
function GA(e33) {
const t2 = [], n2 = new Set, o2 = new Set, i2 = function(e34) {
const t3 = new Map;
for (const n3 of e34.connections)
for (const e35 of n3.pointsToConnect)
e35.pcb_port_id && t3.set(e35.pcb_port_id, { x: e35.x, y: e35.y });
return t3;
}(e33);
for (const r2 of e33.obstacles) {
const e34 = r2.connectedTo, s2 = e34.find((e35) => e35.startsWith("pcb_smtpad_")), a2 = e34.find((e35) => e35.startsWith("pcb_plated_hole_")), c2 = e34.filter((e35) => e35.startsWith("pcb_port_")), l2 = HA(r2.center, c2, i2);
if (!s2 && !a2 && !l2)
continue;
const h2 = r2.layers;
if (h2.length === 0)
continue;
const { width: d2, height: u2 } = r2, p2 = r2.center.x, m2 = r2.center.y, g2 = r2.ccwRotationDegrees, f2 = typeof g2 == "number" && Number.isFinite(g2);
if (h2.length > 1) {
const e35 = a2 ?? `pcb_plated_hole_${p2.toFixed(3)}_${m2.toFixed(3)}`;
if (o2.has(e35))
continue;
if (o2.add(e35), f2) {
const n3 = Math.max(0.5 * Math.min(d2, u2), 0.1);
t2.push({ type: "pcb_plated_hole", pcb_plated_hole_id: e35, shape: "rotated_pill_hole_with_rect_pad", hole_shape: "rotated_pill", pad_shape: "rect", hole_width: n3, hole_height: n3, hole_ccw_rotation: g2, rect_pad_width: d2, rect_pad_height: u2, rect_ccw_rotation: g2, hole_offset_x: 0, hole_offset_y: 0, x: p2, y: m2, layers: h2, ...l2 ? { pcb_port_id: l2 } : {} });
continue;
}
if (Math.abs(d2 - u2) < 0.001) {
t2.push({ type: "pcb_plated_hole", pcb_plated_hole_id: e35, shape: "circle", outer_diameter: Math.max(d2, u2), hole_diameter: Math.max(0.5 * Math.min(d2, u2), 0.1), x: p2, y: m2, layers: h2, ...l2 ? { pcb_port_id: l2 } : {} });
continue;
}
t2.push({ type: "pcb_plated_hole", pcb_plated_hole_id: e35, shape: "circular_hole_with_rect_pad", hole_shape: "circle", hole_diameter: Math.max(0.5 * Math.min(d2, u2), 0.1), rect_pad_width: d2, rect_pad_height: u2, hole_offset_x: 0, hole_offset_y: 0, x: p2, y: m2, layers: h2, ...l2 ? { pcb_port_id: l2 } : {} });
continue;
}
const _2 = s2 ?? `pcb_smtpad_${p2.toFixed(3)}_${m2.toFixed(3)}`;
n2.has(_2) || (n2.add(_2), f2 ? t2.push({ type: "pcb_smtpad", pcb_smtpad_id: _2, layer: h2[0], shape: "rotated_rect", x: p2, y: m2, width: d2, height: u2, ccw_rotation: g2, ...l2 ? { pcb_port_id: l2 } : {} }) : t2.push({ type: "pcb_smtpad", pcb_smtpad_id: _2, layer: h2[0], shape: "rect", width: d2, height: u2, x: p2, y: m2, ...l2 ? { pcb_port_id: l2 } : {} }));
}
return t2;
}
function UA(e33, t2, n2 = 0.1, o2 = e33.minViaDiameter ?? 0.3) {
const i2 = [];
i2.push(...function(e34, t3) {
const n3 = [];
return e34.connections.forEach((o3) => {
const i3 = o3.pointsToConnect.filter((e35) => e35.pcb_port_id).map((e35) => e35.pcb_port_id).filter(Boolean), r3 = o3.netConnectionName || o3.rootConnectionName || o3.name, s2 = [], a2 = t3.find((e35) => (e35.connection_name ?? e35.connectionName) === o3.name);
if (a2) {
const t4 = (e35) => ("route_type" in e35) && e35.route_type === "jumper" ? e35.start : ("x" in e35) && ("y" in e35) ? { x: e35.x, y: e35.y } : { x: 0, y: 0 }, n4 = [t4(a2.route[0]), t4(a2.route[a2.route.length - 1])];
for (const t5 of n4)
for (const n5 of e34.obstacles)
jt(t5, n5) <= 0 && s2.push(n5);
}
const c2 = n3.find((e35) => e35.type === "source_trace" && e35.source_trace_id === r3);
if (c2) {
const e35 = c2;
e35.connected_source_port_ids = [...new Set([...e35.connected_source_port_ids, ...i3])];
} else
n3.push({ type: "source_trace", source_trace_id: r3, connected_source_port_ids: i3.concat(s2.flatMap((e35) => [`obstacle_${e35.center.x.toFixed(3)}_${e35.center.y.toFixed(3)}_${e35.layers.join(".")}`, ...e35.connectedTo])), connected_source_net_ids: [] });
}), n3;
}(e33, t2)), i2.push(...function(e34) {
const t3 = new Map;
return e34.connections.forEach((e35) => {
e35.pointsToConnect.forEach((e36) => {
e36.pcb_port_id && t3.set(e36.pcb_port_id, { type: "pcb_port", pcb_port_id: e36.pcb_port_id, source_port_id: e36.pcb_port_id, x: e36.x, y: e36.y, layers: VA(e36) });
});
}), Array.from(t3.values());
}(e33)), i2.push(...GA(e33)), i2.push(...function(e34, t3, n3 = 0.3, o3 = false) {
const i3 = [], r3 = new Set;
return e34.length > 0 && ("type" in e34[0] && e34[0].type === "pcb_trace" ? e34.forEach((e35) => {
e35.route.forEach((s2) => {
if (s2.route_type === "via") {
const a2 = s2.via_diameter ?? n3, c2 = `${s2.x},${s2.y},${s2.from_layer},${s2.to_layer}`;
r3.has(c2) || (i3.push({ type: "pcb_via", pcb_via_id: `via_${i3.length}`, pcb_trace_id: e35.pcb_trace_id, x: s2.x, y: s2.y, outer_diameter: a2, hole_diameter: 0.5 * a2, layers: OM(s2, t3, o3) }), r3.add(c2));
}
});
}) : e34.forEach((e35, s2) => {
const a2 = `trace_${s2}`, c2 = e35.viaDiameter ?? n3;
for (let n4 = 1;n4 < e35.route.length; n4++) {
const s3 = e35.route[n4 - 1], l2 = e35.route[n4];
if (s3.z !== l2.z && Math.abs(s3.x - l2.x) < 0.01 && Math.abs(s3.y - l2.y) < 0.01) {
const e36 = EM(s3.z, t3), n5 = EM(l2.z, t3), h2 = `${l2.x},${l2.y},${e36},${n5}`;
r3.has(h2) || (i3.push({ type: "pcb_via", pcb_via_id: `via_${i3.length}`, pcb_trace_id: a2, x: l2.x, y: l2.y, outer_diameter: c2, hole_diameter: 0.5 * c2, layers: OM({ from_layer: e36, to_layer: n5 }, t3, o3) }), r3.add(h2));
}
}
})), i3;
}(t2, e33.layerCount, o2, e33.allowBlindAndBuriedVias));
const r2 = new Map;
return e33.connections.forEach((e34) => {
r2.set(e34.name, e34.netConnectionName || e34.rootConnectionName || e34.name);
}), t2.length > 0 && ("type" in t2[0] && t2[0].type === "pcb_trace" ? t2.forEach((e34) => {
const t3 = e34.connection_name;
i2.push(function(e35, t4) {
return { type: "pcb_trace", pcb_trace_id: e35.pcb_trace_id, source_trace_id: t4, route: e35.route.map((e36) => e36.route_type === "wire" ? { route_type: "wire", x: e36.x, y: e36.y, width: e36.width, layer: e36.layer, start_pcb_port_id: e36.start_pcb_port_id, end_pcb_port_id: e36.end_pcb_port_id } : e36.route_type === "via" ? { route_type: "via", x: e36.x, y: e36.y, from_layer: e36.from_layer, to_layer: e36.to_layer } : null).filter((e36) => e36 !== null) };
}(e34, r2.get(t3) || t3));
}) : t2.forEach((t3, o3) => {
const s2 = t3.connectionName, a2 = function(e34, t4, n3, o4 = 0.1, i3) {
const r3 = [];
if (!e34.jumpers || e34.jumpers.length === 0)
return [{ type: "pcb_trace", pcb_trace_id: t4, source_trace_id: n3, route: e34.route.map((t5, n4) => {
const r4 = n4 === 0, s4 = n4 === e34.route.length - 1;
return { route_type: "wire", x: t5.x, y: t5.y, width: o4, layer: EM(t5.z, i3), ...r4 && t5.pcb_port_id ? { start_pcb_port_id: t5.pcb_port_id } : {}, ...s4 && t5.pcb_port_id ? { end_pcb_port_id: t5.pcb_port_id } : {} };
}) }];
const s3 = [];
for (const t5 of e34.jumpers) {
let n4 = -1, o5 = -1;
for (let i4 = 0;i4 < e34.route.length; i4++) {
const r4 = e34.route[i4];
Math.abs(r4.x - t5.start.x) < 0.01 && Math.abs(r4.y - t5.start.y) < 0.01 && (n4 = i4), Math.abs(r4.x - t5.end.x) < 0.01 && Math.abs(r4.y - t5.end.y) < 0.01 && (o5 = i4);
}
n4 !== -1 && o5 !== -1 && (n4 > o5 && ([n4, o5] = [o5, n4]), s3.push({ startIdx: n4, endIdx: o5 }));
}
s3.sort((e35, t5) => e35.startIdx - t5.startIdx);
let a3 = 0, c2 = 0;
for (const { startIdx: l2, endIdx: h2 } of s3) {
if (l2 >= a3) {
const s4 = e34.route.slice(a3, l2 + 1);
s4.length > 0 && (r3.push({ type: "pcb_trace", pcb_trace_id: `${t4}_${c2}`, source_trace_id: n3, route: s4.map((e35, t5) => {
const n4 = t5 === 0 && a3 === 0;
return { route_type: "wire", x: e35.x, y: e35.y, width: o4, layer: EM(e35.z, i3), ...n4 && e35.pcb_port_id ? { start_pcb_port_id: e35.pcb_port_id } : {} };
}) }), c2++);
}
a3 = h2;
}
if (a3 < e34.route.length) {
const s4 = e34.route.slice(a3);
if (s4.length > 0) {
r3.push({ type: "pcb_trace", pcb_trace_id: `${t4}_${c2}`, source_trace_id: n3, route: s4.map((t5, n4) => {
const r4 = n4 === s4.length - 1;
return { route_type: "wire", x: t5.x, y: t5.y, width: o4, layer: EM(t5.z, i3), ...r4 && t5.pcb_port_id ? { end_pcb_port_id: t5.pcb_port_id } : {} };
}) });
}
}
return r3;
}(t3, `trace_${o3}`, r2.get(s2) || s2, n2, e33.layerCount);
i2.push(...a2);
})), i2;
}
var ZA = (e33) => e33.rootConnectionName ?? e33.connectionName;
var qA = (e33, t2) => {
if (e33 && t2)
return e33.getNetConnectedToId(t2);
};
var JA = (e33, t2, n2) => {
if (!t2)
return false;
if (e33 === t2)
return true;
const o2 = n2?.getNetConnectedToId(e33), i2 = n2?.getNetConnectedToId(t2);
return !(!o2 || !(o2 === i2 || e33 && o2 === t2)) || !(!i2 || i2 !== e33);
};
var QA = (e33, t2, n2) => t2.connectedTo?.some((t3) => JA(e33, t3, n2)) ?? false;
var KA = (e33, t2, n2) => Math.max(t2, Math.min(e33, n2));
var eO = (e33, t2) => {
e33.x = KA(e33.x, t2.minX, t2.maxX), e33.y = KA(e33.y, t2.minY, t2.maxY);
};
var tO = (e33, t2) => ({ minX: e33.minX - t2, minY: e33.minY - t2, maxX: e33.maxX + t2, maxY: e33.maxY + t2 });
var nO = (e33, t2) => ({ minCellX: Math.floor(e33.minX / t2), maxCellX: Math.floor(e33.maxX / t2), minCellY: Math.floor(e33.minY / t2), maxCellY: Math.floor(e33.maxY / t2) });
var oO = (e33, t2) => `${e33}:${t2}`;
var iO = new WeakMap;
var rO = (e33, t2, n2) => {
const o2 = new Map, i2 = Math.ceil(e33.length / 32);
iO.set(o2, { bits: new Uint32Array(i2), wordGenerations: new Uint32Array(i2), generation: 0 });
for (let i3 = 0;i3 < e33.length; i3 += 1) {
const r2 = e33[i3];
if (!r2)
continue;
const s2 = nO(t2(r2), n2);
for (let e34 = s2.minCellX;e34 <= s2.maxCellX; e34 += 1)
for (let t3 = s2.minCellY;t3 <= s2.maxCellY; t3 += 1) {
const n3 = oO(e34, t3), r3 = o2.get(n3);
r3 ? r3.push(i3) : o2.set(n3, [i3]);
}
}
return o2;
};
var sO = (e33, t2, n2) => {
let o2 = iO.get(e33);
o2 || (o2 = { bits: new Uint32Array(0), wordGenerations: new Uint32Array(0), generation: 0 }, iO.set(e33, o2)), o2.generation += 1, o2.generation > 4294967295 && (o2.wordGenerations.fill(0), o2.generation = 1);
const i2 = o2.generation, r2 = nO(t2, n2);
let s2 = 1 / 0, a2 = -1;
for (let t3 = r2.minCellX;t3 <= r2.maxCellX; t3 += 1)
for (let n3 = r2.minCellY;n3 <= r2.maxCellY; n3 += 1) {
const r3 = e33.get(oO(t3, n3));
if (r3)
for (const e34 of r3) {
const t4 = e34 >>> 5;
if (t4 >= o2.bits.length) {
const e35 = Math.max(t4 + 1, 2 * o2.bits.length), n4 = new Uint32Array(e35);
n4.set(o2.bits);
const i3 = new Uint32Array(e35);
i3.set(o2.wordGenerations), o2.bits = n4, o2.wordGenerations = i3;
}
o2.wordGenerations[t4] !== i2 && (o2.wordGenerations[t4] = i2, o2.bits[t4] = 0), o2.bits[t4] = o2.bits[t4] | 1 << (31 & e34), t4 < s2 && (s2 = t4), t4 > a2 && (a2 = t4);
}
}
const c2 = [];
for (let e34 = s2;e34 <= a2; e34 += 1) {
if (o2.wordGenerations[e34] !== i2)
continue;
let t3 = o2.bits[e34];
for (;t3 !== 0; ) {
const n3 = 31 - Math.clz32(t3 & -t3);
c2.push(32 * e34 + n3), t3 &= t3 - 1;
}
}
return c2;
};
var aO = 0.000001;
var cO = (e33, t2, n2) => {
if (e33.length === 0)
return [];
const o2 = n2?.traceThickness ?? 0.1, i2 = e33[0], r2 = e33.at(-1), s2 = (e34) => {
if (e34.pcb_port_id)
return e34.pcb_port_id;
const o3 = EM(e34.z, t2);
return n2?.connectionPoints?.find((t3) => {
return t3.pcb_port_id && (n3 = t3, i3 = e34, Math.abs(n3.x - i3.x) <= aO && Math.abs(n3.y - i3.y) <= aO) && VA(t3).includes(o3);
var n3, i3;
})?.pcb_port_id;
}, a2 = s2(i2), c2 = s2(r2), l2 = [{ route_type: "wire", x: i2.x, y: i2.y, width: o2, layer: EM(i2.z, t2), ...a2 ? { start_pcb_port_id: a2 } : {}, ...e33.length === 1 && c2 ? { end_pcb_port_id: c2 } : {} }];
for (let i3 = 1;i3 < e33.length; i3 += 1) {
const r3 = e33[i3 - 1], s3 = e33[i3];
r3 && s3 && (r3.z !== s3.z && r3.x === s3.x && r3.y === s3.y && l2.push({ route_type: "via", x: s3.x, y: s3.y, from_layer: EM(r3.z, t2), to_layer: EM(s3.z, t2), ...n2?.viaDiameter ? { via_diameter: n2.viaDiameter } : {} }), l2.push({ route_type: "wire", x: s3.x, y: s3.y, width: o2, layer: EM(s3.z, t2), ...i3 === e33.length - 1 && c2 ? { end_pcb_port_id: c2 } : {} }));
}
return l2;
};
var lO = (e33, t2) => ({ x: Ot(e33.x, t2.minX, t2.maxX), y: Ot(e33.y, t2.minY, t2.maxY) });
var hO = (e33, t2) => {
const n2 = e33.x - t2.center.x, o2 = e33.y - t2.center.y;
return t2.circular ? Math.max(0, Math.hypot(n2, o2) - t2.halfWidth) : $t(R(t2.worldToLocal, e33), { minX: -t2.halfWidth, maxX: t2.halfWidth, minY: -t2.halfHeight, maxY: t2.halfHeight });
};
var dO = (e33, t2) => ({ kind: "line", start: e33, end: t2, bounds: Ht([e33, t2]) });
var uO = (e33, t2) => ({ kind: "circle", center: e33, radius: t2, bounds: Vt({ center: e33, width: 2 * t2, height: 2 * t2 }) });
var pO = (e33) => {
const t2 = e33.clearance + KM;
if (e33.circular)
return [uO(e33.center, e33.halfWidth + t2)];
const n2 = (t3, n3) => R(e33.localToWorld, { x: t3, y: n3 }), { halfWidth: o2, halfHeight: i2 } = e33;
return [dO(n2(-o2, -i2 - t2), n2(o2, -i2 - t2)), dO(n2(o2 + t2, -i2), n2(o2 + t2, i2)), dO(n2(o2, i2 + t2), n2(-o2, i2 + t2)), dO(n2(-o2 - t2, i2), n2(-o2 - t2, -i2)), uO(n2(-o2, -i2), t2), uO(n2(o2, -i2), t2), uO(n2(o2, i2), t2), uO(n2(-o2, i2), t2)];
};
var mO = (e33, t2) => {
if (t2.kind === "circle") {
const n2 = e33.x - t2.center.x, o2 = e33.y - t2.center.y, i2 = Math.hypot(n2, o2);
return i2 === 0 ? [{ x: t2.center.x + t2.radius, y: t2.center.y }, { x: t2.center.x - t2.radius, y: t2.center.y }, { x: t2.center.x, y: t2.center.y + t2.radius }, { x: t2.center.x, y: t2.center.y - t2.radius }] : [{ x: t2.center.x + n2 * t2.radius / i2, y: t2.center.y + o2 * t2.radius / i2 }];
}
return [t2.start, t2.end, Bt(e33, t2.start, t2.end)];
};
var gO = (e33, t2) => {
const n2 = e33.end.x - e33.start.x, o2 = e33.end.y - e33.start.y, i2 = e33.start.x - t2.center.x, r2 = e33.start.y - t2.center.y, s2 = n2 * n2 + o2 * o2;
if (s2 === 0)
return [];
const a2 = 2 * (i2 * n2 + r2 * o2), c2 = a2 * a2 - 4 * s2 * (i2 * i2 + r2 * r2 - t2.radius * t2.radius);
if (c2 < 0)
return [];
const l2 = Math.sqrt(c2);
return [(-a2 - l2) / (2 * s2), (-a2 + l2) / (2 * s2)].filter((e34) => e34 >= 0 && e34 <= 1).map((t3) => ({ x: e33.start.x + n2 * t3, y: e33.start.y + o2 * t3 }));
};
var fO = (e33, t2) => {
if (e33.kind === "line" && t2.kind === "circle")
return gO(e33, t2);
if (e33.kind === "circle" && t2.kind === "line")
return gO(t2, e33);
if (e33.kind === "line" && t2.kind === "line") {
const n3 = It(e33.start, e33.end, t2.start, t2.end);
return n3 ? [n3] : [];
}
if (e33.kind !== "circle" || t2.kind !== "circle")
return [];
const n2 = t2.center.x - e33.center.x, o2 = t2.center.y - e33.center.y, i2 = Math.hypot(n2, o2);
if (i2 === 0 || i2 > e33.radius + t2.radius || i2 < Math.abs(e33.radius - t2.radius))
return [];
const r2 = (e33.radius ** 2 - t2.radius ** 2 + i2 ** 2) / (2 * i2), s2 = Math.sqrt(Math.max(0, e33.radius ** 2 - r2 ** 2)), a2 = e33.center.x + n2 * r2 / i2, c2 = e33.center.y + o2 * r2 / i2;
return [{ x: a2 - o2 * s2 / i2, y: c2 + n2 * s2 / i2 }, { x: a2 + o2 * s2 / i2, y: c2 - n2 * s2 / i2 }];
};
var _O = (e33, t2, n2, o2, i2) => {
const r2 = new Set(function(e34, t3, n3 = 1) {
if (n3 === 0)
throw new Error("step cannot be 0");
let o3, i3;
t3 === undefined ? (o3 = 0, i3 = e34) : (o3 = e34, i3 = t3);
const r3 = [];
if (n3 > 0)
for (let e35 = o3;e35 < i3; e35 += n3)
r3.push(e35);
else
for (let e35 = o3;e35 > i3; e35 += n3)
r3.push(e35);
return r3;
}(e33.allowBlindAndBuriedVias ? Math.min(...o2) : 0, e33.allowBlindAndBuriedVias ? Math.max(...o2) + 1 : e33.layerCount).map((t3) => EM(t3, e33.layerCount)));
return e33.obstacles.filter((e34) => !e34.isCopperPour && e34.layers.some((e35) => r2.has(e35))).map((o3) => {
const r3 = typeof o3.ccwRotationDegrees == "number" && Number.isFinite(o3.ccwRotationDegrees), s2 = !r3 && o3.layers.length > 1 && Math.abs(o3.width - o3.height) < 0.001, a2 = L(k(o3.center.x, o3.center.y), $(r3 ? o3.ccwRotationDegrees : 0)), c2 = s2 ? Math.max(o3.width, o3.height) / 2 : o3.width / 2, l2 = s2 ? c2 : o3.height / 2, h2 = QA(ZA(t2), o3, i2) || QA(t2.connectionName, o3, i2), d2 = n2 + (h2 ? 0 : rw(e33)), u2 = Ht(E(a2, [{ x: -c2, y: -l2 }, { x: c2, y: -l2 }, { x: c2, y: l2 }, { x: -c2, y: l2 }])), p2 = d2 + KM;
return { center: o3.center, halfWidth: c2, halfHeight: l2, localToWorld: a2, worldToLocal: A(a2), circular: s2, clearance: d2, bounds: { minX: u2.minX - p2, maxX: u2.maxX + p2, minY: u2.minY - p2, maxY: u2.maxY + p2 } };
});
};
var yO = (e33, t2, n2, o2) => {
const i2 = Math.min(...e33.zLayers), r2 = Math.max(...e33.zLayers), s2 = t2.filter((t3) => t3.z >= i2 && t3.z <= r2 && !JA(e33.rootConnectionName, t3.rootConnectionName, o2)).map((t3) => ({ segment: t3, required: e33.radius + t3.radius + n2 })).filter(({ segment: t3, required: n3 }) => xt(e33, t3.start, t3.end) <= n3 + tw), a2 = s2.flatMap(({ segment: e34, required: t3 }) => {
const { start: n3, end: o3 } = e34, i3 = Math.sqrt(Xt(n3, o3));
if (i3 <= KM)
return [];
const r3 = t3 + KM, s3 = (o3.y - n3.y) / i3 * r3, a3 = (n3.x - o3.x) / i3 * r3;
return [dO({ x: n3.x + s3, y: n3.y + a3 }, { x: o3.x + s3, y: o3.y + a3 }), dO({ x: n3.x - s3, y: n3.y - a3 }, { x: o3.x - s3, y: o3.y - a3 }), uO(n3, r3), uO(o3, r3)];
}).filter((t3) => $t(e33, t3.bounds) <= tw), c2 = [], l2 = (t3) => {
Xt(t3, e33) > tw ** 2 || c2.some((e34) => Xt(e34, t3) < 0.000000000001) || s2.some(({ segment: e34, required: n3 }) => xt(t3, e34.start, e34.end) < n3) || c2.push(t3);
};
l2(e33);
for (let t3 = 0;t3 < a2.length; t3 += 1) {
const n3 = a2[t3];
for (const t4 of mO(e33, n3))
l2(t4);
for (let e34 = t3 + 1;e34 < a2.length; e34 += 1) {
const t4 = a2[e34];
if (Wt(n3.bounds, t4.bounds))
for (const e35 of fO(n3, t4))
l2(e35);
}
}
return c2.sort((t3, n3) => Xt(t3, e33) - Xt(n3, e33));
};
var bO = (e33) => ({ ...e33, route: e33.route.map((e34) => ({ ...e34 })), vias: e33.vias.map((e34) => ({ ...e34 })) });
var xO = (e33) => e33.map(bO);
var vO = (e33, t2) => {
const n2 = new Set(t2);
return e33.map((e34, t3) => n2.has(t3) ? bO(e34) : e34);
};
var IO = (e33, t2) => Math.abs(e33.x - t2.x) <= ew && Math.abs(e33.y - t2.y) <= ew;
var SO = ["pcb_smtpad", "pcb_plated_hole", "pcb_hole", "pcb_keepout"];
var CO = (e33) => typeof e33.type == "string" ? e33.type : typeof e33.error_type == "string" ? e33.error_type : undefined;
var PO = (e33) => {
if (CO(e33) === "pcb_pad_trace_clearance_error")
return true;
const t2 = typeof e33.message == "string" ? e33.message.toLowerCase() : "";
return (t2.includes("pcb_trace") || t2.includes("pcb trace")) && SO.some((e34) => t2.includes(e34));
};
var MO = (e33) => {
const t2 = typeof e33.message == "string" ? e33.message : "", n2 = t2.match(/gap: (-?\d+(?:\.\d+)?)mm/), o2 = t2.match(/required: (-?\d+(?:\.\d+)?)mm/);
if (n2 && o2) {
const e34 = Number.parseFloat(n2[1]), t3 = Number.parseFloat(o2[1]);
if (Number.isFinite(e34) && Number.isFinite(t3))
return Math.max(0, t3 - e34);
}
if (n2) {
const e34 = Number.parseFloat(n2[1]), t3 = WA.traceClearance;
if (Number.isFinite(e34))
return Math.max(0, t3 - e34);
}
return 1;
};
var wO = { projectEngineError: (e33) => ({ ...e33, center: typeof e33.first_contact_center == "object" ? e33.first_contact_center : e33.center, message: typeof e33.first_contact_message == "string" ? e33.first_contact_message : e33.message, actual_clearance: typeof e33.first_actual_clearance == "number" ? e33.first_actual_clearance : e33.actual_clearance }), getErrorSeverity: MO };
var NO = { projectEngineError: (e33) => e33, getErrorSeverity: (e33) => {
const t2 = Number(e33.minimum_clearance), n2 = Number(e33.worst_actual_clearance);
return Number.isFinite(t2) && Number.isFinite(n2) ? Math.max(0, t2 - n2) : MO(e33);
} };
var TO = (e33, t2 = MO) => e33.reduce((e34, n2) => e34 + t2(n2), 0);
var RO = (e33, t2, n2, o2, i2, r2 = wO) => {
const s2 = i2 && !n2 ? e33 : ((e34, t3) => t3 ? { ...e34, connections: e34.connections.map((e35) => {
const n3 = qA(t3, e35.name) ?? qA(t3, e35.rootConnectionName) ?? e35.netConnectionName;
return n3 ? { ...e35, netConnectionName: n3 } : e35;
}), obstacles: e34.obstacles.map((e35) => {
const n3 = new Set(e35.connectedTo);
for (const o3 of e35.connectedTo) {
const e36 = qA(t3, o3);
e36 && n3.add(e36);
}
return { ...e35, connectedTo: [...n3] };
}) } : e34)(e33, o2), { traces: a2, traceRouteIndexById: c2 } = ((e34, t3) => {
const n3 = [], o3 = new Map, i3 = new Map;
for (let e35 = 0;e35 < t3.length; e35 += 1) {
const n4 = t3[e35];
if (!n4)
continue;
const o4 = i3.get(n4.connectionName);
o4 ? o4.push({ route: n4, routeIndex: e35 }) : i3.set(n4.connectionName, [{ route: n4, routeIndex: e35 }]);
}
for (const t4 of e34.connections) {
const r3 = i3.get(t4.name) ?? [];
for (let i4 = 0;i4 < r3.length; i4 += 1) {
const s3 = r3[i4];
if (!s3)
continue;
const a3 = `${t4.name}_${i4}`;
n3.push({ type: "pcb_trace", pcb_trace_id: a3, connection_name: t4.netConnectionName ?? t4.rootConnectionName ?? t4.name, route: cO(s3.route.route, e34.layerCount, { traceThickness: s3.route.traceThickness ?? t4.nominalTraceWidth ?? e34.nominalTraceWidth ?? e34.minTraceWidth, viaDiameter: s3.route.viaDiameter ?? e34.minViaDiameter, connectionPoints: t4.pointsToConnect }) }), o3.set(a3, s3.routeIndex);
}
}
return { traces: n3, traceRouteIndexById: o3 };
})(s2, t2), l2 = n2?.({ srj: s2, routes: t2, traces: a2 });
if (l2) {
const e34 = Array.isArray(l2) ? l2 : l2.errors, t3 = Array.isArray(l2) ? l2 : l2.errorsWithCenters ?? l2.errors;
return { errors: t3, count: e34.length, issueScore: TO(t3, r2.getErrorSeverity), legacyIssueScore: TO(t3.filter((e35) => !Qk(e35)), r2.getErrorSeverity), traceRouteIndexById: c2 };
}
const h2 = i2?.evaluate(a2) ?? ((e34, t3 = {}) => {
const n3 = Math.max(t3.viaClearance ?? 0.1, 0.1), o3 = [...BA(e34, XA(t3.traceClearance)), ...$A(e34, XA(n3)), ...YA(e34, XA(n3))], i3 = e34.filter((e35) => e35.type === "pcb_via"), r3 = new Map(i3.map((e35) => [e35.pcb_via_id, e35])), s3 = o3.map((e35) => {
if ("center" in e35 && e35.center)
return e35;
if ("pcb_center" in e35 && e35.pcb_center)
return { ...e35, center: e35.pcb_center };
if ("pcb_via_ids" in e35 && Array.isArray(e35.pcb_via_ids)) {
const [t4, n4] = e35.pcb_via_ids;
if (typeof t4 != "string" || typeof n4 != "string")
return e35;
const o4 = r3.get(t4), i4 = r3.get(n4);
if (o4 && i4)
return { ...e35, center: { x: (o4.x + i4.x) / 2, y: (o4.y + i4.y) / 2 } };
}
if ("pcb_error_id" in e35 && typeof e35.pcb_error_id == "string" && (e35.pcb_error_id.startsWith("same_net_vias_close_") || e35.pcb_error_id.startsWith("different_net_vias_close_"))) {
const t4 = e35.pcb_error_id.replace("same_net_vias_close_", "").replace("different_net_vias_close_", "").split("_").filter(Boolean);
if (t4.length === 2) {
const n4 = t4[0], o4 = t4[1];
if (!n4 || !o4)
return e35;
const i4 = r3.get(n4), s4 = r3.get(o4);
if (i4 && s4)
return { ...e35, center: { x: (i4.x + s4.x) / 2, y: (i4.y + s4.y) / 2 } };
}
}
return e35;
}), a3 = s3.filter((e35) => Boolean(e35.center));
return { errors: o3, errorsWithCenters: s3, locationAwareErrors: a3 };
})(UA(s2, a2, s2.minTraceWidth, s2.minViaDiameter), { traceClearance: s2.minTraceToPadEdgeClearance ?? WA.traceClearance, viaClearance: s2.minTraceToPadEdgeClearance ?? WA.viaClearance }), d2 = h2.errors, u2 = (h2.errorsWithCenters.length > 0 ? h2.errorsWithCenters : h2.errors).map((e34) => r2.projectEngineError(e34));
return { errors: u2, count: d2.length, issueScore: TO(u2, r2.getErrorSeverity), legacyIssueScore: TO(u2.filter((e34) => !Qk(e34)), r2.getErrorSeverity), traceRouteIndexById: c2 };
};
var EO = (e33, t2, n2, o2, i2) => RO(e33, t2, n2, o2, i2, wO);
var AO = (e33, t2, n2, o2, i2) => RO(e33, t2, n2, o2, i2, NO);
var OO = (e33, t2) => {
const n2 = [];
for (let o2 = 0;o2 < e33.length; o2 += 1) {
const i2 = e33[o2];
if (!i2)
continue;
let r2;
for (let e34 = 0;e34 < i2.route.length - 1; e34 += 1) {
const s2 = i2.route[e34], a2 = i2.route[e34 + 1];
if (!s2 || !a2)
continue;
if (s2.z === a2.z || !IO(s2, a2))
continue;
const c2 = r2 ??= new Set, l2 = [e34, e34 + 1];
for (let t3 = e34 - 1;t3 >= 0; t3 -= 1) {
const e35 = i2.route[t3];
if (!e35 || !IO(e35, s2))
break;
l2.push(t3);
}
for (let t3 = e34 + 2;t3 < i2.route.length; t3 += 1) {
const e35 = i2.route[t3];
if (!e35 || !IO(e35, s2))
break;
l2.push(t3);
}
const h2 = l2;
if (h2.some((e35) => c2.has(e35)))
continue;
for (const e35 of h2)
c2.add(e35);
const d2 = h2.filter((e35) => e35 === 0 || e35 === i2.route.length - 1), u2 = d2.some((e35) => Boolean(i2.route[e35]?.pcb_port_id));
let p2 = 0, m2 = t2.layerCount - 1;
if (t2.allowBlindAndBuriedVias) {
const e35 = h2.map((e36) => i2.route[e36].z);
p2 = Math.min(...e35), m2 = Math.max(...e35);
}
n2.push({ routeIndex: o2, rootConnectionName: ZA(i2), pointIndexes: h2, zLayers: Array.from({ length: m2 - p2 + 1 }, (e35, t3) => p2 + t3), x: s2.x, y: s2.y, radius: (i2.viaDiameter ?? t2.minViaDiameter ?? 0.3) / 2, movable: d2.length === 0, canCanonicalize: d2.length === 0 || !u2 });
}
}
return n2;
};
var kO = (e33, t2) => {
const n2 = [];
for (let o2 = 0;o2 < e33.route.length - 1; o2 += 1) {
const i2 = e33.route[o2], r2 = e33.route[o2 + 1];
i2 && r2 && (i2.z !== r2.z || IO(i2, r2) || n2.push({ routeIndex: t2, rootConnectionName: ZA(e33), startIndex: o2, endIndex: o2 + 1, start: i2, end: r2, z: i2.z, radius: (e33.traceThickness ?? 0.1) / 2 }));
}
return n2;
};
var DO = (e33) => e33.flatMap((e34, t2) => kO(e34, t2));
var LO = (e33) => ({ minX: e33.x, minY: e33.y, maxX: e33.x, maxY: e33.y });
var zO = (e33) => ({ minX: Math.min(e33.start.x, e33.end.x), minY: Math.min(e33.start.y, e33.end.y), maxX: Math.max(e33.start.x, e33.end.x), maxY: Math.max(e33.start.y, e33.end.y) });
var BO = (e33) => ({ minX: e33.center.x - e33.width / 2, minY: e33.center.y - e33.height / 2, maxX: e33.center.x + e33.width / 2, maxY: e33.center.y + e33.height / 2 });
var FO = (e33, t2) => {
if (e33.zLayers && e33.zLayers.length > 0)
return e33.zLayers;
const n2 = Array.from({ length: t2 }, (e34, t3) => t3).filter((n3) => e33.layers.includes(EM(n3, t2)));
return n2.length > 0 ? n2 : Array.from({ length: t2 }, (e34, t3) => t3);
};
var jO = (e33, t2, n2) => {
const o2 = t2.reduce((e34, t3) => Math.max(e34, t3.radius), (e33.minViaDiameter ?? 0.3) / 2), i2 = n2.reduce((e34, t3) => Math.max(e34, t3.radius), e33.minTraceWidth / 2), r2 = (WA.traceClearance) + ow;
return Math.max(2 * o2 + 0.2 + ow, o2 + i2 + r2, 2 * i2 + r2, i2 + iw(e33) + ow, o2 + rw(e33) + ow);
};
var $O = (e33, t2, n2) => {
const o2 = n2.x - t2.x, i2 = n2.y - t2.y, r2 = o2 * o2 + i2 * i2;
if (r2 <= KM)
return { x: t2.x, y: t2.y, t: 0 };
const s2 = KA(((e33.x - t2.x) * o2 + (e33.y - t2.y) * i2) / r2, 0, 1);
return { x: t2.x + o2 * s2, y: t2.y + i2 * s2, t: s2 };
};
var YO = (e33, t2) => $O(e33, t2.start, t2.end);
var XO = (e33, t2) => {
const n2 = t2.width / 2, o2 = t2.height / 2, i2 = Math.max(Math.abs(e33.x - t2.center.x) - n2, 0), r2 = Math.max(Math.abs(e33.y - t2.center.y) - o2, 0);
return Math.hypot(i2, r2);
};
var WO = (e33, t2) => e33.x >= t2.center.x - t2.width / 2 - ew && e33.x <= t2.center.x + t2.width / 2 + ew && e33.y >= t2.center.y - t2.height / 2 - ew && e33.y <= t2.center.y + t2.height / 2 + ew;
var VO = (e33, t2, n2, o2) => e33.obstacles.find((i2) => QA(ZA(t2), i2, o2) && FO(i2, e33.layerCount).includes(n2.z) && WO(n2, i2));
var HO = (e33, t2, n2 = 0.6, o2) => {
let i2;
for (const r2 of e33.obstacles) {
const e34 = XO(t2, r2);
e34 > n2 || (o2 && !o2(r2) || (!i2 || e34 < i2.distance) && (i2 = { obstacle: r2, distance: e34 }));
}
return i2?.obstacle;
};
var GO = (e33, t2, n2) => {
const o2 = t2.width / 2, i2 = t2.height / 2, r2 = KA(e33.x, t2.center.x - o2, t2.center.x + o2), s2 = KA(e33.y, t2.center.y - i2, t2.center.y + i2);
let a2 = e33.x - r2, c2 = e33.y - s2, l2 = Math.hypot(a2, c2);
if (l2 <= KM) {
o2 - Math.abs(e33.x - t2.center.x) < i2 - Math.abs(e33.y - t2.center.y) ? (a2 = e33.x >= t2.center.x ? 1 : -1, c2 = 0, l2 = 0) : (a2 = 0, c2 = e33.y >= t2.center.y ? 1 : -1, l2 = 0);
}
const h2 = n2 - l2;
if (h2 <= 0)
return;
const d2 = Math.hypot(a2, c2);
return { direction: { x: d2 > KM ? a2 / d2 : 1, y: d2 > KM ? c2 / d2 : 0 }, penetration: h2 };
};
var UO = (e33, t2, n2, o2) => {
const i2 = t2.message;
if (typeof i2 != "string" || !i2.includes("pcb_"))
return n2;
const r2 = Array.isArray(t2.pcb_pad_ids) ? t2.pcb_pad_ids.filter((e34) => typeof e34 == "string") : [], s2 = e33.obstacles.find((e34) => r2.some((t3) => e34.connectedTo.includes(t3)) && (true));
return s2 ? s2.center : HO(e33, n2, 0.6, o2)?.center ?? n2;
};
var ZO = (e33, t2) => {
const n2 = e33.route[t2];
if (!n2)
return [];
const o2 = [t2];
for (let i2 = t2 - 1;i2 >= 0; i2 -= 1) {
const t3 = e33.route[i2];
if (!t3 || !IO(t3, n2))
break;
o2.push(i2);
}
for (let i2 = t2 + 1;i2 < e33.route.length; i2 += 1) {
const t3 = e33.route[i2];
if (!t3 || !IO(t3, n2))
break;
o2.push(i2);
}
return [...new Set(o2)];
};
var qO = (e33, t2) => {
if (t2 <= 0 || t2 >= e33.route.length - 1)
return;
const n2 = ZO(e33, t2);
return n2.includes(0) || n2.includes(e33.route.length - 1) ? undefined : n2;
};
var JO = (e33, t2) => e33.x >= t2.minX - ew && e33.x <= t2.maxX + ew && e33.y >= t2.minY - ew && e33.y <= t2.maxY + ew;
var QO = (e33, t2) => Math.min(e33.x - t2.minX, t2.maxX - e33.x, e33.y - t2.minY, t2.maxY - e33.y);
var KO = (e33, t2, n2) => {
const o2 = n2.x - t2.x, i2 = n2.y - t2.y, r2 = e33.x - t2.x, s2 = o2 * (e33.y - t2.y) - i2 * r2;
if (Math.abs(s2) > ew)
return false;
const a2 = Math.min(t2.x, n2.x) - ew, c2 = Math.max(t2.x, n2.x) + ew, l2 = Math.min(t2.y, n2.y) - ew, h2 = Math.max(t2.y, n2.y) + ew;
return e33.x >= a2 && e33.x <= c2 && e33.y >= l2 && e33.y <= h2;
};
var ek = (e33, t2) => {
if (t2.length < 3)
return true;
for (let n3 = 0;n3 < t2.length; n3 += 1) {
const o2 = t2[n3], i2 = t2[(n3 + 1) % t2.length];
if (o2 && i2 && KO(e33, o2, i2))
return true;
}
let n2 = false;
for (let o2 = 0, i2 = t2.length - 1;o2 < t2.length; i2 = o2, o2 += 1) {
const r2 = t2[o2], s2 = t2[i2];
if (!r2 || !s2)
continue;
r2.y > e33.y != s2.y > e33.y && e33.x < (s2.x - r2.x) * (e33.y - r2.y) / (s2.y - r2.y) + r2.x && (n2 = !n2);
}
return n2;
};
var tk = (e33, t2) => {
const n2 = Math.hypot(e33, t2);
if (!(n2 <= KM))
return { x: e33 / n2, y: t2 / n2 };
};
var nk = (e33, t2) => e33.outline && e33.outline.length >= 3 ? ((e34, t3) => {
const n2 = ek(e34, t3);
let o2;
for (let n3 = 0;n3 < t3.length; n3 += 1) {
const i3 = t3[n3], r3 = t3[(n3 + 1) % t3.length];
if (!i3 || !r3)
continue;
const s3 = $O(e34, i3, r3), a3 = Math.hypot(e34.x - s3.x, e34.y - s3.y);
(!o2 || a3 < o2.distance) && (o2 = { projection: s3, start: i3, end: r3, distance: a3 });
}
if (!o2)
return;
const i2 = tk(n2 ? e34.x - o2.projection.x : o2.projection.x - e34.x, n2 ? e34.y - o2.projection.y : o2.projection.y - e34.y);
if (i2)
return i2;
const r2 = o2.end.x - o2.start.x, s2 = o2.end.y - o2.start.y, a2 = Math.hypot(r2, s2);
if (a2 <= KM)
return;
const c2 = ((e35) => {
let t4 = 0;
for (let n3 = 0;n3 < e35.length; n3 += 1) {
const o3 = e35[n3], i3 = e35[(n3 + 1) % e35.length];
o3 && i3 && (t4 += o3.x * i3.y - i3.x * o3.y);
}
return t4 / 2;
})(t3) >= 0;
return { x: c2 ? -s2 / a2 : s2 / a2, y: c2 ? r2 / a2 : -r2 / a2 };
})(t2, e33.outline) : ((e34, t3) => {
const n2 = e34.x - t3.minX, o2 = t3.maxX - e34.x, i2 = e34.y - t3.minY, r2 = t3.maxY - e34.y, s2 = Math.min(n2, o2, i2, r2);
let a2 = 0, c2 = 0;
return n2 <= s2 + ew && (a2 += 1), o2 <= s2 + ew && (a2 -= 1), i2 <= s2 + ew && (c2 += 1), r2 <= s2 + ew && (c2 -= 1), tk(a2, c2);
})(t2, e33.bounds);
var ok = (e33, t2) => e33.outline && e33.outline.length >= 3 ? ek(t2, e33.outline) : JO(t2, e33.bounds);
var ik = (e33, t2) => {
if (e33.outline && e33.outline.length >= 3) {
const n2 = ((e34, t3) => {
let n3 = Number.POSITIVE_INFINITY;
for (let o2 = 0;o2 < t3.length; o2 += 1) {
const i2 = t3[o2], r2 = t3[(o2 + 1) % t3.length];
i2 && r2 && (n3 = Math.min(n3, xt(e34, i2, r2)));
}
return n3;
})(t2, e33.outline);
return ek(t2, e33.outline) ? n2 : -n2;
}
return QO(t2, e33.bounds);
};
var rk = (e33, t2, n2) => {
if (Math.abs(t2.x - n2.x) <= ew && Math.abs(t2.y - n2.y) <= ew)
return Math.min(ik(e33, t2), ik(e33, n2));
if (e33.outline && e33.outline.length >= 3) {
if (!ek(t2, e33.outline) || !ek(n2, e33.outline))
return Math.min(ik(e33, t2), ik(e33, n2));
let o2 = Number.POSITIVE_INFINITY;
for (let i2 = 0;i2 < e33.outline.length; i2 += 1) {
const r2 = e33.outline[i2], s2 = e33.outline[(i2 + 1) % e33.outline.length];
r2 && s2 && (o2 = Math.min(o2, kt(t2, n2, r2, s2)));
}
return o2;
}
return JO(t2, e33.bounds) && JO(n2, e33.bounds) ? Math.min(QO(t2, e33.bounds), QO(n2, e33.bounds)) : Math.min(ik(e33, t2), ik(e33, n2));
};
var sk = (e33, t2) => t2 + Math.max(0.16, e33.defaultObstacleMargin ?? 0, WA.traceClearance);
var ak = (e33, t2, n2) => t2 < e33 - ew && Math.min(e33, t2) <= n2 + ew;
var ck = (e33, t2, n2, o2, i2) => {
const r2 = e33 * n2.x + t2 * n2.y, s2 = -Math.max(0, o2 - i2);
if (r2 >= s2 - ew)
return { x: e33, y: t2 };
const a2 = s2 - r2;
return { x: e33 + n2.x * a2, y: t2 + n2.y * a2 };
};
var lk = (e33, t2, n2, o2, i2) => {
const r2 = nk(e33, t2);
return r2 ? ck(n2, o2, r2, ik(e33, t2), sk(e33, i2)) : { x: n2, y: o2 };
};
var hk = (e33, t2, n2, o2) => {
const i2 = [...new Set(n2)].sort((e34, t3) => e34 - t3);
if (i2.length === 0)
return Number.POSITIVE_INFINITY;
const r2 = new Set(i2), s2 = (e34) => o2?.get(e34) ?? t2.route[e34];
let a2 = Number.POSITIVE_INFINITY;
for (const t3 of i2) {
const n3 = s2(t3);
n3 && (a2 = Math.min(a2, ik(e33, n3)));
}
for (let n3 = 0;n3 < t2.route.length - 1; n3 += 1) {
if (!r2.has(n3) && !r2.has(n3 + 1))
continue;
const t3 = s2(n3), o3 = s2(n3 + 1);
t3 && o3 && (a2 = Math.min(a2, rk(e33, t3, o3)));
}
return a2;
};
var dk = (e33, t2, n2, o2, i2, r2) => {
const s2 = [...new Set(n2)].sort((e34, t3) => e34 - t3);
if (s2.length === 0)
return;
const a2 = ((e34, t3, n3, o3, i3, r3) => {
const s3 = [...new Set(n3)].sort((e35, t4) => e35 - t4);
let a3 = { x: o3, y: i3 };
const c3 = sk(e34, r3);
for (let n4 = 0;n4 < Math.max(1, s3.length); n4 += 1) {
let n5 = false;
for (const o4 of s3) {
const i4 = t3.route[o4];
if (!i4)
continue;
const r4 = nk(e34, i4);
if (!r4)
continue;
const s4 = ck(a3.x, a3.y, r4, ik(e34, i4), c3);
(Math.abs(s4.x - a3.x) > KM || Math.abs(s4.y - a3.y) > KM) && (a3 = s4, n5 = true);
}
if (!n5)
break;
}
return a3;
})(e33, t2, s2, o2, i2, r2);
if (Math.abs(a2.x) <= KM && Math.abs(a2.y) <= KM)
return;
const c2 = new Map;
for (const e34 of s2) {
const n3 = t2.route[e34];
if (!n3)
continue;
const o3 = { x: n3.x + a2.x, y: n3.y + a2.y };
c2.set(e34, o3);
}
const l2 = hk(e33, t2, s2), h2 = hk(e33, t2, s2, c2);
if (h2 < r2 - ew)
return;
const d2 = sk(e33, r2);
return ak(l2, h2, d2) ? undefined : a2;
};
var uk = (e33, t2, n2, o2, i2, r2, s2) => {
const a2 = e33[t2];
if (!a2)
return false;
const c2 = qO(a2, n2);
if (!c2)
return false;
const l2 = dk(r2, a2, c2, o2, i2, s2);
if (!l2)
return false;
let h2 = false;
for (const e34 of c2) {
const t3 = a2.route[e34];
t3 && (t3.x += l2.x, t3.y += l2.y, eO(t3, r2.bounds), h2 = true);
}
return h2;
};
var pk = (e33, t2, n2, o2, i2, r2) => qO(t2, n2) ?? ((e34, t3, n3, o3, i3, r3) => {
const s2 = t3.route[n3];
if (!s2 || s2.pcb_port_id || n3 !== 0 && n3 !== t3.route.length - 1)
return;
const a2 = VO(e34, t3, s2, r3);
if (!a2)
return;
const c2 = { ...s2, x: s2.x + o3, y: s2.y + i3 };
return ok(e34, c2) && WO(c2, a2) ? ZO(t3, n3) : undefined;
})(e33, t2, n2, o2, i2, r2);
var mk = (e33, t2, n2, o2, i2, r2) => {
const s2 = dk(i2, e33, t2, n2, o2, r2);
if (!s2)
return false;
let a2 = false;
for (const n3 of t2) {
const t3 = e33.route[n3];
t3 && (t3.x += s2.x, t3.y += s2.y, eO(t3, i2.bounds), a2 = true);
}
return a2;
};
var gk = (e33, t2, n2, o2, i2, r2) => {
const s2 = t2.route[n2];
if (!s2)
return false;
if (s2.pcb_port_id)
return false;
const a2 = VO(e33, t2, s2, r2);
return !!a2 && WO({ ...s2, x: s2.x + o2, y: s2.y + i2 }, a2);
};
var fk = (e33, t2, n2, o2) => {
const i2 = t2.route[n2];
if (i2 && !i2.pcb_port_id)
return VO(e33, t2, i2, o2);
};
var _k = (e33, t2, n2, o2, i2, r2, s2) => {
const a2 = e33[t2];
if (!a2 || a2.route.length === 0)
return false;
const c2 = ((e34, t3, n3, o3, i3) => {
let { NEGATIVE_INFINITY: r3, POSITIVE_INFINITY: s3, NEGATIVE_INFINITY: a3, POSITIVE_INFINITY: c3 } = Number;
for (const n4 of [0, t3.route.length - 1]) {
const o4 = t3.route[n4], l3 = fk(e34, t3, n4, i3);
if (!o4 || !l3)
return;
r3 = Math.max(r3, l3.center.x - l3.width / 2 - o4.x), s3 = Math.min(s3, l3.center.x + l3.width / 2 - o4.x), a3 = Math.max(a3, l3.center.y - l3.height / 2 - o4.y), c3 = Math.min(c3, l3.center.y + l3.height / 2 - o4.y);
}
if (!(r3 > s3 || a3 > c3))
return { x: KA(n3, r3, s3), y: KA(o3, a3, c3) };
})(i2, a2, n2, o2, s2);
if (!c2)
return false;
const l2 = a2.route.map((e34, t3) => t3), h2 = dk(i2, a2, l2, c2.x, c2.y, r2);
if (!h2)
return false;
const d2 = a2.route.length - 1;
if (!gk(i2, a2, 0, h2.x, h2.y, s2) || !gk(i2, a2, d2, h2.x, h2.y, s2))
return false;
let u2 = false;
for (const e34 of a2.route)
e34.x += h2.x, e34.y += h2.y, eO(e34, i2.bounds), u2 = true;
return u2;
};
var yk = (e33, t2, n2) => {
const o2 = t2.x - e33.x, i2 = t2.y - e33.y, r2 = n2.x - t2.x, s2 = n2.y - t2.y;
return Math.abs(o2 * s2 - i2 * r2) <= ew;
};
var bk = (e33, t2) => {
if (e33.z !== t2.z)
return false;
const n2 = t2.end.x - t2.start.x, o2 = t2.end.y - t2.start.y, i2 = e33.x - t2.start.x, r2 = e33.y - t2.start.y;
return Math.abs(n2 * r2 - o2 * i2) <= ew;
};
var xk = (e33, t2) => {
const n2 = ((e34, t3) => {
const n3 = t3.end.x - t3.start.x, o3 = t3.end.y - t3.start.y, i2 = Math.max(ew, 0.12 * (e34.traceThickness ?? 0.1)), r2 = Math.abs(o3) <= i2, s2 = Math.abs(n3) <= i2;
let { startIndex: a2, endIndex: c2 } = t3;
if (r2 || s2) {
const n4 = r2 ? (t3.start.y + t3.end.y) / 2 : (t3.start.x + t3.end.x) / 2;
for (;a2 > 0; ) {
const o4 = e34.route[a2 - 1];
if (!o4 || o4.z !== t3.z || Math.abs((r2 ? o4.y : o4.x) - n4) > i2)
break;
a2 -= 1;
}
for (;c2 < e34.route.length - 1; ) {
const o4 = e34.route[c2 + 1];
if (!o4 || o4.z !== t3.z || Math.abs((r2 ? o4.y : o4.x) - n4) > i2)
break;
c2 += 1;
}
return Array.from({ length: c2 - a2 + 1 }, (e35, t4) => a2 + t4);
}
for (;a2 > 0; ) {
const n4 = e34.route[a2 - 1], o4 = e34.route[a2], i3 = e34.route[a2 + 1];
if (!(n4 && o4 && i3 && n4.z === t3.z && bk(n4, t3) && yk(n4, o4, i3)))
break;
a2 -= 1;
}
for (;c2 < e34.route.length - 1; ) {
const n4 = e34.route[c2 - 1], o4 = e34.route[c2], i3 = e34.route[c2 + 1];
if (!(n4 && o4 && i3 && i3.z === t3.z && bk(i3, t3) && yk(n4, o4, i3)))
break;
c2 += 1;
}
return Array.from({ length: c2 - a2 + 1 }, (e35, t4) => a2 + t4);
})(e33, t2);
if (n2.length <= 2)
return;
const o2 = [];
for (const t3 of n2) {
const n3 = qO(e33, t3);
if (!n3)
return;
o2.push(...n3);
}
return [...new Set(o2)];
};
var vk = (e33, t2) => t2 > 0 && t2 < e33.route.length - 1 && !((e34, t3) => {
const n2 = e34.route[t3];
if (!n2)
return false;
const o2 = e34.route[t3 - 1], i2 = e34.route[t3 + 1];
return o2 && o2.z !== n2.z && IO(o2, n2) || i2 && i2.z !== n2.z && IO(i2, n2);
})(e33, t2);
var Ik = (e33, t2, n2) => {
const o2 = e33.route[t2.startIndex], i2 = e33.route[t2.endIndex];
return !(!o2 || !i2) && (o2.z === t2.z && i2.z === t2.z && (!!((e34, t3) => zO(e34).maxX >= t3.minX - ew && zO(e34).minX <= t3.maxX + ew && zO(e34).maxY >= t3.minY - ew && zO(e34).minY <= t3.maxY + ew)(t2, n2) && (vk(e33, t2.startIndex) || vk(e33, t2.endIndex))));
};
var Sk = (e33, t2, n2, o2, i2, r2, s2) => {
const a2 = e33[t2.routeIndex];
if (!a2)
return false;
const c2 = ((e34, t3, n3, o3) => {
const i3 = tO(BO(n3), o3);
let { startIndex: r3, startIndex: s3 } = t3;
for (;r3 > 0; ) {
const n4 = { ...t3, startIndex: r3 - 1, endIndex: r3, start: e34.route[r3 - 1], end: e34.route[r3] };
if (!e34.route[r3 - 1] || !Ik(e34, n4, i3))
break;
r3 -= 1;
}
for (;s3 < e34.route.length - 2; ) {
const n4 = { ...t3, startIndex: s3 + 1, endIndex: s3 + 2, start: e34.route[s3 + 1], end: e34.route[s3 + 2] };
if (!e34.route[s3 + 2] || !Ik(e34, n4, i3))
break;
s3 += 1;
}
const a3 = [];
for (let t4 = r3;t4 <= s3 + 1; t4 += 1)
vk(e34, t4) && a3.push(t4);
return [...new Set(a3)];
})(a2, t2, n2, o2);
return !(c2.length <= 2) && mk(a2, c2, i2, r2, s2, t2.radius);
};
var Ck = (e33, t2) => {
const n2 = YO(t2, e33), o2 = n2.x - t2.x, i2 = n2.y - t2.y, r2 = Math.hypot(o2, i2), s2 = e33.end.x - e33.start.x, a2 = e33.end.y - e33.start.y, c2 = Math.hypot(s2, a2), l2 = e33.routeIndex % 2 == 0 ? 1 : -1;
return { projection: n2, direction: r2 > KM ? { x: o2 / r2, y: i2 / r2 } : c2 > KM ? { x: -a2 / c2 * l2, y: s2 / c2 * l2 } : { x: 1, y: 0 } };
};
var Pk = (e33, t2, n2, o2, i2) => {
const r2 = e33[t2.routeIndex];
if (!r2)
return false;
const s2 = lk(i2, t2, n2, o2, t2.radius);
if (Math.abs(s2.x) <= KM && Math.abs(s2.y) <= KM)
return false;
const a2 = { x: t2.x + s2.x, y: t2.y + s2.y }, c2 = ik(i2, t2), l2 = ik(i2, a2);
if (l2 < t2.radius - ew)
return false;
const h2 = sk(i2, t2.radius);
if (ak(c2, l2, h2))
return false;
t2.x += s2.x, t2.y += s2.y, eO(t2, i2.bounds);
for (const e34 of t2.pointIndexes) {
const n3 = r2.route[e34];
n3 && (n3.x = t2.x, n3.y = t2.y);
}
return true;
};
var Mk = (e33, t2, n2) => {
const o2 = OO(e33, n2), i2 = o2.find((e34) => e34.routeIndex === t2.routeIndex && e34.pointIndexes.some((e35) => t2.pointIndexes.includes(e35)));
return i2 ? o2.filter((e34) => e34.rootConnectionName === i2.rootConnectionName && Math.hypot(e34.x - i2.x, e34.y - i2.y) <= ew) : [];
};
var wk = (e33, t2, n2, o2, i2) => t2.movable && Mk(e33, t2, i2).length <= 1 && Pk(e33, t2, n2, o2, i2);
var Nk = (e33, t2, n2, o2, i2 = 1) => {
const { projection: r2, direction: s2 } = Ck(t2, n2), a2 = tw * i2, c2 = 1 - r2.t, l2 = r2.t, h2 = uk(e33, t2.routeIndex, t2.startIndex, s2.x * a2 * c2, s2.y * a2 * c2, o2, t2.radius), d2 = uk(e33, t2.routeIndex, t2.endIndex, s2.x * a2 * l2, s2.y * a2 * l2, o2, t2.radius);
return !(!h2 && !d2) || ((e34, t3, n3, o3, i3) => {
const r3 = e34[t3.routeIndex];
if (!r3)
return false;
const { projection: s3, direction: a3 } = Ck(t3, n3), c3 = lk(o3, s3, a3.x * tw * i3, a3.y * tw * i3, t3.radius);
if (Math.abs(c3.x) <= KM && Math.abs(c3.y) <= KM)
return false;
const l3 = { ...r3.route[t3.startIndex], x: s3.x + c3.x, y: s3.y + c3.y };
if (eO(l3, o3.bounds), xt(l3, t3.start, t3.end) <= ew)
return false;
const h3 = r3.route[t3.startIndex], d3 = r3.route[t3.endIndex];
if (!h3 || !d3)
return false;
const u2 = rk(o3, h3, d3), p2 = Math.min(ik(o3, l3), rk(o3, h3, l3), rk(o3, l3, d3));
if (p2 < t3.radius - ew)
return false;
const m2 = sk(o3, t3.radius);
return !ak(u2, p2, m2) && (r3.route.splice(t3.endIndex, 0, l3), true);
})(e33, t2, n2, o2, i2);
};
var Tk = (e33, t2, n2, o2, i2, r2 = 1) => {
const s2 = t2.radius + iw(o2) + ow, a2 = Yk(t2, n2, s2);
if (!a2)
return false;
const c2 = Math.min(0.3 * Math.abs(r2), a2.penetration + ow), l2 = a2.direction.x * c2, h2 = a2.direction.y * c2, d2 = e33[t2.routeIndex];
if (!d2)
return false;
const u2 = !((e34) => {
for (let t3 = 0;t3 < e34.route.length - 1; t3 += 1) {
const n3 = e34.route[t3], o3 = e34.route[t3 + 1];
if (n3 && o3 && n3.z !== o3.z && IO(n3, o3))
return true;
}
return false;
})(d2);
if (u2 && _k(e33, t2.routeIndex, l2, h2, o2, t2.radius, i2))
return true;
const p2 = Sk(e33, t2, n2, s2, l2, h2, o2) || ((e34, t3, n3, o3, i3) => {
const r3 = e34[t3.routeIndex];
if (!r3)
return false;
const s3 = xk(r3, t3);
return !!s3 && mk(r3, s3, n3, o3, i3, t3.radius);
})(e33, t2, l2, h2, o2) || ((e34, t3, n3, o3, i3, r3) => {
const s3 = e34[t3.routeIndex];
if (!s3)
return false;
const a3 = pk(i3, s3, t3.startIndex, n3, o3, r3), c3 = pk(i3, s3, t3.endIndex, n3, o3, r3);
if (!a3 || !c3)
return false;
const l3 = [...new Set([...a3, ...c3])], h3 = dk(i3, s3, l3, n3, o3, t3.radius);
if (!h3)
return false;
let d3 = false;
for (const e35 of l3) {
const t4 = s3.route[e35];
t4 && (t4.x += h3.x, t4.y += h3.y, eO(t4, i3.bounds), d3 = true);
}
return d3;
})(e33, t2, l2, h2, o2, i2);
if (p2)
return true;
if (!u2 && _k(e33, t2.routeIndex, l2, h2, o2, t2.radius, i2))
return true;
const m2 = n2.width / 2, g2 = n2.height / 2, f2 = (Math.abs(a2.direction.y) >= Math.abs(a2.direction.x) ? [{ ...d2.route[t2.startIndex], x: n2.center.x - m2 - s2, y: n2.center.y + a2.direction.y * (g2 + s2) }, { ...d2.route[t2.startIndex], x: n2.center.x + m2 + s2, y: n2.center.y + a2.direction.y * (g2 + s2) }] : [{ ...d2.route[t2.startIndex], x: n2.center.x + a2.direction.x * (m2 + s2), y: n2.center.y - g2 - s2 }, { ...d2.route[t2.startIndex], x: n2.center.x + a2.direction.x * (m2 + s2), y: n2.center.y + g2 + s2 }]).map((e34) => {
const { t: n3 } = YO(e34, t2), i3 = { x: t2.start.x + (t2.end.x - t2.start.x) * n3, y: t2.start.y + (t2.end.y - t2.start.y) * n3 }, r3 = lk(o2, i3, e34.x - i3.x, e34.y - i3.y, t2.radius);
return e34.x = i3.x + r3.x, e34.y = i3.y + r3.y, eO(e34, o2.bounds), { point: e34, t: n3, moved: Math.abs(r3.x) > KM || Math.abs(r3.y) > KM, awayFromObstacleMotion: r3.x * a2.direction.x + r3.y * a2.direction.y };
}).sort((e34, t3) => e34.t - t3.t);
if (!f2.some(({ moved: e34 }) => e34))
return false;
if (!f2.some(({ awayFromObstacleMotion: e34 }) => e34 > ew))
return false;
const _2 = f2.map(({ point: e34 }) => e34);
if (_2.every((e34) => xt(e34, t2.start, t2.end) <= ew))
return false;
if (_2.some((e34) => !ok(o2, e34)))
return false;
const y2 = d2.route[t2.startIndex], b2 = d2.route[t2.endIndex], x2 = _2[0], v2 = _2[1];
if (!(y2 && b2 && x2 && v2))
return false;
const I2 = rk(o2, y2, b2), S2 = Math.min(ik(o2, x2), ik(o2, v2), rk(o2, y2, x2), rk(o2, x2, v2), rk(o2, v2, b2));
if (S2 < t2.radius - ew)
return false;
const C2 = sk(o2, t2.radius);
return !ak(I2, S2, C2) && (d2.route.splice(t2.endIndex, 0, ..._2), true);
};
var Rk = (e33, t2, n2) => {
let o2;
for (const i2 of e33) {
if (n2 !== undefined && i2.routeIndex !== n2)
continue;
const e34 = YO(t2, i2), r2 = Math.hypot(e34.x - t2.x, e34.y - t2.y);
(!o2 || r2 < o2.distance) && (o2 = { segment: i2, distance: r2 });
}
return o2?.segment;
};
var Ek = (e33, t2, n2) => {
let o2;
for (const i2 of e33) {
if (n2 !== undefined && i2.routeIndex !== n2)
continue;
const e34 = Math.hypot(i2.x - t2.x, i2.y - t2.y);
(!o2 || e34 < o2.distance) && (o2 = { via: i2, distance: e34 });
}
return o2?.via;
};
var Ak = (e33, t2) => {
const n2 = e33.map((e34) => ({ via: e34, distance: Math.hypot(e34.x - t2.x, e34.y - t2.y) })).sort((e34, t3) => e34.distance - t3.distance).slice(0, 2).map(({ via: e34 }) => e34);
return n2.length === 2 ? n2 : undefined;
};
var Ok = (e33, t2, n2, o2) => {
const i2 = t2.x - n2.x, r2 = t2.y - n2.y, s2 = Math.hypot(i2, r2);
return wk(e33, t2, (s2 > KM ? i2 / s2 : 1) * tw, (s2 > KM ? r2 / s2 : 0) * tw, o2);
};
var kk = (e33, t2) => {
const n2 = YO(e33.start, t2), o2 = YO(e33.end, t2), i2 = YO(t2.start, e33), r2 = YO(t2.end, e33), s2 = [{ leftT: 0, rightT: n2.t, leftPoint: e33.start, rightPoint: n2 }, { leftT: 1, rightT: o2.t, leftPoint: e33.end, rightPoint: o2 }, { leftT: i2.t, rightT: 0, leftPoint: i2, rightPoint: t2.start }, { leftT: r2.t, rightT: 1, leftPoint: r2, rightPoint: t2.end }];
let a2 = s2[0], c2 = Math.hypot(a2.leftPoint.x - a2.rightPoint.x, a2.leftPoint.y - a2.rightPoint.y);
for (let e34 = 1;e34 < s2.length; e34 += 1) {
const t3 = s2[e34], n3 = Math.hypot(t3.leftPoint.x - t3.rightPoint.x, t3.leftPoint.y - t3.rightPoint.y);
n3 < c2 && (a2 = t3, c2 = n3);
}
return a2;
};
var Dk = (e33, t2, n2, o2, i2, r2) => {
const s2 = KA(r2, 0, 1), a2 = 1 - s2, c2 = s2, l2 = uk(e33, t2.routeIndex, t2.startIndex, n2 * a2, o2 * a2, i2, t2.radius), h2 = uk(e33, t2.routeIndex, t2.endIndex, n2 * c2, o2 * c2, i2, t2.radius);
return l2 || h2;
};
var Lk = (e33, t2, n2, o2, i2, r2 = 0.035, s2 = false) => {
if (!s2 && JA(t2.rootConnectionName, n2.rootConnectionName, i2))
return false;
const a2 = t2.radius + n2.radius + 0.2 + ow, c2 = t2.x - n2.x, l2 = t2.y - n2.y, h2 = Math.hypot(c2, l2), d2 = a2 - h2;
if (d2 <= 0)
return false;
const u2 = 1.618 * (97 * t2.routeIndex + 13 * n2.routeIndex), p2 = h2 > KM ? c2 / h2 : Math.cos(u2), m2 = h2 > KM ? l2 / h2 : Math.sin(u2), g2 = Number(t2.movable) + Number(n2.movable);
if (g2 === 0)
return false;
const f2 = Math.min(r2, d2 / g2), _2 = wk(e33, t2, p2 * f2, m2 * f2, o2), y2 = wk(e33, n2, -p2 * f2, -m2 * f2, o2);
return _2 || y2;
};
var zk = (e33, t2, n2, o2, i2) => {
if (!JA(t2.rootConnectionName, n2.rootConnectionName, i2))
return false;
const [r2, s2] = t2.canCanonicalize ? n2.canCanonicalize && t2.routeIndex <= n2.routeIndex ? [t2, n2] : [n2, t2] : [t2, n2];
return ((e34, t3, n3, o3) => {
if (!n3.canCanonicalize)
return false;
const i3 = t3.x - n3.x, r3 = t3.y - n3.y;
if (!n3.movable && Math.hypot(i3, r3) > n3.radius + ew)
return false;
const s3 = e34[n3.routeIndex];
if (!s3)
return false;
const a2 = { x: n3.x, y: n3.y }, c2 = n3.pointIndexes.map((e35) => {
const t4 = s3.route[e35];
return t4 ? { pointIndex: e35, x: t4.x, y: t4.y } : undefined;
});
if (Pk(e34, n3, i3, r3, o3) && IO(n3, t3))
return true;
n3.x = a2.x, n3.y = a2.y;
for (const e35 of c2) {
if (!e35)
continue;
const t4 = s3.route[e35.pointIndex];
t4 && (t4.x = e35.x, t4.y = e35.y);
}
return false;
})(e33, r2, s2, o2);
};
var Bk = (e33, t2, n2, o2, i2, r2 = 0.035, s2 = 2, a2 = false) => {
if (JA(t2.rootConnectionName, n2.rootConnectionName, i2))
return false;
const c2 = YO(t2, n2), l2 = t2.x - c2.x, h2 = t2.y - c2.y, d2 = Math.hypot(l2, h2), u2 = t2.radius + n2.radius + (WA.traceClearance) + ow - d2;
if (u2 <= 0)
return false;
const p2 = n2.end.x - n2.start.x, m2 = n2.end.y - n2.start.y, g2 = Math.hypot(p2, m2), f2 = t2.routeIndex % 2 == 0 ? 1 : -1, _2 = d2 > KM ? l2 / d2 : g2 > KM ? -m2 / g2 * f2 : 1, y2 = d2 > KM ? h2 / d2 : g2 > KM ? p2 / g2 * f2 : 0, b2 = Math.min(r2, u2 / s2), x2 = a2 ? ((e34, t3, n3, o3, i3) => {
const r3 = Mk(e34, t3, i3);
if (r3.length === 0 || r3.some((t4) => !t4.movable || e34[t4.routeIndex] === undefined))
return false;
const s3 = r3.reduce((e35, t4) => t4.radius > e35.radius ? t4 : e35);
if (!Pk(e34, s3, n3, o3, i3))
return false;
for (const t4 of r3) {
if (t4 === s3)
continue;
t4.x = s3.x, t4.y = s3.y;
const n4 = e34[t4.routeIndex];
for (const e35 of t4.pointIndexes) {
const t5 = n4.route[e35];
t5 && (t5.x = s3.x, t5.y = s3.y);
}
}
return true;
})(e33, t2, _2 * b2, y2 * b2, o2) : wk(e33, t2, _2 * b2, y2 * b2, o2), v2 = Dk(e33, n2, -_2 * b2, -y2 * b2, o2, c2.t);
return x2 || v2;
};
var Fk = (e33, t2, n2, o2, i2) => {
if (t2.z !== n2.z || JA(t2.rootConnectionName, n2.rootConnectionName, i2))
return false;
const r2 = kk(t2, n2), s2 = r2.leftPoint.x - r2.rightPoint.x, a2 = r2.leftPoint.y - r2.rightPoint.y, c2 = Math.hypot(s2, a2), l2 = t2.radius + n2.radius + (WA.traceClearance) + ow - c2;
if (l2 <= 0)
return false;
const h2 = t2.end.x - t2.start.x, d2 = t2.end.y - t2.start.y, u2 = Math.hypot(h2, d2), p2 = (t2.routeIndex + n2.routeIndex) % 2 == 0 ? 1 : -1, m2 = c2 > KM ? s2 / c2 : u2 > KM ? -d2 / u2 * p2 : 1, g2 = c2 > KM ? a2 / c2 : u2 > KM ? h2 / u2 * p2 : 0, f2 = Math.min(nw, l2 / 2), _2 = Dk(e33, t2, m2 * f2, g2 * f2, o2, r2.leftT), y2 = Dk(e33, n2, -m2 * f2, -g2 * f2, o2, r2.rightT);
return _2 || y2;
};
var jk = (e33, t2, n2) => FO(e33, n2).includes(t2.z);
var $k = (e33, t2, n2, o2, i2) => {
const r2 = t2[n2];
if (!r2)
return;
const s2 = kO(r2, n2);
if (s2.length === 0)
return;
const a2 = ZA(r2), c2 = Rk(s2, o2);
if (!c2)
return;
const l2 = HO(e33, o2, 0.6, (t3) => !QA(a2, t3, i2) && jk(t3, c2, e33.layerCount));
if (l2)
return { obstacle: l2, segment: c2 };
const h2 = HO(e33, o2, 0.6, (t3) => !QA(a2, t3, i2) && s2.some((n3) => jk(t3, n3, e33.layerCount)));
if (!h2)
return;
const d2 = Rk(s2.filter((t3) => jk(h2, t3, e33.layerCount)), o2);
return d2 ? { obstacle: h2, segment: d2 } : undefined;
};
var Yk = (e33, t2, n2) => {
const o2 = t2.width / 2, i2 = t2.height / 2, r2 = [{ x: t2.center.x - o2, y: t2.center.y - i2 }, { x: t2.center.x + o2, y: t2.center.y - i2 }, { x: t2.center.x + o2, y: t2.center.y + i2 }, { x: t2.center.x - o2, y: t2.center.y + i2 }], s2 = [t2.center, ...r2].map((t3) => YO(t3, e33)), a2 = [{ point: e33.start, t: 0 }, { point: e33.end, t: 1 }, { point: { x: (e33.start.x + e33.end.x) / 2, y: (e33.start.y + e33.end.y) / 2 }, t: 0.5 }, ...s2.map((e34) => ({ point: { x: e34.x, y: e34.y }, t: e34.t }))];
let c2;
const l2 = Math.hypot(e33.end.x - e33.start.x, e33.end.y - e33.start.y);
for (const o3 of a2) {
const i3 = GO(o3.point, t2, n2);
if (!i3)
continue;
const r3 = l2 > KM ? Math.abs(((e33.end.x - e33.start.x) * i3.direction.y - (e33.end.y - e33.start.y) * i3.direction.x) / l2) : 0;
(!c2 || i3.penetration > c2.penetration + KM || Math.abs(i3.penetration - c2.penetration) <= KM && r3 > c2.normality) && (c2 = { ...i3, normality: r3, t: o3.t });
}
return c2;
};
var Xk = (e33, t2, n2, o2 = false) => {
let i2 = false;
const r2 = OO(t2, e33), s2 = DO(t2), a2 = jO(e33, r2, s2), c2 = Math.max(1, 2 * a2), l2 = rO(r2, LO, c2), h2 = rO(s2, zO, c2);
for (let s3 = 0;s3 < r2.length; s3 += 1) {
const h3 = r2[s3];
if (!h3)
continue;
const d2 = sO(l2, tO(LO(h3), a2), c2);
for (const a3 of d2) {
if (a3 <= s3)
continue;
const c3 = r2[a3];
c3 && (i2 = Lk(t2, h3, c3, e33, n2, nw, o2) || i2);
}
}
for (let o3 = 0;o3 < r2.length; o3 += 1) {
const l3 = r2[o3];
if (!l3)
continue;
const d2 = sO(h2, tO(LO(l3), a2), c2);
for (const o4 of d2) {
const r3 = s2[o4];
r3 && (i2 = Bk(t2, l3, r3, e33, n2) || i2);
}
}
for (let o3 = 0;o3 < s2.length; o3 += 1) {
const r3 = s2[o3];
if (!r3)
continue;
const l3 = sO(h2, tO(zO(r3), a2), c2);
for (const a3 of l3) {
if (a3 <= o3)
continue;
const c3 = s2[a3];
c3 && (i2 = Fk(t2, r3, c3, e33, n2) || i2);
}
}
return ((e34, t3, n3, o3, i3, r3, s3, a3) => {
let c3 = false;
const l3 = iw(e34), h3 = o3.reduce((e35, t4) => Math.max(e35, t4.radius), 0) + l3 + ow, d2 = rw(e34), u2 = n3.reduce((e35, t4) => Math.max(e35, t4.radius), 0) + d2 + ow;
for (const p2 of e34.obstacles) {
if (p2.isCopperPour)
continue;
const m2 = BO(p2), g2 = sO(i3, tO(m2, u2), s3);
for (const o4 of g2) {
const i4 = n3[o4];
if (!i4)
continue;
if (QA(i4.rootConnectionName, p2, a3))
continue;
const r4 = GO(i4, p2, i4.radius + d2 + ow);
if (!r4)
continue;
const s4 = Math.min(nw, r4.penetration);
c3 = wk(t3, i4, r4.direction.x * s4, r4.direction.y * s4, e34) || c3;
}
const f2 = sO(r3, tO(m2, h3), s3);
for (const n4 of f2) {
const i4 = o3[n4];
if (!i4)
continue;
if (QA(i4.rootConnectionName, p2, a3) || !jk(p2, i4, e34.layerCount))
continue;
const r4 = Yk(i4, p2, i4.radius + l3 + ow);
if (!r4)
continue;
const s4 = Math.min(nw, r4.penetration);
c3 = Dk(t3, i4, r4.direction.x * s4, r4.direction.y * s4, e34, r4.t) || c3;
}
}
return c3;
})(e33, t2, r2, s2, l2, h2, c2, n2) || i2;
};
var Wk = (e33, t2, n2, o2 = 1, i2, r2 = false, s2 = true) => {
const a2 = xO(t2), c2 = Math.max(2, Math.round(12 * Math.max(1, n2) * o2));
let l2 = false;
for (let t3 = 0;t3 < c2; t3 += 1) {
if (!Xk(e33, a2, i2, r2))
break;
l2 = true;
}
return l2 && s2 && ((e34, t3, n3) => {
let o3 = false;
const i3 = OO(t3, e34), r3 = DO(t3), s3 = jO(e34, i3, r3), a3 = Math.max(1, 2 * s3), c3 = rO(r3, zO, a3);
for (const l3 of i3) {
const i4 = sO(c3, tO(LO(l3), s3), a3);
for (const s4 of i4) {
const i5 = r3[s4];
i5 && (o3 = Bk(t3, l3, i5, e34, n3, nw, 1.75) || o3);
}
}
})(e33, a2, i2), l2 ? Gk(a2) : t2;
};
var Vk = (e33) => {
const t2 = [];
for (let n2 = 0;n2 < e33.route.length - 1; n2 += 1) {
const o2 = e33.route[n2], i2 = e33.route[n2 + 1];
if (!o2 || !i2)
continue;
if (o2.toNextSegmentType === "through_obstacle")
continue;
if (o2.z === i2.z || !IO(o2, i2))
continue;
const r2 = { x: o2.x, y: o2.y }, s2 = t2.at(-1);
s2 && IO(s2, r2) || t2.push(r2);
}
return t2;
};
var Hk = (e33) => ({ ...e33, vias: Vk(e33) });
var Gk = (e33) => e33.map(Hk);
var Uk = (e33, t2) => {
const n2 = new Set(t2);
return e33.map((e34, t3) => n2.has(t3) ? Hk(e34) : e34);
};
var Zk = (e33) => {
const t2 = e33.pcb_trace_id;
if (typeof t2 != "string")
return;
const n2 = t2.match(/^trace_(\d+)/);
return n2 ? Number.parseInt(n2[1], 10) : undefined;
};
var qk = (e33) => {
const t2 = e33.center ?? e33.pcb_center;
if (!t2 || typeof t2 != "object")
return;
const n2 = t2;
return typeof n2.x == "number" && typeof n2.y == "number" ? { x: n2.x, y: n2.y } : undefined;
};
var Jk = (e33, t2 = true) => e33.errors.filter((e34) => ((e35) => CO(e35) === "pcb_via_clearance_error" || Array.isArray(e35.pcb_via_ids))(e34) && (t2 || !Qk(e34))).length;
var Qk = (e33) => CO(e33) === "pcb_pad_pad_clearance_error" && Array.isArray(e33.pcb_via_ids) && e33.pcb_via_ids.length === 1;
var Kk = (e33) => {
const t2 = Object.entries(e33).filter(([e34, t3]) => e34 !== "source_trace_id" && (e34.endsWith("_id") || e34.endsWith("_ids")) && t3 !== undefined && t3 !== "").sort(([e34], [t3]) => e34.localeCompare(t3)), n2 = typeof e33.message == "string" ? e33.message.replace(/-?\d+\.\d+/g, "#") : "";
return JSON.stringify([CO(e33), t2, n2]);
};
var eD = (e33) => Math.max(e33.errors.filter((e34) => !Qk(e34)).length, e33.count - e33.errors.filter(Qk).length);
var tD = (e33) => {
const t2 = eD(e33);
return t2 > 0 ? t2 : e33.count;
};
var nD = (e33) => {
if (eD(e33) === 0)
return e33.issueScore;
const t2 = e33.errors.filter((e34) => !Qk(e34));
return e33.errors.some(Qk) ? TO(t2) : e33.legacyIssueScore ?? TO(t2);
};
var oD = (e33, t2) => {
const n2 = eD(e33), o2 = eD(t2);
return n2 !== o2 ? n2 < o2 : !(n2 > 0) && e33.count < t2.count;
};
var iD = (e33) => {
const t2 = e33.filter((e34) => !Qk(e34));
return t2.length > 0 ? t2 : e33;
};
var rD = (e33, t2) => {
const n2 = e33.pcb_trace_id;
return typeof n2 == "string" ? t2.get(n2) ?? Zk(e33) : Zk(e33);
};
var sD = (e33, t2, n2, o2, i2) => {
const r2 = n2.pcb_port_id;
if (!r2)
return false;
const s2 = (i2 ?? t2.viaDiameter) / 2;
return e33.obstacles.some((i3) => {
const a2 = FO(i3, e33.layerCount);
return !(a2.length !== 1 || a2[0] !== n2.z || !i3.connectedTo.includes(r2) || n2.x - s2 < i3.center.x - i3.width / 2 - KM || n2.x + s2 > i3.center.x + i3.width / 2 + KM || n2.y - s2 < i3.center.y - i3.height / 2 - KM || n2.y + s2 > i3.center.y + i3.height / 2 + KM) && (QA(ZA(t2), i3, o2) || QA(t2.connectionName, i3, o2));
});
};
var aD = [0, 1, -1, 2, -2, 3, -3, 4];
var cD = aD.flatMap((e33) => aD.map((t2) => [e33, t2])).sort(([e33, t2], [n2, o2]) => Math.abs(e33) + Math.abs(t2) - Math.abs(n2) - Math.abs(o2));
var lD = cD.length;
var hD = (e33, t2, n2) => e33.x - t2 >= n2.minX - KM && e33.x + t2 <= n2.maxX + KM && e33.y - t2 >= n2.minY - KM && e33.y + t2 <= n2.maxY + KM;
var dD = (e33, t2) => {
const n2 = e33.at(-1);
n2 && IO(n2, t2) && n2.z === t2.z && n2.pcb_port_id === t2.pcb_port_id || e33.push(t2);
};
var uD = (e33, t2, n2, o2, i2, r2, s2, a2 = 0, c2 = false) => {
const l2 = CO(n2);
if (l2 !== "pcb_pad_trace_clearance_error" && l2 !== "pcb_trace_error")
return false;
if (i2 < 0 || i2 >= e33.layerCount)
return false;
const h2 = t2[o2];
if (!h2 || h2.route.length < 2)
return false;
const d2 = h2.route.map((e34) => ({ ...e34 })), u2 = d2[0], p2 = d2.at(-1);
if (!u2 || !p2)
return false;
const m2 = qk(n2);
if (!m2)
return false;
const g2 = PO(n2), f2 = g2 ? $k(e33, t2, o2, m2, s2) : undefined, _2 = g2 ? f2?.segment : Rk(kO(h2, o2), m2);
if (!_2 || _2.z === i2)
return false;
let { startIndex: y2, endIndex: b2 } = _2;
const x2 = r2 === "full" ? d2.length : r2;
for (let e34 = 0;e34 < x2; e34 += 1) {
let e35 = false;
const t3 = d2[y2 - 1];
t3?.z === _2.z && (y2 -= 1, e35 = true);
const n3 = d2[b2 + 1];
if (n3?.z === _2.z && (b2 += 1, e35 = true), !e35)
break;
}
const v2 = y2 === 0 && u2.pcb_port_id, I2 = b2 === d2.length - 1 && p2.pcb_port_id, S2 = h2.viaDiameter / 2, C2 = cD[a2 % lD];
let P2 = false;
const M2 = (t3) => {
const n3 = t3 === "start" ? u2 : p2, o3 = ((e34, t4, n4, o4) => {
const i3 = n4.pcb_port_id;
if (i3)
return e34.obstacles.find((r4) => {
const s3 = FO(r4, e34.layerCount);
return !(s3.length !== 1 || s3[0] !== n4.z || !r4.connectedTo.includes(i3) || !WO(n4, r4)) && (QA(ZA(t4), r4, o4) || QA(t4.connectionName, r4, o4));
});
})(e33, h2, n3, s2), r3 = ((e34, t4) => {
const n4 = t4 === "start" ? e34[0] : e34.at(-1);
if (!n4)
return;
const o4 = t4 === "start" ? Array.from({ length: e34.length - 1 }, (e35, t5) => t5 + 1) : Array.from({ length: e34.length - 1 }, (t5, n5) => e34.length - n5 - 2);
for (const t5 of o4) {
const o5 = e34[t5];
if (!o5)
continue;
const i3 = o5.x - n4.x, r4 = o5.y - n4.y, s3 = Math.hypot(i3, r4);
if (!(s3 <= KM))
return { x: i3 / s3, y: r4 / s3 };
}
})(d2, t3);
if (!o3 || !r3)
return;
const a3 = ((e34, t4, n4, o4) => {
let i3 = 0, r4 = Math.hypot(t4.width, t4.height) + 2 * o4;
const s3 = o4 + KM, a4 = (t5) => ({ x: e34.x + n4.x * t5, y: e34.y + n4.y * t5 });
if (!(XO(a4(r4), t4) < s3)) {
for (;r4 - i3 > KM; ) {
const e35 = (i3 + r4) / 2;
XO(a4(e35), t4) >= s3 ? r4 = e35 : i3 = e35;
}
return a4(r4);
}
})(n3, o3, ((e34, t4) => {
const n4 = t4 * Math.PI / 4, o4 = Math.cos(n4), i3 = Math.sin(n4);
return { x: e34.x * o4 - e34.y * i3, y: e34.x * i3 + e34.y * o4 };
})(r3, t3 === "start" ? C2[0] : C2[1]), S2);
if (!a3 || !hD(a3, S2, e33.bounds) || XO(a3, o3) + KM < S2)
return;
if (!c2)
return a3;
const l3 = ((e34, t4, n4, o4, i3, r4) => {
const s3 = o4 + (e34.minBoardEdgeClearance ?? 0), a4 = { minX: e34.bounds.minX + s3, maxX: e34.bounds.maxX - s3, minY: e34.bounds.minY + s3, maxY: e34.bounds.maxY - s3 };
if (a4.minX > a4.maxX || a4.minY > a4.maxY)
return;
const c3 = _O(e34, t4, o4, i3, r4), l4 = (e35) => wt(e35, a4) && c3.every((t5) => hO(e35, t5) >= t5.clearance), h3 = lO(n4, a4);
if (l4(h3))
return wt(n4, a4) ? n4 : h3;
const d3 = c3.filter((e35) => hO(h3, e35) < e35.clearance), u3 = new Set(d3);
for (let e35 = 0;e35 < d3.length; e35 += 1)
for (const t5 of c3)
!u3.has(t5) && Wt(d3[e35].bounds, t5.bounds) && (u3.add(t5), d3.push(t5));
const p3 = d3.flatMap(pO), m3 = { x: a4.minX, y: a4.minY }, g3 = { x: a4.maxX, y: a4.minY }, f3 = { x: a4.maxX, y: a4.maxY }, _3 = { x: a4.minX, y: a4.maxY };
let y3;
p3.push(dO(m3, g3), dO(g3, f3), dO(f3, _3), dO(_3, m3));
let b3 = Number.POSITIVE_INFINITY;
const x3 = (e35) => {
const t5 = Xt(e35, n4);
t5 < b3 && l4(e35) && (y3 = e35, b3 = t5);
};
for (const e35 of p3)
for (const t5 of mO(n4, e35))
x3(t5);
for (let e35 = 0;e35 < p3.length; e35 += 1) {
const t5 = p3[e35];
if (!(Xt(n4, lO(n4, t5.bounds)) > b3))
for (let o5 = e35 + 1;o5 < p3.length; o5 += 1) {
const e36 = p3[o5];
if (Wt(t5.bounds, e36.bounds) && !(Xt(n4, lO(n4, e36.bounds)) > b3))
for (const n5 of fO(t5, e36))
x3(n5);
}
}
return y3;
})(e33, h2, a3, S2, [_2.z, i2], s2);
return P2 ||= l3 !== undefined && l3 !== a3, l3;
}, w2 = v2 ? M2("start") : undefined, N2 = I2 ? M2("end") : undefined;
if (v2 && !w2 || I2 && !N2 || c2 && !P2)
return false;
const T2 = [];
for (let e34 = 0;e34 < y2; e34 += 1)
dD(T2, d2[e34]);
const R2 = d2[y2], E2 = y2 > 0 && IO(d2[y2 - 1], R2), A2 = d2[b2], O2 = b2 < d2.length - 1 && IO(d2[b2 + 1], A2);
v2 ? (dD(T2, u2), dD(T2, { ...u2, ...w2, pcb_port_id: undefined }), dD(T2, { ...u2, ...w2, z: i2, pcb_port_id: undefined })) : (E2 || dD(T2, { ...R2, pcb_port_id: undefined }), dD(T2, { ...R2, z: i2, pcb_port_id: undefined }));
const k2 = I2 ? b2 - 1 : b2;
for (let e34 = y2 + 1;e34 <= k2; e34 += 1)
dD(T2, { ...d2[e34], z: i2, pcb_port_id: undefined });
I2 ? (dD(T2, { ...p2, ...N2, z: i2, pcb_port_id: undefined }), dD(T2, { ...p2, ...N2, pcb_port_id: undefined }), dD(T2, p2)) : O2 || dD(T2, { ...A2, pcb_port_id: undefined });
for (let e34 = b2 + 1;e34 < d2.length; e34 += 1)
dD(T2, d2[e34]);
for (let e34 = 1;e34 < T2.length - 1; e34 += 1)
T2[e34].pcb_port_id = undefined;
const D2 = e33.minBoardEdgeClearance ?? 0.2, L2 = kO(h2, o2), z2 = OO([h2], e33);
for (let t3 = 1;t3 < T2.length; t3 += 1) {
const n3 = T2[t3 - 1], o3 = T2[t3];
if (n3.z === o3.z && !L2.some((e34) => KO(n3, e34.start, e34.end) && KO(o3, e34.start, e34.end)) && rk(e33, n3, o3) < h2.traceThickness / 2 + D2)
return false;
if (n3.z !== o3.z && n3.toNextSegmentType !== "through_obstacle" && !z2.some((e34) => IO(e34, o3) && e34.radius >= S2) && ik(e33, o3) < S2 + D2)
return false;
}
return h2.route = T2, true;
};
var pD = (e33, t2, n2, o2, i2, r2, s2) => {
const a2 = CO(n2);
if (a2 !== "pcb_pad_trace_clearance_error" && a2 !== "pcb_trace_error")
return false;
if (i2 < 0 || i2 >= e33.layerCount)
return false;
const c2 = rD(n2, o2);
if (c2 === undefined)
return false;
const l2 = t2[c2];
if (!l2 || l2.route.length < 2)
return false;
const h2 = l2.route[0], d2 = l2.route.at(-1);
if (!h2 || !d2 || h2.z !== d2.z || i2 === h2.z)
return false;
if (l2.route.some((e34) => e34.z !== h2.z))
return false;
if (!h2.pcb_port_id || !d2.pcb_port_id)
return false;
if (!sD(e33, l2, h2, r2, s2) || !sD(e33, l2, d2, r2, s2))
return false;
const u2 = l2.route.map((e34) => ({ ...e34 }));
return l2.route = [u2[0], { ...u2[0], z: i2, pcb_port_id: undefined }, ...u2.slice(1, -1).map((e34) => ({ ...e34, z: i2 })), { ...u2.at(-1), z: i2, pcb_port_id: undefined }, u2.at(-1)], true;
};
var mD = (e33, t2, n2, o2, i2, r2, s2) => {
if (CO(n2) !== "pcb_pad_trace_clearance_error")
return false;
const a2 = rD(n2, o2);
if (a2 === undefined)
return false;
const c2 = t2[a2];
if (!c2 || c2.route.length < 4)
return false;
const l2 = c2.route.map((e34) => ({ ...e34 }));
if (i2 === "start") {
const t3 = l2[0];
if (!sD(e33, c2, t3, r2, s2))
return false;
let n3 = -1;
for (let e34 = 1;e34 < l2.length; e34 += 1)
if (l2[e34].z !== t3.z) {
n3 = e34;
break;
}
if (n3 <= 0)
return false;
const o3 = n3 - 1;
if (!IO(l2[o3], l2[n3]))
return false;
let i3 = n3;
for (;i3 + 1 < l2.length && IO(l2[n3], l2[i3 + 1]); )
i3 += 1;
const a3 = l2[i3].z, h3 = l2.slice(o3, i3 + 1).map((e34) => e34.z);
return c2.route = [t3, ...h3.slice(1).map((e34) => ({ ...t3, z: e34, pcb_port_id: undefined })), ...l2.slice(1, o3 + 1).map((e34) => ({ ...e34, z: a3 })), ...l2.slice(i3 + 1)], true;
}
const h2 = l2.at(-1);
if (!sD(e33, c2, h2, r2, s2))
return false;
let d2 = -1;
for (let e34 = l2.length - 2;e34 >= 0; e34 -= 1)
if (l2[e34].z !== h2.z) {
d2 = e34;
break;
}
if (d2 < 0 || d2 >= l2.length - 1)
return false;
const u2 = d2 + 1;
if (!IO(l2[d2], l2[u2]))
return false;
let p2 = d2;
for (;p2 - 1 >= 0 && IO(l2[d2], l2[p2 - 1]); )
p2 -= 1;
const m2 = l2[p2].z, g2 = l2.slice(p2, u2 + 1).map((e34) => e34.z);
return c2.route = [...l2.slice(0, p2 + 1), ...l2.slice(u2 + 1, -1).map((e34) => ({ ...e34, z: m2 })), { ...h2, z: m2, pcb_port_id: undefined }, ...g2.slice(1, -1).map((e34) => ({ ...h2, z: e34, pcb_port_id: undefined })), h2], true;
};
var gD = (e33, t2) => {
const n2 = e33.pcb_trace_id;
if (typeof n2 != "string")
return;
if (Array.isArray(e33.pcb_via_ids) && e33.pcb_via_ids.length > 0)
return;
const o2 = Array.isArray(e33.pcb_trace_ids) ? e33.pcb_trace_ids.filter((e34) => typeof e34 == "string") : [], i2 = e33.pcb_trace_error_id, r2 = `overlap_${n2}_`, s2 = typeof i2 == "string" && i2.startsWith(r2) ? i2.slice(r2.length) : undefined, a2 = [n2, ...o2, ...s2 ? [s2] : []], c2 = [...new Set(a2.map((e34) => t2.get(e34)).filter((e34) => e34 !== undefined))];
return c2.length >= 2 ? [c2[0], c2[1]] : undefined;
};
var fD = (e33, t2, n2, o2, i2) => {
if (CO(n2) !== "pcb_trace_error")
return;
const r2 = gD(n2, o2);
if (!r2)
return;
const s2 = n2.worst_contact_center ?? n2.center;
if (!s2 || typeof s2 != "object")
return;
const a2 = s2;
if (typeof a2.x != "number" || typeof a2.y != "number")
return;
const c2 = { x: a2.x, y: a2.y }, l2 = DO(t2), h2 = Rk(l2, c2, r2[0]), d2 = Rk(l2, c2, r2[1]);
if (!h2 || !d2 || h2.z !== d2.z)
return;
const u2 = kk(h2, d2), p2 = u2.leftPoint.x - u2.rightPoint.x, m2 = u2.leftPoint.y - u2.rightPoint.y, g2 = Math.hypot(p2, m2), f2 = Number(n2.minimum_clearance), _2 = Number.isFinite(f2) ? f2 : WA.traceClearance, y2 = h2.radius + d2.radius + _2 - g2;
if (y2 <= KM)
return;
const b2 = i2 === 0 ? h2 : d2, x2 = i2 === 0 ? u2.leftT : u2.rightT, v2 = (1 - x2) ** 2 + x2 ** 2;
if (v2 <= KM)
return;
const I2 = y2 / v2, S2 = i2 === 0 ? u2.leftPoint : u2.rightPoint, C2 = i2 === 0 ? u2.rightPoint : u2.leftPoint, P2 = i2 === 0 ? 1 : -1, M2 = b2.end.x - b2.start.x, w2 = b2.end.y - b2.start.y, N2 = Math.hypot(M2, w2), T2 = (b2.routeIndex + (i2 === 0 ? d2.routeIndex : h2.routeIndex)) % 2 == 0 ? 1 : -1, R2 = g2 > KM ? (S2.x - C2.x) / g2 : N2 > KM ? -w2 / N2 * T2 * P2 : P2, E2 = g2 > KM ? (S2.y - C2.y) / g2 : N2 > KM ? M2 / N2 * T2 * P2 : 0;
return Dk(t2, b2, R2 * I2, E2 * I2, e33, x2) ? { movedRouteIndex: b2.routeIndex } : undefined;
};
var _D = (e33) => {
const { srj: t2, via: n2, segment: o2, segments: i2, initialTarget: r2, requiredTraceDistance: s2, requiredObstacleDistance: a2, connMap: c2 } = e33, l2 = Math.min(...n2.zLayers), h2 = Math.max(...n2.zLayers), d2 = t2.obstacles.filter((e34) => !e34.isCopperPour && !QA(n2.rootConnectionName, e34, c2) && FO(e34, t2.layerCount).some((e35) => e35 >= l2 && e35 <= h2)), u2 = d2.filter((e34) => Boolean(GO(r2, e34, a2))), p2 = [r2, ...yO(n2, i2, s2 - n2.radius - o2.radius, c2), ...u2.flatMap((e34) => ((e35) => {
const { point: t3, obstacle: n3, requiredDistance: o3 } = e35, i3 = n3.center.x - n3.width / 2, r3 = n3.center.x + n3.width / 2, s3 = n3.center.y - n3.height / 2, a3 = n3.center.y + n3.height / 2, c3 = Math.max(i3 - t3.x, t3.x - r3, 0), l3 = Math.max(s3 - t3.y, t3.y - a3, 0), h3 = [];
if (c3 < o3) {
const e36 = Math.sqrt(o3 * o3 - c3 * c3);
h3.push({ x: t3.x, y: s3 - e36 - KM }, { x: t3.x, y: a3 + e36 + KM });
}
if (l3 < o3) {
const e36 = Math.sqrt(o3 * o3 - l3 * l3);
h3.push({ x: i3 - e36 - KM, y: t3.y }, { x: r3 + e36 + KM, y: t3.y });
}
return h3;
})({ point: r2, obstacle: e34, requiredDistance: a2 }))];
return p2.filter((e34) => {
if (!hD(e34, n2.radius, t2.bounds))
return false;
const r3 = YO(e34, o2);
return !(Math.hypot(e34.x - r3.x, e34.y - r3.y) < s2 - KM) && (!i2.some((t3) => t3.z >= l2 && t3.z <= h2 && !JA(n2.rootConnectionName, t3.rootConnectionName, c2) && xt(e34, t3.start, t3.end) < s2 + t3.radius - o2.radius - KM) && d2.every((t3) => XO(e34, t3) >= a2 - KM));
}).sort((e34, t3) => Math.hypot(e34.x - n2.x, e34.y - n2.y) - Math.hypot(t3.x - n2.x, t3.y - n2.y))[0];
};
var yD = (e33, t2, n2, o2, i2, r2) => {
if (CO(n2) !== "pcb_trace_error")
return false;
const s2 = typeof n2.pcb_trace_error_id == "string" ? n2.pcb_trace_error_id.toLowerCase() : "", a2 = typeof n2.message == "string" ? n2.message.toLowerCase() : "";
if (!(typeof n2.pcb_via_id == "string" || Array.isArray(n2.pcb_via_ids) || s2.includes("_via_") || a2.includes("via")))
return false;
if (rD(n2, o2) !== i2)
return false;
if (gD(n2, o2))
return false;
const c2 = n2.worst_contact_center ?? n2.center;
if (!c2 || typeof c2 != "object")
return false;
const l2 = c2;
if (typeof l2.x != "number" || typeof l2.y != "number")
return false;
const h2 = { x: l2.x, y: l2.y }, d2 = DO(t2), u2 = Rk(d2, h2, i2), p2 = Array.isArray(n2.pcb_trace_ids) ? n2.pcb_trace_ids.filter((e34) => typeof e34 == "string" && e34 !== n2.pcb_trace_id) : [], m2 = p2.map((e34) => o2.get(e34)).filter((e34) => e34 !== undefined), g2 = OO(t2, e33), f2 = Ek(p2.length > 0 ? g2.filter((e34) => m2.includes(e34.routeIndex)) : g2, h2);
if (!u2 || !f2 || !f2.movable || JA(f2.rootConnectionName, u2.rootConnectionName, r2))
return false;
const _2 = YO(f2, u2), y2 = f2.x - _2.x, b2 = f2.y - _2.y, x2 = Math.hypot(y2, b2), v2 = Number(n2.minimum_clearance), I2 = Number.isFinite(v2) ? v2 : WA.traceClearance, S2 = f2.radius + u2.radius + I2 - x2;
if (S2 <= KM)
return false;
const C2 = u2.end.x - u2.start.x, P2 = u2.end.y - u2.start.y, M2 = Math.hypot(C2, P2), w2 = f2.routeIndex % 2 == 0 ? 1 : -1, N2 = x2 > KM ? y2 / x2 : M2 > KM ? -P2 / M2 * w2 : 1, T2 = x2 > KM ? b2 / x2 : M2 > KM ? C2 / M2 * w2 : 0, R2 = f2.radius + u2.radius + I2, E2 = f2.radius + rw(e33) + ow, A2 = { x: f2.x + N2 * (S2 + ow), y: f2.y + T2 * (S2 + ow) }, O2 = _D({ srj: e33, via: f2, segment: u2, segments: d2, initialTarget: A2, requiredTraceDistance: R2, requiredObstacleDistance: E2, connMap: r2 });
return !!O2 && wk(t2, f2, O2.x - f2.x, O2.y - f2.y, e33);
};
var bD = (e33, t2, n2) => {
if (CO(t2) !== "pcb_trace_error")
return;
const o2 = qk(t2), i2 = e33[n2];
if (!o2 || !i2)
return;
const r2 = Rk(kO(i2, n2), o2);
return r2 ? { center: o2, route: i2, segment: r2 } : undefined;
};
var xD = (e33, t2, n2, o2) => {
const i2 = bD(e33, t2, n2);
if (!i2)
return;
const { route: r2, segment: s2 } = i2, a2 = Math.max(0, s2.startIndex - o2), c2 = Math.min(r2.route.length - 1, s2.endIndex + o2), l2 = r2.route.slice(a2, c2 + 1), h2 = l2[0], d2 = l2.at(-1);
return h2 && d2 && !l2.some((e34) => e34.z !== h2.z) && h2.z === d2.z ? { route: r2, spanStartIndex: a2, spanEndIndex: c2, start: h2, end: d2 } : undefined;
};
var vD = (e33, t2, n2, o2, i2, r2, s2 = 0, a2, c2) => {
if (r2 < 0 || r2 >= e33.layerCount)
return false;
const l2 = gD(n2, o2);
if (!l2)
return false;
const h2 = l2[i2], d2 = bD(t2, n2, h2);
if (!d2 || d2.segment.z === r2)
return false;
const { route: u2, segment: p2 } = d2;
let { startIndex: m2, endIndex: g2 } = p2;
for (let e34 = 0;e34 < s2; e34 += 1) {
const e35 = u2.route[m2 - 1];
e35?.z === p2.z && (m2 -= 1);
const t3 = u2.route[g2 + 1];
t3?.z === p2.z && (g2 += 1);
}
if (m2 === 0 && u2.route[0]?.pcb_port_id && !sD(e33, u2, u2.route[0], a2, c2) || g2 === u2.route.length - 1 && u2.route.at(-1)?.pcb_port_id && !sD(e33, u2, u2.route.at(-1), a2, c2))
return false;
const f2 = u2.route[m2], _2 = u2.route[g2];
if (!f2 || !_2 || f2.z !== _2.z)
return false;
const y2 = u2.route.slice(m2, g2 + 1).map((e34) => ({ ...e34, z: r2, pcb_port_id: undefined }));
return u2.route.splice(m2, g2 - m2 + 1, { ...f2 }, ...y2, { ..._2 }), true;
};
var ID = (e33, t2, n2, o2, i2, r2) => {
if (o2 <= 0 || i2 <= 0)
return false;
const s2 = bD(e33, t2, n2);
if (!s2)
return false;
const { center: a2, route: c2, segment: l2 } = s2, h2 = l2.end.x - l2.start.x, d2 = l2.end.y - l2.start.y, u2 = Math.hypot(h2, d2);
if (u2 <= KM)
return false;
const p2 = YO(a2, l2), m2 = KA(p2.t - o2 / u2, 0.02, 0.98), g2 = KA(p2.t + o2 / u2, 0.02, 0.98);
if (m2 >= g2)
return false;
const f2 = (e34) => ({ x: l2.start.x + h2 * e34, y: l2.start.y + d2 * e34, z: l2.z }), _2 = f2(m2), y2 = f2(g2), b2 = -d2 / u2 * r2, x2 = h2 / u2 * r2, v2 = c2.route[l2.startIndex], I2 = c2.route[l2.endIndex];
return c2.route.splice(l2.startIndex, 2, { ...v2 }, _2, { ..._2, x: _2.x + b2 * i2, y: _2.y + x2 * i2 }, { ...y2, x: y2.x + b2 * i2, y: y2.y + x2 * i2 }, y2, { ...I2 }), true;
};
var SD = (e33, t2, n2, o2, i2, r2, s2, a2 = false) => {
if (!Number.isInteger(i2) || i2 < 0 || i2 >= e33.layerCount)
return false;
const c2 = qk(n2), l2 = t2[o2], h2 = l2?.route[0], d2 = l2?.route.at(-1);
if (!l2 || !c2 || !h2 || !d2 || h2.z !== d2.z || h2.z === i2 || l2.jumpers?.length || l2.route.some((e34) => e34.z !== h2.z || e34.toNextSegmentType === "through_obstacle"))
return false;
const u2 = d2.x - h2.x, p2 = d2.y - h2.y, m2 = Math.hypot(u2, p2);
if (m2 <= KM || m2 > 8)
return false;
const g2 = u2 / m2, f2 = p2 / m2, _2 = f2 * r2, y2 = -g2 * r2, b2 = (e34) => (e34.x - c2.x) * g2 + (e34.y - c2.y) * f2, x2 = (e34, t3, n3) => ({ x: c2.x + g2 * e34 + _2 * t3, y: c2.y + f2 * e34 + y2 * t3, z: n3 }), v2 = (l2.viaDiameter ?? e33.minViaDiameter ?? 0.3) + (e33.minTraceToPadEdgeClearance ?? WA.traceClearance ?? 0.1), I2 = (a2 ? 1.25 : -0.75) * v2, S2 = (a2 ? -0.75 : 1.25) * v2, C2 = b2(h2) + 0.5 * v2 * s2, P2 = b2(d2) + v2 * s2, M2 = x2(C2, I2, h2.z), w2 = x2(P2, S2, h2.z), N2 = x2(C2, 2 * v2, i2), T2 = x2(P2, 2 * v2, i2), R2 = [{ ...h2 }, M2, { ...M2, z: i2 }, N2, T2, { ...w2, z: i2 }, w2, { ...d2 }], E2 = e33.minBoardEdgeClearance ?? 0, A2 = (l2.viaDiameter ?? e33.minViaDiameter ?? 0.3) / 2, O2 = l2.traceThickness / 2;
if ([M2, w2].some((t3) => ik(e33, t3) + ew < A2 + E2))
return false;
for (let t3 = 0;t3 < R2.length - 1; t3 += 1) {
const n3 = R2[t3], o3 = R2[t3 + 1];
if (n3.z === o3.z && rk(e33, n3, o3) + ew < O2 + E2)
return false;
}
return l2.route.splice(0, l2.route.length, ...R2), true;
};
var CD = (e33, t2, n2, o2, i2, r2, s2) => {
if (!Number.isInteger(i2) || i2 < 1 || r2 <= 0)
return false;
const a2 = xD(t2, n2, o2, i2);
if (!a2)
return false;
const { route: c2, spanStartIndex: l2, spanEndIndex: h2, start: d2, end: u2 } = a2, p2 = u2.x - d2.x, m2 = u2.y - d2.y, g2 = Math.hypot(p2, m2);
if (g2 <= KM)
return false;
const f2 = -m2 / g2 * s2 * r2, _2 = p2 / g2 * s2 * r2, y2 = { ...d2, x: d2.x + f2, y: d2.y + _2, pcb_port_id: undefined }, b2 = { ...u2, x: u2.x + f2, y: u2.y + _2, pcb_port_id: undefined };
return !(!JO(y2, e33.bounds) || !JO(b2, e33.bounds)) && (c2.route.splice(l2, h2 - l2 + 1, { ...d2 }, y2, b2, { ...u2 }), true);
};
var PD = (e33, t2, n2, o2, i2, r2) => {
if (!Number.isInteger(i2) || i2 < 0)
return false;
const s2 = xD(t2, n2, o2, i2);
if (!s2)
return false;
const { route: a2, spanStartIndex: c2, spanEndIndex: l2, start: h2, end: d2 } = s2;
return !(Math.hypot(r2.x - h2.x, r2.y - h2.y) <= KM || Math.hypot(r2.x - d2.x, r2.y - d2.y) <= KM || !JO(r2, e33.bounds)) && (a2.route.splice(c2, l2 - c2 + 1, { ...h2 }, { x: r2.x, y: r2.y, z: h2.z }, { ...d2 }), true);
};
var MD = (e33, t2, n2, o2, i2, r2) => {
if (r2) {
const t3 = eD(e33), n3 = eD(r2);
if (t3 !== n3)
return t3 < n3;
}
const s2 = tD(e33), a2 = nD(e33);
return s2 < n2 || s2 === n2 && a2 < o2 || s2 === n2 && t2 < i2;
};
var wD = (e33, t2, n2, o2, i2, r2, s2 = true, a2 = false, c2 = true, l2 = false) => {
let h2 = false;
for (const d2 of n2) {
const n3 = OO(t2, e33), u2 = DO(t2), p2 = qk(d2);
if (!p2)
continue;
let m2 = p2;
const g2 = d2.pcb_via_ids, f2 = CO(d2) === "pcb_via_clearance_error", _2 = Qk(d2), y2 = Array.isArray(g2) && g2.length > 0, b2 = !f2 && !_2 && y2 && (typeof d2.pcb_trace_id == "string" || Array.isArray(d2.pcb_trace_ids)), x2 = l2 && b2;
if (y2 && !b2) {
m2 = UO(e33, d2, p2);
const c3 = rD(d2, o2), l3 = g2.length > 1 ? Ak(n3, p2) : undefined;
if (l3) {
const n4 = a2 && CO(d2) === "pcb_via_clearance_error" && d2.pcb_via_pair_net_relation === "same_net", o3 = s2 && CO(d2) === "pcb_via_clearance_error";
h2 = (n4 ? zk(t2, l3[0], l3[1], e33, r2) : Lk(t2, l3[0], l3[1], e33, r2, 0.16 * Math.abs(i2), o3)) || h2;
} else {
const o3 = Ek(n3, p2, c3);
o3 && (h2 = Ok(t2, o3, m2, e33) || h2);
}
continue;
}
const v2 = d2.pcb_trace_id, I2 = rD(d2, o2);
if (x2 && I2 === undefined)
continue;
const S2 = Array.isArray(d2.pcb_trace_ids) ? d2.pcb_trace_ids.filter((e34) => typeof e34 == "string") : [];
if (x2 && typeof v2 == "string" && I2 !== undefined && S2.includes(v2) && S2.some((e34) => e34 !== v2 && !o2.has(e34))) {
const o3 = Ek(n3, p2, I2);
if (o3) {
h2 = Ok(t2, o3, p2, e33) || h2;
continue;
}
}
const C2 = s2 && !b2 ? gD(d2, o2) : undefined;
if (C2) {
const n4 = Rk(u2, p2, C2[0]), o3 = Rk(u2, p2, C2[1]);
if (n4 && o3 && Fk(t2, n4, o3, e33, r2)) {
h2 = true;
continue;
}
}
const P2 = PO(d2), M2 = P2 && I2 !== undefined ? $k(e33, t2, I2, p2, r2) : undefined, w2 = P2 ? M2?.segment : Rk(u2, p2, I2);
if (w2) {
const o3 = P2 ? M2?.obstacle : HO(e33, p2);
if (P2 && !o3)
continue;
m2 = P2 ? o3?.center ?? p2 : UO(e33, d2, p2);
const s3 = x2 ? undefined : Ek(n3, p2), a3 = CO(d2) === "pcb_via_trace_clearance_error", l3 = typeof d2.pcb_trace_error_id == "string" ? d2.pcb_trace_error_id.toLowerCase() : "", u3 = typeof d2.message == "string" ? d2.message.toLowerCase() : "", g3 = a3 || typeof d2.pcb_via_id == "string" || Array.isArray(d2.pcb_via_ids) || l3.includes("_via_") || u3.includes("via"), f3 = Array.isArray(d2.pcb_port_ids) && d2.pcb_port_ids.length > 0;
if (s3 && !JA(s3.rootConnectionName, w2.rootConnectionName, r2) && (a3 || Math.hypot(s3.x - p2.x, s3.y - p2.y) < 0.45)) {
if (Bk(t2, s3, w2, e33, r2, 0.3 * Math.abs(i2), 1, c2) && (h2 = true, g3 && !f3))
continue;
}
h2 = (o3 !== undefined && (P2 || !QA(w2.rootConnectionName, o3, r2) && jk(o3, w2, e33.layerCount)) ? Tk(t2, w2, o3, e33, r2, i2) : Nk(t2, w2, m2, e33, i2)) || h2;
}
const N2 = x2 ? undefined : Ek(OO(t2, e33), p2);
N2 && Math.hypot(N2.x - p2.x, N2.y - p2.y) < 0.35 && (h2 = Ok(t2, N2, m2, e33) || h2);
}
return h2;
};
var ND = 0.000001;
var TD = 0.006;
var RD = [1, 0.5, 0.25, 0.1, 0.05, 0.025];
var ED = (e33, t2) => (t2.traceThickness ?? e33.minTraceWidth) / 2;
var AD = (e33) => e33.minTraceToPadEdgeClearance ?? 0.1;
var OD = (e33, t2) => t2.viaDiameter ?? e33.minViaDiameter ?? 0.3;
var kD = (e33, t2) => vt(e33, t2) < ND;
var DD = (e33) => {
const t2 = [], n2 = (e34) => {
t2.some((t3) => kD(t3, e34)) || t2.push({ x: e34.x, y: e34.y });
};
for (const t3 of e33.vias)
n2(t3);
for (let t3 = 0;t3 < e33.route.length - 1; t3 += 1) {
const o2 = e33.route[t3], i2 = e33.route[t3 + 1];
o2 && i2 && o2.z !== i2.z && (kD(o2, i2) && n2(o2));
}
return t2;
};
var LD = (e33) => vt({ x: 0, y: 0 }, e33) < ND ? { x: 0, y: 0 } : Ft({ x: 0, y: 0 }, e33);
var zD = (e33, t2) => {
if (e33.zLayers && e33.zLayers.length > 0)
return e33.zLayers;
const n2 = Array.from({ length: t2 }, (e34, t3) => t3).filter((n3) => e33.layers.includes(EM(n3, t2)));
return n2.length > 0 ? n2 : Array.from({ length: t2 }, (e34, t3) => t3);
};
var BD = (e33, t2, n2) => JA(ZA(e33), ZA(t2), n2) || JA(ZA(e33), t2.connectionName, n2) || JA(e33.connectionName, ZA(t2), n2) || JA(e33.connectionName, t2.connectionName, n2);
var FD = (e33, t2, n2) => QA(ZA(e33), t2, n2) || QA(e33.connectionName, t2, n2);
var jD = (e33, t2, n2, o2) => !n2.pcb_port_id && e33.obstacles.some((i2) => FD(t2, i2, o2) && zD(i2, e33.layerCount).includes(n2.z) && ((e34, t3) => e34.x >= t3.center.x - t3.width / 2 - ND && e34.x <= t3.center.x + t3.width / 2 + ND && e34.y >= t3.center.y - t3.height / 2 - ND && e34.y <= t3.center.y + t3.height / 2 + ND)(n2, i2));
var $D = (e33, t2, n2, o2, i2) => {
if (!((e34, t3) => e34.zLayers.includes(t3))(i2, n2.z))
return Number.POSITIVE_INFINITY;
const r2 = ED(e33, t2);
return i2.kind === "pad" ? Lt(n2, o2, i2.obstacle) - (AD(e33) + r2 + TD) : xt(i2.center, n2, o2) - (AD(e33) + r2 + i2.diameter / 2 + TD);
};
var YD = (e33, t2, n2) => {
const o2 = n2.kind === "pad" ? n2.obstacle.center : n2.center, i2 = Bt(o2, e33, t2);
let r2 = LD({ x: i2.x - o2.x, y: i2.y - o2.y });
if (Math.abs(r2.x) < ND && Math.abs(r2.y) < ND) {
const n3 = t2.x - e33.x, i3 = t2.y - e33.y, s2 = Yt(e33, t2), a2 = LD({ x: -i3, y: n3 }), c2 = { x: -a2.x, y: -a2.y };
r2 = vt({ x: s2.x + a2.x, y: s2.y + a2.y }, o2) >= vt({ x: s2.x + c2.x, y: s2.y + c2.y }, o2) ? a2 : c2;
}
return r2;
};
var XD = (e33, t2, n2, o2) => {
if (n2 <= 0 || n2 >= t2.route.length - 1) {
const i3 = t2.route[n2];
return !i3 || !jD(e33, t2, i3, o2);
}
const i2 = t2.route[n2];
if (!i2 || i2.insideJumperPad)
return true;
const r2 = t2.route[n2 - 1], s2 = t2.route[n2 + 1];
return !(!r2 || r2.z === i2.z) || (!(!s2 || s2.z === i2.z) || t2.vias.some((e34) => kD(e34, i2)));
};
var WD = (e33, t2, n2) => {
let o2 = 0;
for (let i2 = 0;i2 < t2.route.length - 1; i2 += 1) {
const r2 = t2.route[i2], s2 = t2.route[i2 + 1];
if (r2 && s2 && r2.z === s2.z && !kD(r2, s2))
for (const i3 of n2) {
const n3 = $D(e33, t2, r2, s2, i3);
if (!(n3 >= 0) && (o2 += n3 * n3, i3.kind === "pad")) {
if (Lt(r2, s2, i3.obstacle) < ND) {
o2 += 0.01 / (xt(i3.obstacle.center, r2, s2) + 0.01);
}
}
}
}
return o2;
};
var VD = (e33, t2, n2, o2) => {
let i2 = 0;
for (let r2 = 0;r2 < t2.route.length - 1; r2 += 1) {
const s2 = t2.route[r2], a2 = t2.route[r2 + 1];
if (s2 && a2 && s2.z === a2.z && !kD(s2, a2)) {
for (const r3 of n2)
if (!BD(t2, r3, o2)) {
for (let n3 = 0;n3 < r3.route.length - 1; n3 += 1) {
const o3 = r3.route[n3], c2 = r3.route[n3 + 1];
if (!o3 || !c2 || o3.z !== s2.z || c2.z !== s2.z || kD(o3, c2))
continue;
const l2 = kt(s2, a2, o3, c2) - ED(e33, t2) - ED(e33, r3), h2 = AD(e33) + TD - l2;
h2 > 0 && (i2 += h2 * h2);
}
for (const n3 of DD(r3)) {
const o3 = xt(n3, s2, a2) - ED(e33, t2) - OD(e33, r3) / 2, c2 = AD(e33) + TD - o3;
c2 > 0 && (i2 += c2 * c2);
}
}
}
}
return i2;
};
var HD = (e33, t2, n2, o2, i2) => {
const r2 = t2.route.map(() => ({ x: 0, y: 0 }));
for (let s2 = 0;s2 < t2.route.length - 1; s2 += 1) {
const a2 = t2.route[s2], c2 = t2.route[s2 + 1];
if (a2 && c2 && a2.z === c2.z && !kD(a2, c2)) {
for (const o3 of n2) {
const n3 = $D(e33, t2, a2, c2, o3);
if (n3 >= 0)
continue;
const l2 = YD(a2, c2, o3);
if (Math.abs(l2.x) < ND && Math.abs(l2.y) < ND)
continue;
const h2 = !XD(e33, t2, s2, i2), d2 = !XD(e33, t2, s2 + 1, i2);
if (!h2 && !d2)
continue;
const u2 = -n3, p2 = h2 && d2 ? 0.5 : h2 ? 1 : 0, m2 = h2 && d2 ? 0.5 : d2 ? 1 : 0;
r2[s2].x += l2.x * u2 * p2, r2[s2].y += l2.y * u2 * p2, r2[s2 + 1].x += l2.x * u2 * m2, r2[s2 + 1].y += l2.y * u2 * m2;
}
for (const n3 of o2)
if (!BD(t2, n3, i2))
for (let o3 = 0;o3 < n3.route.length - 1; o3 += 1) {
const l2 = n3.route[o3], h2 = n3.route[o3 + 1];
if (!l2 || !h2 || l2.z !== a2.z || h2.z !== a2.z || kD(l2, h2))
continue;
const d2 = kt(a2, c2, l2, h2) - ED(e33, t2) - ED(e33, n3), u2 = e33.minTraceToPadEdgeClearance + TD - d2;
if (u2 <= 0)
continue;
const p2 = Yt(a2, c2), m2 = Bt(p2, l2, h2);
let g2 = LD({ x: p2.x - m2.x, y: p2.y - m2.y });
if (Math.abs(g2.x) < ND && Math.abs(g2.y) < ND) {
const e34 = c2.x - a2.x, t3 = c2.y - a2.y;
g2 = LD({ x: -t3, y: e34 });
}
const f2 = !XD(e33, t2, s2, i2), _2 = !XD(e33, t2, s2 + 1, i2);
if (!f2 && !_2)
continue;
const y2 = f2 && _2 ? 0.5 : f2 ? 1 : 0, b2 = f2 && _2 ? 0.5 : _2 ? 1 : 0;
r2[s2].x += g2.x * u2 * y2, r2[s2].y += g2.y * u2 * y2, r2[s2 + 1].x += g2.x * u2 * b2, r2[s2 + 1].y += g2.y * u2 * b2;
}
}
}
return r2;
};
var GD = (e33, t2, n2, o2, i2) => ({ ...t2, route: t2.route.map((r2, s2) => {
if (XD(e33, t2, s2, i2))
return { ...r2 };
const a2 = ((e34, t3) => {
const n3 = vt({ x: 0, y: 0 }, e34);
if (n3 <= t3 || n3 < ND)
return e34;
const o3 = t3 / n3;
return { x: e34.x * o3, y: e34.y * o3 };
})(n2[s2] ?? { x: 0, y: 0 }, 0.5);
return { ...r2, x: r2.x + a2.x * o2, y: r2.y + a2.y * o2 };
}), vias: t2.vias.map((e34) => ({ ...e34 })), jumpers: t2.jumpers ? [...t2.jumpers] : undefined });
var UD = (e33, t2) => t2.route.every((t3) => t3.x >= e33.bounds.minX - ND && t3.x <= e33.bounds.maxX + ND && t3.y >= e33.bounds.minY - ND && t3.y <= e33.bounds.maxY + ND);
var ZD = (e33, t2, n2, o2, i2) => {
const r2 = ((e34, t3, n3, o3) => {
const i3 = [];
for (const t4 of e34.obstacles)
t4.isCopperPour || FD(n3, t4, o3) || i3.push({ kind: "pad", obstacle: t4, zLayers: zD(t4, e34.layerCount) });
const r3 = Array.from({ length: e34.layerCount }, (e35, t4) => t4);
for (const s3 of t3)
if (s3 !== n3 && !BD(n3, s3, o3))
for (const t4 of DD(s3))
i3.push({ kind: "via", center: { x: t4.x, y: t4.y }, diameter: OD(e34, s3), zLayers: r3, connectionName: s3.connectionName, rootConnectionName: s3.rootConnectionName });
return i3;
})(e33, t2, n2, i2), s2 = t2.filter((e34, t3) => t3 !== o2 && e34 !== n2);
let a2 = n2, c2 = WD(e33, a2, r2) + VD(e33, a2, s2, i2);
for (let t3 = 0;t3 < 160 && !(c2 <= ND); t3 += 1) {
const t4 = HD(e33, a2, r2, s2, i2);
if (t4.every((e34) => vt(e34, { x: 0, y: 0 }) < 0.000000001))
break;
let n3 = null, o3 = c2;
for (const l2 of RD) {
const h2 = GD(e33, a2, t4, l2, i2), d2 = WD(e33, h2, r2) + VD(e33, h2, s2, i2);
if (d2 < c2 - 0.000001 && UD(e33, h2)) {
n3 = h2, o3 = d2;
break;
}
}
if (!n3)
break;
a2 = n3, c2 = o3;
}
return a2;
};
var qD = 0.000001;
var JD = [1, 0.5, 0.25, 0.1, 0.05, 0.025];
var QD = (e33, t2) => e33.some((e34) => t2.includes(e34));
var KD = (e33, t2, n2, o2) => (QA(e33.rootConnectionName, n2, o2) || QA(t2.connectionName, n2, o2)) && XO(e33, n2) <= qD;
var eL = (e33, t2, n2, o2) => {
const i2 = [], r2 = t2[n2.routeIndex];
if (!r2)
return i2;
for (const t3 of e33.obstacles) {
if (t3.isCopperPour || KD(n2, r2, t3, o2))
continue;
const s2 = FO(t3, e33.layerCount);
QD(n2.zLayers, s2) && i2.push({ obstacle: t3 });
}
return i2;
};
var tL = (e33, t2, n2) => XO(t2, n2.obstacle) - (t2.radius + e33.minViaEdgeToPadEdgeClearance + 0.006);
var nL = (e33, t2, n2, o2) => OO(t2, e33).filter((e34) => e34.routeIndex === n2).reduce((n3, i2) => n3 + ((e34, t3, n4, o3) => {
let i3 = 0;
for (const r2 of eL(e34, t3, n4, o3)) {
const t4 = tL(e34, n4, r2);
!(t4 >= 0) && (i3 += t4 * t4, XO(n4, r2.obstacle) < qD) && (i3 += 0.01 / (vt(n4, r2.obstacle.center) + 0.01));
}
return i3;
})(e33, t2, i2, o2), 0);
var oL = (e33, t2, n2, o2) => {
const i2 = t2[n2];
if (!i2)
return [];
const r2 = i2.route.map(() => ({ x: 0, y: 0 })), s2 = OO(t2, e33).filter((e34) => e34.routeIndex === n2);
for (const n3 of s2)
if (n3.movable)
for (const i3 of eL(e33, t2, n3, o2)) {
const t3 = n3.radius + e33.minViaEdgeToPadEdgeClearance + 0.006, o3 = GO(n3, i3.obstacle, t3);
if (o3)
for (const e34 of n3.pointIndexes)
r2[e34].x += o3.direction.x * o3.penetration, r2[e34].y += o3.direction.y * o3.penetration;
}
return r2;
};
var iL = (e33, t2, n2, o2) => {
const i2 = new Set(OO([t2], e33).flatMap((e34) => e34.movable ? e34.pointIndexes : []));
return { ...t2, route: t2.route.map((e34, t3) => {
if (!i2.has(t3))
return { ...e34 };
const r2 = ((e35, t4) => {
const n3 = vt({ x: 0, y: 0 }, e35);
if (n3 <= t4 || n3 < qD)
return e35;
const o3 = t4 / n3;
return { x: e35.x * o3, y: e35.y * o3 };
})(n2[t3] ?? { x: 0, y: 0 }, 0.5);
return { ...e34, x: e34.x + r2.x * o2, y: e34.y + r2.y * o2 };
}), vias: t2.vias.map((e34) => ({ ...e34 })), jumpers: t2.jumpers ? [...t2.jumpers] : undefined };
};
var rL = (e33, t2) => t2.route.every((t3) => t3.x >= e33.bounds.minX - qD && t3.x <= e33.bounds.maxX + qD && t3.y >= e33.bounds.minY - qD && t3.y <= e33.bounds.maxY + qD);
var sL = (e33, t2, n2, o2, i2) => {
let r2 = n2, s2 = nL(e33, t2, o2, i2);
for (let n3 = 0;n3 < 160 && !(s2 <= qD); n3 += 1) {
const n4 = oL(e33, t2, o2, i2);
if (n4.every((e34) => vt(e34, { x: 0, y: 0 }) < 0.000000001))
break;
let a2 = null, c2 = s2;
for (const l2 of JD) {
const h2 = iL(e33, r2, n4, l2), d2 = [...t2];
d2[o2] = h2;
const u2 = nL(e33, d2, o2, i2);
if (u2 < s2 - 0.000001 && rL(e33, h2)) {
a2 = h2, c2 = u2;
break;
}
}
if (!a2)
break;
t2[o2] = a2, r2 = a2, s2 = c2;
}
return r2;
};
var aL = [0.2, 0.4, 0.8, 1.2].flatMap((e33) => [0.2, 0.3, 0.45, 0.6].flatMap((t2) => [-1, 1].map((n2) => ({ halfSpan: e33, offset: t2, directionSign: n2 })))).flatMap((e33) => [0, 1].map((t2) => ({ kind: "segment", routeSide: t2, ...e33 })));
var cL = [1, -1].flatMap((e33) => [1, -1].flatMap((t2) => [false, true].flatMap((n2) => [0, 1].map((o2) => ({ routeSide: o2, normalDirectionSign: e33, tangentDirectionSign: t2, reverseEndpointOffsets: n2 })))));
var lL = [0, 1].map((e33) => ({ kind: "displacementChain", routeSide: e33 }));
var hL = [...lL, ...[-1, 1].flatMap((e33) => [0, 1].map((t2) => ({ kind: "segment", routeSide: t2, halfSpan: 0.4, offset: 1.2, directionSign: e33 }))), ...[-1, 1].flatMap((e33) => [0, 1].map((t2) => ({ kind: "span", routeSide: t2, spanExpansion: 3, offset: 1.8, directionSign: e33 }))), ...[{ dx: -2.4, dy: -0.4 }, { dx: -2.4, dy: 0.4 }, { dx: 2.4, dy: -0.4 }, { dx: 2.4, dy: 0.4 }, { dx: -0.4, dy: -2.4 }, { dx: -0.4, dy: 2.4 }, { dx: 0.4, dy: -2.4 }, { dx: 0.4, dy: 2.4 }].flatMap((e33) => [0, 1].map((t2) => ({ kind: "waypoint", routeSide: t2, spanExpansion: 2, ...e33 }))), ...[{ dx: -0.17, dy: 0 }, { dx: 0.17, dy: 0 }, { dx: 0, dy: -0.17 }, { dx: 0, dy: 0.17 }].flatMap((e33) => [0, 1].map((t2) => ({ kind: "waypoint", routeSide: t2, spanExpansion: 0, ...e33 }))), ...aL];
var dL = [0, 1, 2];
var uL = class extends De {
srj;
inputHdRoutes;
guardedInputHdRoutes;
connMap;
effort;
drcEvaluator;
referenceDrcEvaluator;
autoroutingDrcEngine;
viaHoleDiameter;
configuredMaxIterations;
enableBroadFallback;
enableLargeBoardBroadFallback;
enableTargetedErrorSweep;
enablePostSolveClearanceRelaxation;
enableSafeTraceLayerMoves;
enableViaInPadLayerMoves;
enableTraceViaOwnerTargeting;
outputHdRoutes;
initialDrcIssueCount;
initialRepairDrcIssueCount;
initialLowCountErrorsHaveMovableTraces = false;
broadForceAccepted = false;
targetedForceAccepted = false;
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 = false;
referenceInputDrcIssueCount;
referenceCandidateDrcIssueCount;
referenceCandidateRolledBack = false;
referenceInputSnapshot;
inputSnapshot;
constructor(e33) {
if (super(), this.srj = e33.srj, this.inputHdRoutes = e33.hdRoutes, this.guardedInputHdRoutes = Gk(xO(e33.hdRoutes)), this.connMap = e33.connMap, this.effort = e33.effort ?? 1, this.drcEvaluator = e33.drcEvaluator, this.referenceDrcEvaluator = e33.referenceDrcEvaluator, this.autoroutingDrcEngine = e33.autoroutingDrcEngine ?? (e33.drcEvaluator ? undefined : new UM(e33.srj, { connMap: e33.connMap, traceClearance: e33.srj.minTraceToPadEdgeClearance ?? WA.traceClearance, viaClearance: e33.srj.minTraceToPadEdgeClearance ?? WA.viaClearance, includeTraceViaOwnerMetadata: e33.enableTraceViaOwnerTargeting ?? false })), e33.viaHoleDiameter !== undefined && (!Number.isFinite(e33.viaHoleDiameter) || e33.viaHoleDiameter <= 0))
throw new Error("viaHoleDiameter must be a positive finite number");
this.viaHoleDiameter = e33.viaHoleDiameter, this.configuredMaxIterations = e33.maxIterations, this.enableBroadFallback = e33.enableBroadFallback ?? true, this.enableLargeBoardBroadFallback = e33.enableLargeBoardBroadFallback ?? true, this.enableTargetedErrorSweep = e33.enableTargetedErrorSweep ?? false, this.enablePostSolveClearanceRelaxation = e33.enablePostSolveClearanceRelaxation ?? true, this.enableSafeTraceLayerMoves = e33.enableSafeTraceLayerMoves ?? false, this.enableViaInPadLayerMoves = e33.enableViaInPadLayerMoves ?? false, this.enableTraceViaOwnerTargeting = e33.enableTraceViaOwnerTargeting ?? false, this.outputHdRoutes = e33.hdRoutes, this.referenceDrcEvaluator && (this.referenceInputSnapshot = this.getReferenceDrcSnapshot(this.inputHdRoutes)), this.MAX_ITERATIONS = this.configuredMaxIterations ?? sw(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(e33) {
this.stats = { initialDrcIssueCount: this.initialDrcIssueCount ?? e33.count, finalDrcIssueCount: e33.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 ?? e33.count, globalDrcForceImproveBestDrcIssueScoreSeen: this.bestDrcIssueScoreSeen ?? e33.issueScore, globalDrcForceImproveDrcCountPlateauChecks: this.drcCountPlateauChecks, globalDrcForceImproveLargeBoardBroadFallbackMisses: this.largeBoardBroadFallbackMisses, globalDrcForceImproveViaPadRepairRolledBack: this.viaPadRepairRolledBack, globalDrcForceImproveReferenceInputDrcIssueCount: this.referenceInputDrcIssueCount, globalDrcForceImproveReferenceCandidateDrcIssueCount: this.referenceCandidateDrcIssueCount, globalDrcForceImproveReferenceCandidateRolledBack: this.referenceCandidateRolledBack };
}
finishAtLegacyCleanCheckpoint() {
const e33 = this.legacyCleanCheckpoint;
return !!e33 && (this.outputHdRoutes = e33.routes, this.outputSnapshot = e33.snapshot, this.viaPadRepairRolledBack = true, this.updateStats(e33.snapshot), this.solved = true, true);
}
increaseMaxIterationsForDrcIssueCount(e33) {
this.configuredMaxIterations === undefined ? this.MAX_ITERATIONS = Math.max(this.MAX_ITERATIONS, ((e34, t2) => Math.max(sw(t2), Math.ceil(e34 * QM * Math.max(1, t2))))(e33, this.effort), ((e34, t2) => e34 > 120 && t2 > 0 ? 192 : 48)(this.inputHdRoutes.length, e33)) : this.MAX_ITERATIONS = this.configuredMaxIterations;
}
getSnapshot(e33) {
return (this.initialLowCountErrorsHaveMovableTraces ? AO : EO)(this.srj, e33, this.drcEvaluator, this.connMap, this.autoroutingDrcEngine);
}
getReferenceDrcSnapshot(e33) {
const t2 = { traces: [], srj: this.srj, routes: e33, hdRoutes: e33 }, n2 = this.referenceDrcEvaluator?.getCachedResult?.(t2);
if (n2) {
const e34 = Array.isArray(n2) ? n2 : n2.errors;
return { errors: e34, count: e34.length };
}
return EO(this.srj, e33, this.referenceDrcEvaluator, this.connMap, this.autoroutingDrcEngine);
}
getViaIssueCount(e33) {
return Jk(e33);
}
getRepairIssueCount(e33) {
return tD(e33);
}
getRepairIssueScore(e33) {
return nD(e33);
}
acceptSolvedRoutes(e33, t2) {
const n2 = this.enablePostSolveClearanceRelaxation ? ((e34, t3, n3) => {
if (e34.minTraceToPadEdgeClearance === undefined || e34.minTraceToPadEdgeClearance <= 0)
return t3;
let o3 = false;
const i3 = xO(t3);
for (let t4 = 0;t4 < 4; t4 += 1)
for (let t5 = 0;t5 < i3.length; t5 += 1) {
const r3 = i3[t5];
if (!r3)
continue;
const s3 = ZD(e34, i3, r3, t5, n3);
s3 !== r3 && (i3[t5] = s3, o3 = true);
}
return o3 ? i3 : t3;
})(this.srj, e33, this.connMap) : e33, o2 = this.enablePostSolveClearanceRelaxation ? ((e34, t3, n3) => {
if (e34.minViaEdgeToPadEdgeClearance === undefined || e34.minViaEdgeToPadEdgeClearance <= 0)
return t3;
let o3 = false;
const i3 = xO(t3);
for (let t4 = 0;t4 < 4; t4 += 1)
for (let t5 = 0;t5 < i3.length; t5 += 1) {
const r3 = i3[t5];
if (!r3)
continue;
const s3 = sL(e34, i3, r3, t5, n3);
s3 !== r3 && (i3[t5] = s3, o3 = true);
}
return o3 ? Gk(i3) : t3;
})(this.srj, n2, this.connMap) : e33, i2 = o2 === e33 ? t2 : this.getSnapshot(o2), r2 = i2.count < t2.count || i2.count === t2.count && i2.issueScore <= t2.issueScore;
let s2 = r2 ? o2 : e33, a2 = r2 ? i2 : t2;
const c2 = this.inputSnapshot ?? this.getSnapshot(this.guardedInputHdRoutes);
if (this.referenceDrcEvaluator) {
const e34 = this.referenceInputSnapshot, t3 = this.getReferenceDrcSnapshot(s2);
this.referenceInputDrcIssueCount = e34.count, this.referenceCandidateDrcIssueCount = t3.count, t3.count > e34.count && (s2 = this.guardedInputHdRoutes, a2 = c2, this.referenceCandidateRolledBack = true);
}
this.outputHdRoutes = s2, this.outputSnapshot = a2, this.stalledIterations = 0, this.updateStats(a2), this.solved = true;
}
updateDrcCountPlateauState(e33) {
const t2 = this.getRepairIssueCount(e33), n2 = this.getRepairIssueScore(e33);
this.bestDrcIssueCountSeen ??= t2, this.bestDrcIssueScoreSeen ??= n2;
const o2 = this.initialRepairDrcIssueCount ?? t2, i2 = this.inputHdRoutes.length > 120 && o2 > 0;
if ((o2 >= 20 || i2) && this.iterations < 192)
return (t2 < this.bestDrcIssueCountSeen || t2 === this.bestDrcIssueCountSeen && n2 < this.bestDrcIssueScoreSeen) && (this.bestDrcIssueCountSeen = t2, this.bestDrcIssueScoreSeen = n2), void (i2 && this.largeBoardBroadFallbackMisses >= 2 && (this.solved = true));
const r2 = ((e34) => e34 >= 20 ? 8 : e34 <= 2 ? 1 : 2)(o2);
if (!(this.iterations - this.lastDrcCountImprovementCheckIteration < r2)) {
if (this.lastDrcCountImprovementCheckIteration = this.iterations, t2 < this.bestDrcIssueCountSeen || t2 === this.bestDrcIssueCountSeen && n2 < this.bestDrcIssueScoreSeen)
return this.bestDrcIssueCountSeen = t2, this.bestDrcIssueScoreSeen = n2, void (this.drcCountPlateauChecks = 0);
this.drcCountPlateauChecks += 1, this.drcCountPlateauChecks >= 2 && (this.solved = true);
}
}
_step() {
let e33 = this.outputHdRoutes, t2 = this.outputSnapshot ?? this.getSnapshot(e33);
const n2 = eD(t2);
if (this.legacyCleanCheckpoint && n2 > 0)
return void this.finishAtLegacyCleanCheckpoint();
if (!this.legacyCleanCheckpoint && n2 === 0 && t2.errors.some(Qk) && (this.legacyCleanCheckpoint = { routes: Gk(xO(e33)), snapshot: t2 }), this.initialDrcIssueCount === undefined) {
this.inputSnapshot = t2, this.initialDrcIssueCount = t2.count, this.initialRepairDrcIssueCount = this.getRepairIssueCount(t2);
const n3 = iD(t2.errors);
this.initialLowCountErrorsHaveMovableTraces = this.initialRepairDrcIssueCount > 0 && this.initialRepairDrcIssueCount <= 3 && n3.every((e34) => rD(e34, t2.traceRouteIndexById) !== undefined), this.initialLowCountErrorsHaveMovableTraces && (t2 = this.getSnapshot(e33)), this.bestDrcIssueCountSeen = this.getRepairIssueCount(t2), this.bestDrcIssueScoreSeen = this.getRepairIssueScore(t2), this.increaseMaxIterationsForDrcIssueCount(this.getRepairIssueCount(t2));
}
if (t2.count === 0)
return void this.acceptSolvedRoutes(e33, t2);
let o2 = this.getRepairIssueCount(t2), i2 = this.getRepairIssueScore(t2), r2 = this.getViaIssueCount(t2);
const s2 = t2.errors.filter((e34) => Boolean(qk(e34)));
if (s2.length === 0)
return void this.acceptSolvedRoutes(e33, t2);
const a2 = (c2 = this.effort, Math.max(1, Math.round(3 * Math.max(1, c2))));
var c2;
let l2 = 0, h2 = 0, d2 = false, u2 = false, p2 = false;
const m2 = iD(s2), g2 = this.enableTargetedErrorSweep ? m2.find((e34) => e34.type === "pcb_via_clearance_error" && e34.pcb_via_pair_net_relation === "same_net") : undefined, f2 = this.enableTargetedErrorSweep && (this.iterations - 1) % 8 == 0, _2 = g2 ?? (f2 ? m2.find((e34) => e34.type === "pcb_via_clearance_error") : undefined), y2 = _2 ? [_2, ...m2.filter((e34) => e34 !== _2)] : m2, b2 = Math.min(y2.length, Math.max(1, Math.ceil(this.effort))), x2 = _2 ? 0 : this.errorCursor % y2.length, v2 = this.enableTargetedErrorSweep ? ((e34, t3) => {
const n3 = Math.max(2, Math.round(12 * Math.max(1, t3)));
return e34.filter((e35) => CO(e35) === "pcb_trace_error").slice(0, n3);
})(s2, this.effort) : [], I2 = o2 <= 1 || this.initialLowCountErrorsHaveMovableTraces, S2 = !this.initialLowCountErrorsHaveMovableTraces && o2 <= 8 && this.srj.layerCount > 1, C2 = _2 ? [] : s2.filter((e34) => e34.type === "pcb_pad_trace_clearance_error" || (this.enableSafeTraceLayerMoves || I2 || S2) && e34.type === "pcb_trace_error"), P2 = C2.map((e34, t3) => C2[(this.padTopologyErrorCursor + t3) % C2.length]);
for (const n3 of this.enableSafeTraceLayerMoves || this.enableViaInPadLayerMoves ? P2 : []) {
const s3 = !this.enableSafeTraceLayerMoves || h2 >= a2, c3 = !this.enableViaInPadLayerMoves || l2 >= a2;
if (u2 || s3 && c3)
break;
let p3;
this.padTopologyErrorCursor = (C2.indexOf(n3) + 1) % C2.length;
const m3 = typeof n3.pcb_trace_error_id == "string" ? n3.pcb_trace_error_id : typeof n3.pcb_trace_id == "string" ? n3.pcb_trace_id : undefined, g3 = rD(n3, t2.traceRouteIndexById), f3 = gD(n3, t2.traceRouteIndexById);
if (this.enableTraceViaOwnerTargeting && g3 !== undefined && Array.isArray(n3.pcb_via_ids) && n3.pcb_via_ids.length === 1 && l2 < a2) {
const o3 = xO(e33);
if (yD(this.srj, o3, n3, t2.traceRouteIndexById, g3, this.connMap)) {
const e34 = Gk(o3), n4 = this.getSnapshot(e34), i3 = this.getViaIssueCount(n4);
l2 += 1, this.candidateAttempts += 1, i3 <= r2 && oD(n4, t2) && (p3 = { routes: e34, snapshot: n4, viaIssueCount: i3, usesViaInPad: false });
}
}
if (this.enableSafeTraceLayerMoves && g3 !== undefined) {
const o3 = f3 ?? [g3], i3 = o3.length * this.srj.layerCount * dL.length, s4 = o3.length * this.srj.layerCount * lD, c4 = i3 + s4, l3 = PO(n3), d3 = l3 ? 0 : i3, u3 = l3 ? s4 : 0;
let _4 = m3 ? this.safeTraceLayerCursorByErrorId.get(m3) ?? 0 : 0, y3 = 0;
for (;h2 < a2 && y3 < c4; ) {
const i4 = _4;
_4 = (_4 + 1) % c4, y3 += 1;
const a3 = i4 >= d3 && i4 < d3 + s4, l4 = i4 - (a3 ? d3 : u3), m4 = l4 % o3.length, g4 = Math.floor(l4 / o3.length), f4 = g4 % this.srj.layerCount, b3 = a3 ? "full" : dL[Math.floor(g4 / this.srj.layerCount) % dL.length], x3 = a3 ? Math.floor(g4 / this.srj.layerCount) : 0, v3 = o3[m4];
let I3 = false;
for (const o4 of [false, true]) {
const i5 = vO(e33, [v3]);
if (!uD(this.srj, i5, n3, v3, f4, b3, this.connMap, x3, o4))
continue;
const s5 = Uk(i5, [v3]);
I3 = true, this.candidateAttempts += 1;
const a4 = this.getSnapshot(s5), c5 = this.getViaIssueCount(a4), l5 = p3?.snapshot ?? t2;
c5 <= (p3?.viaIssueCount ?? r2) && (oD(a4, l5) || p3 !== undefined && tD(a4) === tD(l5) && a4.count < l5.count) && (p3 = { routes: s5, snapshot: a4, viaIssueCount: c5, usesViaInPad: false });
}
I3 && (h2 += 1);
}
m3 && this.safeTraceLayerCursorByErrorId.set(m3, _4);
}
if (this.enableSafeTraceLayerMoves && S2 && m3 && f3) {
let o3 = this.traceLayerCorridorCursorByErrorId.get(m3) ?? 0, i3 = 0;
for (;l2 < a2 && i3 < cL.length; ) {
const s4 = cL[o3 % cL.length];
o3 += 1, i3 += 1;
const a3 = f3[s4.routeSide], c4 = e33[a3]?.route[0]?.z;
if (c4 === undefined)
continue;
const h3 = (c4 + 1) % this.srj.layerCount, d3 = vO(e33, [a3]);
if (!SD(this.srj, d3, n3, a3, h3, s4.normalDirectionSign, s4.tangentDirectionSign, s4.reverseEndpointOffsets))
continue;
const u3 = Uk(d3, [a3]);
l2 += 1, this.candidateAttempts += 1;
const m4 = this.getSnapshot(u3), g4 = this.getViaIssueCount(m4), _4 = p3?.snapshot ?? t2;
g4 <= (p3?.viaIssueCount ?? r2) && oD(m4, _4) && (p3 = { routes: u3, snapshot: m4, viaIssueCount: g4, usesViaInPad: false });
}
this.traceLayerCorridorCursorByErrorId.set(m3, o3);
}
if (this.enableSafeTraceLayerMoves && m3 && (this.initialLowCountErrorsHaveMovableTraces && (f3 || g3 !== undefined) || !this.initialLowCountErrorsHaveMovableTraces && f3)) {
const s4 = this.initialLowCountErrorsHaveMovableTraces ? hL : I2 ? [...lL, ...aL] : lL, c4 = f3 ?? [g3];
let h3 = this.tracePairDetourCursorByErrorId.get(m3) ?? 0, u3 = 0;
for (;l2 < a2 && u3 < s4.length; ) {
const m4 = s4[h3 % s4.length];
h3 += 1, u3 += 1;
const g4 = c4[m4.routeSide];
if (g4 === undefined)
continue;
const f4 = this.initialLowCountErrorsHaveMovableTraces && n3.worst_contact_center ? { ...n3, center: n3.worst_contact_center, message: n3.worst_contact_message ?? n3.message, actual_clearance: n3.worst_actual_clearance ?? n3.actual_clearance } : n3;
if (m4.kind === "displacementChain") {
const n4 = xO(e33), s5 = fD(this.srj, n4, f4, t2.traceRouteIndexById, m4.routeSide);
if (!s5)
continue;
d2 = true, l2 += 1, this.candidateAttempts += 1;
let c5 = Gk(n4), h4 = this.getSnapshot(c5), u4 = this.getViaIssueCount(h4), g5 = this.getRepairIssueCount(h4);
if (g5 > 0 && l2 < a2) {
const e34 = xO(c5);
let t3 = false;
for (const n5 of h4.errors)
t3 = yD(this.srj, e34, n5, h4.traceRouteIndexById, s5.movedRouteIndex, this.connMap) || t3;
if (t3) {
l2 += 1, this.candidateAttempts += 1;
const t4 = Gk(e34), n5 = this.getSnapshot(t4), o3 = this.getViaIssueCount(n5);
MD(n5, o3, g5, this.getRepairIssueScore(h4), u4, h4) && (c5 = t4, h4 = n5, u4 = o3, g5 = this.getRepairIssueCount(h4));
}
}
const _5 = p3 ? this.getRepairIssueCount(p3.snapshot) : o2, y4 = p3 ? this.getRepairIssueScore(p3.snapshot) : i2, b4 = p3?.viaIssueCount ?? r2;
if (u4 <= b4 && MD(h4, u4, _5, y4, b4, p3?.snapshot ?? t2) && (p3 = { routes: c5, snapshot: h4, viaIssueCount: u4, usesViaInPad: false }), g5 === 0)
break;
continue;
}
const _4 = vO(e33, [g4]);
if (!(m4.kind === "segment" ? ID(_4, f4, g4, m4.halfSpan, m4.offset, m4.directionSign) : m4.kind === "span" ? CD(this.srj, _4, f4, g4, m4.spanExpansion, m4.offset, m4.directionSign) : PD(this.srj, _4, f4, g4, m4.spanExpansion, { x: f4.center.x + m4.dx, y: f4.center.y + m4.dy })))
continue;
const y3 = Uk(_4, [g4]);
d2 = true, l2 += 1, this.candidateAttempts += 1;
const b3 = this.getSnapshot(y3), x3 = this.getViaIssueCount(b3), v3 = p3 ? this.getRepairIssueCount(p3.snapshot) : o2, I3 = p3 ? this.getRepairIssueScore(p3.snapshot) : i2, S3 = p3?.viaIssueCount ?? r2;
(this.initialLowCountErrorsHaveMovableTraces ? MD(b3, x3, v3, I3, S3, p3?.snapshot ?? t2) : x3 <= S3 && oD(b3, p3?.snapshot ?? t2)) && (p3 = { routes: y3, snapshot: b3, viaIssueCount: x3, usesViaInPad: false });
}
this.tracePairDetourCursorByErrorId.set(m3, h3);
}
for (const s4 of this.enableViaInPadLayerMoves ? ["start", "end"] : []) {
if (l2 >= a2)
break;
if (g3 === undefined)
break;
const c4 = vO(e33, [g3]);
if (!mD(this.srj, c4, n3, t2.traceRouteIndexById, s4, this.connMap, this.viaHoleDiameter))
continue;
const h3 = Uk(c4, [g3]);
this.viaInPadCandidateAttempts += 1, l2 += 1, this.candidateAttempts += 1;
const d3 = this.getSnapshot(h3), u3 = this.getViaIssueCount(d3), m4 = p3 ? this.getRepairIssueCount(p3.snapshot) : o2, f4 = p3 ? this.getRepairIssueScore(p3.snapshot) : i2;
MD(d3, u3, m4, f4, p3?.viaIssueCount ?? r2, p3?.snapshot ?? t2) && (p3 = { routes: h3, snapshot: d3, viaIssueCount: u3, usesViaInPad: true });
}
const _3 = this.enableViaInPadLayerMoves ? this.srj.layerCount : 0;
for (let s4 = 0;s4 < _3 && !(l2 >= a2) && g3 !== undefined; s4 += 1) {
const a3 = vO(e33, [g3]);
if (!pD(this.srj, a3, n3, t2.traceRouteIndexById, s4, this.connMap, this.viaHoleDiameter))
continue;
const c4 = Uk(a3, [g3]);
this.viaInPadCandidateAttempts += 1, l2 += 1, this.candidateAttempts += 1;
const h3 = this.getSnapshot(c4), d3 = this.getViaIssueCount(h3), u3 = p3 ? this.getRepairIssueCount(p3.snapshot) : o2, m4 = p3 ? this.getRepairIssueScore(p3.snapshot) : i2;
MD(h3, d3, u3, m4, p3?.viaIssueCount ?? r2, p3?.snapshot ?? t2) && (p3 = { routes: c4, snapshot: h3, viaIssueCount: d3, usesViaInPad: true });
}
if (this.enableViaInPadLayerMoves && I2 && f3) {
const s4 = this.iterations % 2 == 0 ? [0, 1] : [1, 0], c4 = this.iterations % 3;
for (const h3 of s4)
for (let s5 = 0;s5 < this.srj.layerCount && !(l2 >= a2); s5 += 1) {
const a3 = f3[h3], d3 = vO(e33, [a3]);
if (!vD(this.srj, d3, n3, t2.traceRouteIndexById, h3, s5, c4, this.connMap, this.viaHoleDiameter))
continue;
const u3 = Uk(d3, [a3]);
this.viaInPadCandidateAttempts += 1, l2 += 1, this.candidateAttempts += 1;
const m4 = this.getSnapshot(u3), g4 = this.getViaIssueCount(m4), _4 = p3 ? this.getRepairIssueCount(p3.snapshot) : o2, y3 = p3 ? this.getRepairIssueScore(p3.snapshot) : i2;
MD(m4, g4, _4, y3, p3?.viaIssueCount ?? r2, p3?.snapshot ?? t2) && (p3 = { routes: u3, snapshot: m4, viaIssueCount: g4, usesViaInPad: true });
}
}
p3 && (e33 = p3.routes, t2 = p3.snapshot, o2 = this.getRepairIssueCount(t2), i2 = this.getRepairIssueScore(t2), r2 = p3.viaIssueCount, this.targetedForceAccepted = true, p3.usesViaInPad && (this.viaInPadCandidatesAccepted += 1), u2 = true);
}
if (!u2 && v2.length >= 2) {
const n3 = xO(e33);
let s3 = false;
for (const e34 of v2)
s3 = wD(this.srj, n3, [e34], t2.traceRouteIndexById, 1, this.connMap, true, this.enableTargetedErrorSweep, false, this.enableTraceViaOwnerTargeting) || s3;
if (s3) {
const s4 = Gk(n3);
l2 += 1, this.candidateAttempts += 1;
const a3 = this.getSnapshot(s4), c3 = this.getViaIssueCount(a3);
if (MD(a3, c3, o2, i2, r2, t2) && (e33 = s4, t2 = a3, o2 = this.getRepairIssueCount(a3), i2 = this.getRepairIssueScore(a3), r2 = c3, this.targetedForceAccepted = true, u2 = true, a3.count === 0))
return void this.acceptSolvedRoutes(e33, t2);
}
}
for (let n3 = 0;n3 < b2 && l2 < a2 && !u2; n3 += 1) {
const s3 = (x2 + n3) % y2.length, c3 = y2[s3];
if (!c3)
continue;
this.errorCursor = (s3 + 1) % y2.length;
const h3 = o2 === 1;
for (const n4 of aw(this.effort)) {
if (l2 >= a2)
break;
const s4 = xO(e33);
if (!wD(this.srj, s4, [c3], t2.traceRouteIndexById, n4, this.connMap, true, this.enableTargetedErrorSweep, h3, this.enableTraceViaOwnerTargeting))
continue;
const d3 = Gk(s4);
l2 += 1, this.candidateAttempts += 1;
const p3 = this.getSnapshot(d3), m3 = this.getViaIssueCount(p3);
if (MD(p3, m3, o2, i2, r2, t2)) {
if (e33 = d3, t2 = p3, o2 = this.getRepairIssueCount(p3), i2 = this.getRepairIssueScore(p3), r2 = m3, this.targetedForceAccepted = true, u2 = true, p3.count === 0)
return void this.acceptSolvedRoutes(e33, t2);
break;
}
}
if (u2)
break;
}
const M2 = e33.length <= 120, w2 = (N2 = s2.length, Math.max(16, Math.min(64, 2 * N2)));
var N2;
const T2 = this.enableLargeBoardBroadFallback && this.MAX_ITERATIONS >= 192 && !M2 && this.stalledIterations > 0 && this.stalledIterations % w2 === 0;
if (this.enableBroadFallback && !u2 && (M2 || this.effort >= 2 && this.stalledIterations >= 2 || T2)) {
p2 = T2;
for (const n3 of [1, 2]) {
const s3 = Wk(this.srj, e33, this.effort, n3, this.connMap, this.drcEvaluator === undefined, false);
if (s3 === e33)
continue;
const a3 = this.getSnapshot(s3), c3 = this.getViaIssueCount(a3);
if (MD(a3, c3, o2, i2, r2, t2) && (e33 = s3, t2 = a3, o2 = this.getRepairIssueCount(a3), i2 = this.getRepairIssueScore(a3), r2 = c3, this.broadForceAccepted = true, u2 = true, a3.count === 0))
return void this.acceptSolvedRoutes(e33, t2);
}
}
u2 ? this.largeBoardBroadFallbackMisses = 0 : p2 && (this.largeBoardBroadFallbackMisses += 1), this.outputHdRoutes = e33, this.outputSnapshot = t2, this.stalledIterations = u2 ? 0 : this.stalledIterations + 1, d2 || this.updateDrcCountPlateauState(t2), this.updateStats(t2), (this.solved || o2 === 0) && this.acceptSolvedRoutes(e33, t2);
}
tryFinalAcceptance() {
const e33 = this.outputSnapshot ?? this.getSnapshot(this.outputHdRoutes);
this.legacyCleanCheckpoint && eD(e33) > 0 && this.finishAtLegacyCleanCheckpoint() || this.acceptSolvedRoutes(this.outputHdRoutes, e33);
}
getOutput() {
return this.outputHdRoutes;
}
visualize() {
return super.visualize();
}
preview() {
return this.visualize();
}
};
var pL = class extends De {
params;
inputHdRoutes;
guardedInputHdRoutes;
broadMaxIterations;
broadPassMultiplier;
autoroutingDrcEngine;
legacyDrcEvaluator;
outputHdRoutes;
phase = "start";
inputSnapshot;
baselineSolver;
baselineSnapshot;
broadInputSnapshot;
broadSnapshot;
broadSolver;
preBroadCandidate;
safeTraceLayerInputRoutes;
safeTraceLayerInputSnapshot;
safeTraceLayerSolver;
safeTraceLayerPhaseAccepted = false;
mixedSafeTraceLayerSolver;
mixedSafeTraceLayerPhaseAccepted = false;
legacySafeTraceLayerRoutes;
legacySafeTraceLayerSnapshot;
legacySafeTraceLayerSelectedSolver;
viaInPadSolver;
portfolioSelectedSolver;
selectedSolver;
referenceInputDrcIssueCount;
referenceCandidateDrcIssueCount;
referenceCandidateRolledBack = false;
mixedReferenceInputDrcIssueCount;
mixedReferenceCandidateDrcIssueCount;
referenceInputSnapshot;
constructor(e33) {
if (super(), !Number.isFinite(e33.broadPassMultiplier))
throw new Error("broadPassMultiplier must be a finite number");
if (e33.broadPassMultiplier <= 0)
throw new Error("broadPassMultiplier must be greater than zero");
if (!Number.isInteger(e33.broadMaxIterations))
throw new Error("broadMaxIterations must be an integer");
if (e33.broadMaxIterations <= 0)
throw new Error("broadMaxIterations must be greater than zero");
if (e33.viaInPadMaxIterations !== undefined && !Number.isInteger(e33.viaInPadMaxIterations))
throw new Error("viaInPadMaxIterations must be an integer");
if (e33.viaInPadMaxIterations !== undefined && e33.viaInPadMaxIterations <= 0)
throw new Error("viaInPadMaxIterations must be greater than zero");
this.autoroutingDrcEngine = e33.autoroutingDrcEngine ?? (e33.drcEvaluator ? undefined : new UM(e33.srj, { connMap: e33.connMap, traceClearance: e33.srj.minTraceToPadEdgeClearance ?? WA.traceClearance, viaClearance: e33.srj.minTraceToPadEdgeClearance ?? WA.viaClearance, includeTraceViaOwnerMetadata: e33.enableTraceViaOwnerTargeting ?? false })), this.legacyDrcEvaluator = (t2) => {
const n2 = e33.drcEvaluator?.evaluateLegacy ?? e33.drcEvaluator, o2 = n2 ? n2(t2) : this.autoroutingDrcEngine.evaluateLegacy(t2.traces), i2 = Array.isArray(o2) ? o2 : o2.errors, r2 = Array.isArray(o2) ? o2 : o2.errorsWithCenters ?? o2.errors;
return { errors: i2.filter((e34) => !Qk(e34)), errorsWithCenters: r2.filter((e34) => !Qk(e34)) };
}, this.params = { ...e33, autoroutingDrcEngine: this.autoroutingDrcEngine }, this.inputHdRoutes = e33.hdRoutes, this.guardedInputHdRoutes = Gk(xO(e33.hdRoutes)), this.broadMaxIterations = e33.broadMaxIterations, this.broadPassMultiplier = e33.broadPassMultiplier, this.outputHdRoutes = e33.hdRoutes, this.params.referenceDrcEvaluator && (this.referenceInputSnapshot = this.getReferenceDrcSnapshot(this.inputHdRoutes));
}
getConstructorParams() {
return [{ ...this.params, hdRoutes: this.inputHdRoutes }];
}
stepBranch(e33, t2) {
if (this.activeSubSolver = e33, e33.step(), e33.failed)
throw new Error(`${t2} DRC repair branch failed: ${e33.error}`);
}
getReferenceDrcSnapshot(e33) {
const t2 = { traces: [], srj: this.params.srj, routes: e33, hdRoutes: e33 }, n2 = this.params.referenceDrcEvaluator?.getCachedResult?.(t2);
if (n2) {
const e34 = Array.isArray(n2) ? n2 : n2.errors;
return { errors: e34, count: e34.length };
}
return EO(this.params.srj, e33, this.params.referenceDrcEvaluator, this.params.connMap, this.autoroutingDrcEngine);
}
finishWithOutput(e33, t2, n2) {
let o2 = e33, i2 = t2;
if (this.params.referenceDrcEvaluator) {
const e34 = this.referenceInputSnapshot, t3 = this.getReferenceDrcSnapshot(o2);
this.referenceInputDrcIssueCount = e34.count, this.referenceCandidateDrcIssueCount = t3.count, (t3.count > e34.count || t3.count === e34.count && ((e35, t4) => {
const n3 = new Set(t4.map(Kk));
return e35.some((e36) => !n3.has(Kk(e36)));
})(t3.errors, e34.errors)) && (o2 = this.guardedInputHdRoutes, i2 = this.inputSnapshot, this.referenceCandidateRolledBack = true);
}
this.outputHdRoutes = o2, this.selectedSolver = n2, this.activeSubSolver = null, this.phase = "done", this.progress = 1, this.stats = { ...this.portfolioSelectedSolver?.stats ?? {}, ...n2?.stats ?? {}, finalDrcIssueCount: i2.count, drcBranchPortfolioInitialDrcIssueCount: this.inputSnapshot?.count ?? t2.count, drcBranchPortfolioBaselineDrcIssueCount: this.baselineSnapshot?.count ?? t2.count, drcBranchPortfolioBroadInitialDrcIssueCount: this.broadInputSnapshot?.count, drcBranchPortfolioBroadFinalDrcIssueCount: this.broadSnapshot?.count, drcBranchPortfolioBroadMaxIterations: this.broadMaxIterations, drcBranchPortfolioBroadBranchAttempted: Boolean(this.broadSolver), drcBranchPortfolioBroadBranchAccepted: this.portfolioSelectedSolver !== undefined && 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: eD(i2), drcBranchPortfolioReferenceInputDrcIssueCount: this.referenceInputDrcIssueCount, drcBranchPortfolioReferenceCandidateDrcIssueCount: this.referenceCandidateDrcIssueCount, drcBranchPortfolioReferenceCandidateRolledBack: this.referenceCandidateRolledBack, drcBranchPortfolioMixedReferenceInputDrcIssueCount: this.mixedReferenceInputDrcIssueCount, drcBranchPortfolioMixedReferenceCandidateDrcIssueCount: this.mixedReferenceCandidateDrcIssueCount }, this.solved = true;
}
startBaselineBranch() {
this.baselineSolver = new uL({ ...this.params, hdRoutes: this.inputHdRoutes, drcEvaluator: this.legacyDrcEvaluator, referenceDrcEvaluator: undefined, enableSafeTraceLayerMoves: false, enableViaInPadLayerMoves: false }), this.activeSubSolver = this.baselineSolver, this.phase = "baseline";
}
startSafeTraceLayerPhase(e33, t2, n2) {
this.portfolioSelectedSolver = n2, this.params.enableSafeTraceLayerMoves ? (this.safeTraceLayerInputRoutes = e33, this.safeTraceLayerInputSnapshot = t2, this.safeTraceLayerSolver = new uL({ ...this.params, hdRoutes: e33, drcEvaluator: this.legacyDrcEvaluator, referenceDrcEvaluator: undefined, maxIterations: this.params.viaInPadMaxIterations ?? this.params.maxIterations, enableLargeBoardBroadFallback: false, enableTargetedErrorSweep: false, enablePostSolveClearanceRelaxation: false, enableSafeTraceLayerMoves: true, enableViaInPadLayerMoves: false }), this.activeSubSolver = this.safeTraceLayerSolver, this.phase = "safeTraceLayer") : this.startViaInPadPhase(e33, t2, n2);
}
startViaInPadPhase(e33, t2, n2) {
this.portfolioSelectedSolver = n2;
const o2 = this.params.enableViaInPadLayerMoves && this.params.viaInPadDrcEvaluator !== undefined;
t2.errors.some(Qk) || o2 ? (this.viaInPadSolver = new uL({ ...this.params, hdRoutes: e33, drcEvaluator: this.params.viaInPadDrcEvaluator ?? this.params.drcEvaluator, maxIterations: this.params.viaInPadMaxIterations ?? this.params.maxIterations, enableLargeBoardBroadFallback: false, enableTargetedErrorSweep: false, enablePostSolveClearanceRelaxation: false, enableSafeTraceLayerMoves: false, enableViaInPadLayerMoves: this.params.enableViaInPadLayerMoves }), this.activeSubSolver = this.viaInPadSolver, this.phase = "viaInPad") : this.finishWithOutput(e33, t2, n2);
}
startMixedSafeTraceLayerPhase(e33, t2, n2) {
this.legacySafeTraceLayerRoutes = e33, this.legacySafeTraceLayerSnapshot = t2, this.legacySafeTraceLayerSelectedSolver = n2, this.mixedSafeTraceLayerSolver = new uL({ ...this.params, hdRoutes: this.safeTraceLayerInputRoutes, drcEvaluator: this.params.drcEvaluator, referenceDrcEvaluator: undefined, maxIterations: this.params.viaInPadMaxIterations ?? this.params.maxIterations, enableLargeBoardBroadFallback: false, enableTargetedErrorSweep: false, enablePostSolveClearanceRelaxation: false, enableSafeTraceLayerMoves: true, enableViaInPadLayerMoves: false }), this.activeSubSolver = this.mixedSafeTraceLayerSolver, this.phase = "mixedSafeTraceLayer";
}
startBroadBranch() {
const e33 = Wk(this.params.srj, this.inputHdRoutes, this.params.effort ?? 1, this.broadPassMultiplier, this.params.connMap);
this.broadInputSnapshot = EO(this.params.srj, e33, this.params.drcEvaluator, this.params.connMap, this.autoroutingDrcEngine), oD(this.broadInputSnapshot, this.baselineSnapshot) ? (this.broadSolver = new uL({ ...this.params, hdRoutes: e33, drcEvaluator: this.legacyDrcEvaluator, referenceDrcEvaluator: undefined, maxIterations: this.broadMaxIterations, enableSafeTraceLayerMoves: false, enableViaInPadLayerMoves: false }), this.activeSubSolver = this.broadSolver, this.phase = "broad") : this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(), this.baselineSnapshot, this.baselineSolver);
}
_step() {
if (this.phase === "start")
return this.inputSnapshot = EO(this.params.srj, this.inputHdRoutes, this.params.drcEvaluator, this.params.connMap, this.autoroutingDrcEngine), eD(this.inputSnapshot) === 0 ? void this.startViaInPadPhase(this.inputHdRoutes, this.inputSnapshot) : void this.startBaselineBranch();
if (this.phase === "baseline") {
if (this.stepBranch(this.baselineSolver, "baseline"), !this.baselineSolver.solved)
return;
const e33 = this.baselineSolver.getOutput();
return this.baselineSnapshot = EO(this.params.srj, e33, this.params.drcEvaluator, this.params.connMap, this.autoroutingDrcEngine), eD(this.baselineSnapshot) === 0 ? void this.startViaInPadPhase(e33, this.baselineSnapshot, this.baselineSolver) : void (this.params.enableSafeTraceLayerMoves && this.baselineSnapshot.count <= 3 ? this.startSafeTraceLayerPhase(e33, this.baselineSnapshot, this.baselineSolver) : this.startBroadBranch());
}
if (this.phase === "broad") {
if (this.stepBranch(this.broadSolver, "broad"), !this.broadSolver.solved)
return;
const e33 = this.broadSolver.getOutput();
return this.broadSnapshot = EO(this.params.srj, e33, this.params.drcEvaluator, this.params.connMap, this.autoroutingDrcEngine), oD(this.broadSnapshot, this.baselineSnapshot) ? void this.startSafeTraceLayerPhase(e33, this.broadSnapshot, this.broadSolver) : void this.startSafeTraceLayerPhase(this.baselineSolver.getOutput(), this.baselineSnapshot, this.baselineSolver);
}
if (this.phase === "safeTraceLayer") {
if (this.stepBranch(this.safeTraceLayerSolver, "safe trace-layer"), !this.safeTraceLayerSolver.solved)
return;
const e33 = this.safeTraceLayerSolver.getOutput(), t2 = EO(this.params.srj, e33, this.params.drcEvaluator, this.params.connMap, this.autoroutingDrcEngine), n2 = Jk(this.safeTraceLayerInputSnapshot, false), o2 = Jk(t2, false);
this.safeTraceLayerPhaseAccepted = o2 <= n2 && MD(t2, o2, this.safeTraceLayerInputSnapshot.count, this.safeTraceLayerInputSnapshot.issueScore, n2, this.safeTraceLayerInputSnapshot);
let i2 = this.safeTraceLayerPhaseAccepted ? e33 : this.safeTraceLayerInputRoutes, r2 = this.safeTraceLayerPhaseAccepted ? t2 : this.safeTraceLayerInputSnapshot, s2 = this.safeTraceLayerPhaseAccepted ? this.safeTraceLayerSolver : this.portfolioSelectedSolver;
return this.preBroadCandidate && !oD(r2, this.preBroadCandidate.snapshot) && (i2 = this.preBroadCandidate.routes, r2 = this.preBroadCandidate.snapshot, s2 = this.preBroadCandidate.solver, this.safeTraceLayerPhaseAccepted = this.preBroadCandidate.safeTraceLayerPhaseAccepted), r2.count > 0 && !this.broadInputSnapshot ? (this.preBroadCandidate = { routes: i2, snapshot: r2, solver: s2, safeTraceLayerPhaseAccepted: this.safeTraceLayerPhaseAccepted }, void this.startBroadBranch()) : eD(r2) > 0 && this.safeTraceLayerInputSnapshot.errors.some(Qk) ? void this.startMixedSafeTraceLayerPhase(i2, r2, s2) : void this.startViaInPadPhase(i2, r2, s2);
}
if (this.phase === "mixedSafeTraceLayer") {
if (this.stepBranch(this.mixedSafeTraceLayerSolver, "mixed safe trace-layer"), !this.mixedSafeTraceLayerSolver.solved)
return;
const e33 = this.mixedSafeTraceLayerSolver.getOutput(), t2 = EO(this.params.srj, e33, this.params.drcEvaluator, this.params.connMap, this.autoroutingDrcEngine), n2 = eD(t2) <= eD(this.legacySafeTraceLayerSnapshot);
let o2 = true;
if (this.params.referenceDrcEvaluator) {
const t3 = this.getReferenceDrcSnapshot(this.legacySafeTraceLayerRoutes), n3 = this.getReferenceDrcSnapshot(e33);
this.mixedReferenceInputDrcIssueCount = t3.count, this.mixedReferenceCandidateDrcIssueCount = n3.count, o2 = n3.count <= t3.count;
}
return this.mixedSafeTraceLayerPhaseAccepted = n2 && o2, void this.startViaInPadPhase(this.mixedSafeTraceLayerPhaseAccepted ? e33 : this.legacySafeTraceLayerRoutes, this.mixedSafeTraceLayerPhaseAccepted ? t2 : this.legacySafeTraceLayerSnapshot, this.mixedSafeTraceLayerPhaseAccepted ? this.mixedSafeTraceLayerSolver : this.legacySafeTraceLayerSelectedSolver);
}
if (this.phase === "viaInPad") {
if (this.stepBranch(this.viaInPadSolver, "via-in-pad"), !this.viaInPadSolver.solved)
return;
const e33 = this.viaInPadSolver.getOutput(), t2 = EO(this.params.srj, e33, this.params.viaInPadDrcEvaluator ?? this.params.drcEvaluator, this.params.connMap, this.autoroutingDrcEngine);
this.finishWithOutput(e33, t2, this.viaInPadSolver);
}
}
getOutput() {
return this.outputHdRoutes;
}
visualize() {
const e33 = this.activeSubSolver ?? this.selectedSolver;
return e33?.visualize() ?? super.visualize();
}
preview() {
const e33 = this.activeSubSolver ?? this.selectedSolver;
return e33?.preview() ?? this.visualize();
}
};
var mL = (e33) => e33.circuitJsonMetadata ?? {};
var gL = ({ connections: e33, obstacles: t2 }) => new Set([...e33.flatMap((e34) => e34.pointsToConnect.flatMap((e35) => e35.pcb_port_id ? [e35.pcb_port_id] : [])), ...t2.flatMap((e34) => {
const t3 = mL(e34).pcb_port_id;
return t3 ? [t3] : [];
})]);
var fL = (e33) => e33.__netConnectionName ?? e33.__rootConnectionNames?.[0] ?? e33.name;
var _L = (e33) => Array.from(new Set([e33.name, e33.__netConnectionName, ...e33.__rootConnectionNames ?? [], ...e33.pointsToConnect.flatMap((e34) => [e34.pointId, e34.pcb_port_id])])).filter((e34) => Boolean(e34));
var yL = (e33, t2) => {
const n2 = new Map, o2 = new Set, i2 = new Map;
for (const r2 of e33) {
const e34 = fL(r2);
for (const t3 of _L(r2)) {
const i3 = n2.get(t3);
i3 && i3 !== e34 ? (n2.delete(t3), o2.add(t3)) : o2.has(t3) || n2.set(t3, e34);
}
const s2 = t2.getNetConnectedToId(r2.name);
if (!s2)
continue;
const a2 = s2, c2 = i2.get(a2) ?? new Set;
c2.add(e34), i2.set(a2, c2);
}
return { connMap: t2, circuitJsonSourceTraceIdBySrjDeclaredConnectionReference: n2, circuitJsonSourceTraceIdsByConnectivityNetId: i2 };
};
var bL = (e33, t2) => {
const n2 = e33.circuitJsonSourceTraceIdBySrjDeclaredConnectionReference.get(t2);
if (n2)
return n2;
const o2 = e33.connMap.getNetConnectedToId(t2);
if (!o2)
return;
const i2 = e33.circuitJsonSourceTraceIdsByConnectivityNetId.get(o2);
return i2?.size === 1 ? i2.values().next().value : undefined;
};
function xL(e33, t2, n2 = e33, o2) {
const i2 = [], r2 = n2 === e33 ? e33.connections : [...e33.connections, ...n2.connections], s2 = n2 === e33 ? e33.obstacles : n2.obstacles, a2 = yL(r2, o2 ?? ri(n2 === e33 ? e33 : { ...n2, connections: r2 })), c2 = gL({ connections: r2, obstacles: s2 });
if (r2.forEach((e34) => {
const n3 = e34.pointsToConnect.map((e35) => e35.pcb_port_id).filter((e35) => Boolean(e35)), o3 = new Set(n3), r3 = (e35) => ((e36) => Array.from(new Set(e36.flatMap((e37) => e37.connectedTo))))(e35).filter((e36) => !o3.has(e36)), c3 = e34.pointsToConnect.map((e35) => e35.pointId).filter((e35) => Boolean(e35)), l2 = bL(a2, e34.name) ?? fL(e34), h2 = [], d2 = t2.find((t3) => (t3.connection_name ?? t3.connectionName) === e34.name);
if (d2) {
const e35 = (e36) => ("route_type" in e36) && e36.route_type === "jumper" ? e36.start : ("x" in e36) && ("y" in e36) ? { x: e36.x, y: e36.y } : { x: 0, y: 0 }, t3 = [e35(d2.route[0]), e35(d2.route[d2.route.length - 1])];
for (const e36 of t3)
for (const t4 of s2)
jt(e36, t4) <= 0 && h2.push(t4);
}
const u2 = i2.find((e35) => e35.type === "source_trace" && e35.source_trace_id === l2);
if (u2) {
const e35 = u2;
e35.connected_source_port_ids = [...new Set([...e35.connected_source_port_ids, ...n3])], e35.connected_source_net_ids = [...new Set([...e35.connected_source_net_ids ?? [], ...c3, ...r3(h2)])];
} else
i2.push({ type: "source_trace", source_trace_id: l2, connected_source_port_ids: n3, connected_source_net_ids: r3(h2).concat(c3) });
}), t2[0] && "type" in t2[0]) {
const e34 = new Map(r2.map((e35) => [e35.name, e35]));
for (const n3 of t2) {
const t3 = [...new Set((n3.connectsTo ?? []).filter((e35) => c2.has(e35)))], o3 = new Set(t3), r3 = [...new Set((n3.connectsTo ?? []).filter((e35) => !o3.has(e35)))];
if (t3.length === 0 && r3.length === 0)
continue;
const s3 = e34.get(n3.connection_name), l2 = bL(a2, n3.connection_name) ?? n3.connectsTo?.map((e35) => bL(a2, e35)).find((e35) => e35 !== undefined) ?? (s3 ? fL(s3) : n3.connection_name), h2 = i2.find((e35) => e35.type === "source_trace" && e35.source_trace_id === l2);
h2?.type !== "source_trace" ? i2.push({ type: "source_trace", source_trace_id: l2, connected_source_port_ids: t3, connected_source_net_ids: r3 }) : (h2.connected_source_port_ids = [...new Set([...h2.connected_source_port_ids, ...t3])], h2.connected_source_net_ids = [...new Set([...h2.connected_source_net_ids ?? [], ...r3])]);
}
}
return i2;
}
function vL(e33, t2, n2) {
let o2, i2 = Number.POSITIVE_INFINITY;
for (const r2 of t2) {
const t3 = n2.get(r2);
if (!t3)
continue;
const s2 = Math.hypot(t3.x - e33.x, t3.y - e33.y);
s2 < i2 && (i2 = s2, o2 = r2);
}
return o2 ?? t2[0];
}
var IL = new Set(["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"]);
var SL = (e33) => IL.has(e33);
function CL(e33, t2, n2, o2) {
const i2 = JSON.stringify([t2.center.x, t2.center.y, t2.width, t2.height, t2.ccwRotationDegrees ?? 0, [...t2.layers].sort()]), r2 = o2.get(e33) ?? new Set;
if (r2.has(i2))
return;
const s2 = r2.size === 0 ? e33 : `${e33}_fragment_${n2}`;
return r2.add(i2), o2.set(e33, r2), s2;
}
function PL(e33) {
const t2 = [], n2 = new Map, o2 = new Map, i2 = function(e34) {
const t3 = new Map;
for (const n3 of e34.connections)
for (const e35 of n3.pointsToConnect)
e35.pcb_port_id && t3.set(e35.pcb_port_id, { x: e35.x, y: e35.y });
return t3;
}(e33), r2 = gL(e33);
for (const [s2, a2] of e33.obstacles.entries()) {
if (a2.isNonPlatedHole) {
const e34 = { type: "pcb_hole", pcb_hole_id: a2.obstacleId ?? `pcb_hole_${s2}`, x: a2.center.x, y: a2.center.y };
if (a2.shape === "circle")
t2.push({ ...e34, hole_shape: "circle", hole_diameter: a2.width });
else {
const n3 = a2.ccwRotationDegrees ?? 0;
if (n3 % 90 != 0)
throw new Error(`Cannot represent rotated rectangular hole ${e34.pcb_hole_id} in Circuit JSON`);
const o3 = n3 % 180 != 0;
t2.push({ ...e34, hole_shape: "rect", hole_width: o3 ? a2.height : a2.width, hole_height: o3 ? a2.width : a2.height });
}
continue;
}
const c2 = a2.connectedTo, l2 = mL(a2);
if (l2.pcb_via_id)
continue;
const { pcb_smtpad_id: h2, pcb_plated_hole_id: d2 } = l2, u2 = [...new Set([...l2.pcb_port_id ? [l2.pcb_port_id] : [], ...c2.filter((e34) => r2.has(e34))])];
if (u2.length === 0) {
for (const t3 of e33.connections)
if (a2.netIsAssignable || _L(t3).some((e34) => c2.includes(e34)))
for (const e34 of t3.pointsToConnect)
e34.pcb_port_id && Math.hypot(e34.x - a2.center.x, e34.y - a2.center.y) < 0.000001 && u2.push(e34.pcb_port_id);
}
const p2 = l2.pcb_port_id && i2.has(l2.pcb_port_id) ? l2.pcb_port_id : vL(a2.center, u2, i2);
if (!h2 && !d2 && !p2)
continue;
const m2 = a2.layers.filter(SL);
if (m2.length === 0)
continue;
const { width: g2, height: f2 } = a2, _2 = a2.center.x, y2 = a2.center.y, b2 = a2.ccwRotationDegrees;
if (Boolean(d2) || m2.length > 1) {
const e34 = CL(d2 ?? `pcb_plated_hole_${_2.toFixed(3)}_${y2.toFixed(3)}`, a2, s2, o2);
if (e34 === undefined)
continue;
if (typeof b2 == "number" && Number.isFinite(b2)) {
const n3 = Math.max(0.5 * Math.min(g2, f2), 0.1);
t2.push({ type: "pcb_plated_hole", pcb_plated_hole_id: e34, shape: "rotated_pill_hole_with_rect_pad", hole_shape: "rotated_pill", pad_shape: "rect", hole_width: n3, hole_height: n3, hole_ccw_rotation: b2, rect_pad_width: g2, rect_pad_height: f2, rect_ccw_rotation: b2, hole_offset_x: 0, hole_offset_y: 0, x: _2, y: y2, layers: m2, ...p2 ? { pcb_port_id: p2 } : {} });
continue;
}
if (Math.abs(g2 - f2) < 0.001) {
t2.push({ type: "pcb_plated_hole", pcb_plated_hole_id: e34, shape: "circle", outer_diameter: Math.max(g2, f2), hole_diameter: Math.max(0.5 * Math.min(g2, f2), 0.1), x: _2, y: y2, layers: m2, ...p2 ? { pcb_port_id: p2 } : {} });
continue;
}
t2.push({ type: "pcb_plated_hole", pcb_plated_hole_id: e34, shape: "circular_hole_with_rect_pad", hole_shape: "circle", hole_diameter: Math.max(0.5 * Math.min(g2, f2), 0.1), rect_pad_width: g2, rect_pad_height: f2, hole_offset_x: 0, hole_offset_y: 0, x: _2, y: y2, layers: m2, ...p2 ? { pcb_port_id: p2 } : {} });
continue;
}
const x2 = CL(h2 ?? `pcb_smtpad_${_2.toFixed(3)}_${y2.toFixed(3)}`, a2, s2, n2);
x2 !== undefined && (typeof b2 == "number" && Number.isFinite(b2) ? t2.push({ type: "pcb_smtpad", pcb_smtpad_id: x2, layer: m2[0], shape: "rotated_rect", x: _2, y: y2, width: g2, height: f2, ccw_rotation: b2, ...p2 ? { pcb_port_id: p2 } : {} }) : t2.push({ type: "pcb_smtpad", pcb_smtpad_id: x2, layer: m2[0], shape: "rect", width: g2, height: f2, x: _2, y: y2, ...p2 ? { pcb_port_id: p2 } : {} }));
}
return t2;
}
function ML(e33, t2, n2) {
if (n2 && e33.layers !== undefined)
return e33.layers;
const o2 = n2 ? e33 : { from_layer: "top", to_layer: Po(t2 - 1, t2) };
return AM(o2, t2);
}
function wL(e33) {
const { minX: t2, maxX: n2, minY: o2, maxY: i2 } = e33.bounds;
return { type: "pcb_board", pcb_board_id: "__autorouting_board__", thickness: 1.6, num_layers: e33.layerCount, center: { x: (t2 + n2) / 2, y: (o2 + i2) / 2 }, width: n2 - t2, height: i2 - o2, ...e33.outline ? { outline: e33.outline, shape: "polygon" } : { shape: "rect" }, material: "fr4", min_trace_to_hole_edge_clearance: e33.minTraceToHoleEdgeClearance, min_pad_edge_to_pad_edge_clearance: e33.minPadEdgeToPadEdgeClearance, ...e33.minBoardEdgeClearance !== undefined ? { min_board_edge_clearance: e33.minBoardEdgeClearance } : {} };
}
function NL(e33, t2, n2 = {}) {
const { minTraceWidth: o2 = 0.1, minViaDiameter: i2, minViaHoleDiameter: r2, originalSrj: s2, includeOriginalConnections: a2 = false } = n2, c2 = Xo(e33), l2 = i2 ?? c2.padDiameter, h2 = e33.min_via_hole_diameter ?? e33.minViaHoleDiameter, d2 = r2 ?? h2 ?? (i2 !== undefined ? 0.5 * l2 : c2.holeDiameter), u2 = [];
u2.push(...xL(e33, t2, a2 && s2 ? s2 : e33, n2.connectivityMaps?.source)), u2.push(...function(e34) {
const t3 = new Map;
return e34.connections.forEach((e35) => {
e35.pointsToConnect.forEach((e36) => {
e36.pcb_port_id && t3.set(e36.pcb_port_id, { type: "pcb_port", pcb_port_id: e36.pcb_port_id, source_port_id: e36.pcb_port_id, x: e36.x, y: e36.y, layers: Co(e36) });
});
}), Array.from(t3.values());
}(a2 && s2 ? s2 : e33)), u2.push(...PL(s2 ?? e33)), u2.push(...function(e34, t3, n3 = 0.3, o3 = 0.5 * n3, i3 = false) {
const r3 = [], s3 = new Set;
return e34.length > 0 && ("type" in e34[0] && e34[0].type === "pcb_trace" ? e34.forEach((e35) => {
e35.route.forEach((a3) => {
if (a3.route_type === "via") {
if (!SL(a3.from_layer) || !SL(a3.to_layer))
return;
const c3 = a3.via_diameter ?? n3, l3 = a3.via_hole_diameter ?? o3, h3 = `${a3.x},${a3.y},${a3.from_layer},${a3.to_layer}`;
s3.has(h3) || (r3.push({ type: "pcb_via", pcb_via_id: `via_${r3.length}`, pcb_trace_id: e35.pcb_trace_id, x: a3.x, y: a3.y, outer_diameter: c3, hole_diameter: l3, layers: ML(a3, t3, i3) }), s3.add(h3));
}
});
}) : e34.forEach((e35, a3) => {
const c3 = `trace_${a3}`, l3 = e35.viaDiameter ?? n3, h3 = o3;
for (let n4 = 1;n4 < e35.route.length; n4++) {
const o4 = e35.route[n4 - 1], a4 = e35.route[n4];
if (o4.z !== a4.z && Math.abs(o4.x - a4.x) < 0.01 && Math.abs(o4.y - a4.y) < 0.01) {
const e36 = Po(o4.z, t3), n5 = Po(a4.z, t3), d3 = `${a4.x},${a4.y},${e36},${n5}`;
s3.has(d3) || (r3.push({ type: "pcb_via", pcb_via_id: `via_${r3.length}`, pcb_trace_id: c3, x: a4.x, y: a4.y, outer_diameter: l3, hole_diameter: h3, layers: ML({ from_layer: e36, to_layer: n5 }, t3, i3) }), s3.add(d3));
}
}
})), r3;
}(t2, e33.layerCount, l2, d2, (s2 ?? e33).allowBlindAndBuriedVias === true));
const p2 = new Set(e33.connections.flatMap(_L)), m2 = yL(a2 && s2 ? [...e33.connections, ...s2.connections.filter((e34) => !p2.has(e34.name))] : e33.connections, n2.connectivityMaps?.route ?? ri(e33));
return t2.length > 0 && ("type" in t2[0] && t2[0].type === "pcb_trace" ? t2.forEach((e34) => {
const t3 = bL(m2, e34.connection_name) ?? e34.connectsTo?.map((e35) => bL(m2, e35)).find((e35) => Boolean(e35)) ?? e34.connection_name;
u2.push(function(e35, t4) {
return { type: "pcb_trace", pcb_trace_id: e35.pcb_trace_id, source_trace_id: t4, route: e35.route.map((e36) => {
if (e36.route_type === "wire") {
if (!SL(e36.layer))
return null;
const t5 = "start_pcb_port_id" in e36 && typeof e36.start_pcb_port_id == "string" ? e36.start_pcb_port_id : undefined, n3 = "end_pcb_port_id" in e36 && typeof e36.end_pcb_port_id == "string" ? e36.end_pcb_port_id : undefined;
return { route_type: "wire", x: e36.x, y: e36.y, width: e36.width, layer: e36.layer, ...t5 ? { start_pcb_port_id: t5 } : {}, ...n3 ? { end_pcb_port_id: n3 } : {} };
}
return e36.route_type === "via" && SL(e36.from_layer) && SL(e36.to_layer) ? { route_type: "via", x: e36.x, y: e36.y, from_layer: e36.from_layer, to_layer: e36.to_layer } : null;
}).filter((e36) => e36 !== null) };
}(e34, t3));
}) : t2.forEach((t3, n3) => {
const i3 = function(e34, t4, n4, o3, i4 = 0.1) {
const r3 = [];
if (!e34.jumpers || e34.jumpers.length === 0)
return [{ type: "pcb_trace", pcb_trace_id: t4, source_trace_id: n4, route: e34.route.map((t5, n5) => {
const r4 = n5 === 0, s4 = n5 === e34.route.length - 1;
return { route_type: "wire", x: t5.x, y: t5.y, width: t5.traceThickness ?? i4, layer: Po(t5.z, o3), ...r4 && t5.pcb_port_id ? { start_pcb_port_id: t5.pcb_port_id } : {}, ...s4 && t5.pcb_port_id ? { end_pcb_port_id: t5.pcb_port_id } : {} };
}) }];
const s3 = [];
for (const t5 of e34.jumpers) {
let n5 = -1, o4 = -1;
for (let i5 = 0;i5 < e34.route.length; i5++) {
const r4 = e34.route[i5];
Math.abs(r4.x - t5.start.x) < 0.01 && Math.abs(r4.y - t5.start.y) < 0.01 && (n5 = i5), Math.abs(r4.x - t5.end.x) < 0.01 && Math.abs(r4.y - t5.end.y) < 0.01 && (o4 = i5);
}
n5 !== -1 && o4 !== -1 && (n5 > o4 && ([n5, o4] = [o4, n5]), s3.push({ startIdx: n5, endIdx: o4 }));
}
s3.sort((e35, t5) => e35.startIdx - t5.startIdx);
let a3 = 0, c3 = 0;
for (const { startIdx: l3, endIdx: h3 } of s3) {
if (l3 >= a3) {
const s4 = e34.route.slice(a3, l3 + 1);
s4.length > 0 && (r3.push({ type: "pcb_trace", pcb_trace_id: `${t4}_${c3}`, source_trace_id: n4, route: s4.map((e35, t5) => {
const n5 = t5 === 0 && a3 === 0;
return { route_type: "wire", x: e35.x, y: e35.y, width: e35.traceThickness ?? i4, layer: Po(e35.z, o3), ...n5 && e35.pcb_port_id ? { start_pcb_port_id: e35.pcb_port_id } : {} };
}) }), c3++);
}
a3 = h3;
}
if (a3 < e34.route.length) {
const s4 = e34.route.slice(a3);
if (s4.length > 0) {
r3.push({ type: "pcb_trace", pcb_trace_id: `${t4}_${c3}`, source_trace_id: n4, route: s4.map((t5, n5) => {
const r4 = n5 === s4.length - 1;
return { route_type: "wire", x: t5.x, y: t5.y, width: t5.traceThickness ?? i4, layer: Po(t5.z, o3), ...r4 && t5.pcb_port_id ? { end_pcb_port_id: t5.pcb_port_id } : {} };
}) });
}
}
return r3;
}(t3, `trace_${n3}`, bL(m2, t3.connectionName) ?? t3.connectionName, e33.layerCount, o2);
u2.push(...i3);
})), u2;
}
var TL = Symbol("originalPortPoint");
var RL = class extends rr {
constructor(e33) {
const t2 = e33.nodeWithPortPoints, n2 = (e33.traceThickness ?? 0.1) / 2 + (e33.traceMargin ?? 0.1), o2 = t2.width > 2 * n2 && t2.height > 2 * n2, i2 = t2.center.x - t2.width / 2 + n2, r2 = t2.center.x + t2.width / 2 - n2, s2 = t2.center.y - t2.height / 2 + n2, a2 = t2.center.y + t2.height / 2 - n2, c2 = t2.portPoints.map((e34) => ({ ...e34, x: Math.max(i2, Math.min(r2, e34.x)), y: Math.max(s2, Math.min(a2, e34.y)), [TL]: e34 })), l2 = new Map;
let h2 = false;
for (const e34 of c2) {
const t3 = `${e34.x},${e34.y},${e34.z}`, n3 = l2.get(t3), o3 = e34[TL];
!n3 || n3.x === o3.x && n3.y === o3.y || (h2 = true), l2.set(t3, o3);
}
super({ ...e33, nodeWithPortPoints: o2 ? { ...t2, width: t2.width - 2 * n2, height: t2.height - 2 * n2, portPoints: c2 } : t2 }), h2 && (this.failed = true, this.error = "Boundary clearance collapses distinct terminals"), o2 || (this.failed = true, this.error = "Node has no interior after copper boundary clearance");
}
getOutput() {
return super.getOutput().map((e33) => {
const t2 = e33.route[0], n2 = e33.route[e33.route.length - 1];
if (!t2[TL] || !n2[TL])
throw new Error("A13 route lost its original terminal metadata");
return { ...e33, route: [{ ...t2[TL] }, ...e33.route, { ...n2[TL] }] };
});
}
};
var EL = class extends RL {
constructor(e33) {
super(e33), this.validationParams = e33;
}
validationParams;
_step() {
if (super._step(), !this.solved)
return;
const e33 = this.getOutput(), { connMap: t2, layerCount: n2 } = this.validationParams, o2 = this.nodeWithPortPoints, i2 = e33.flatMap((e34) => e34.route), r2 = Math.max(this.traceThickness, this.viaDiameter) / 2 + Math.max(this.traceMargin, 0.1) + 0.000001, s2 = Math.min(...i2.map((e34) => e34.x)) - r2, a2 = Math.max(...i2.map((e34) => e34.x)) + r2, c2 = Math.min(...i2.map((e34) => e34.y)) - r2, l2 = Math.max(...i2.map((e34) => e34.y)) + r2, h2 = this.validationParams.obstacles.filter((e34) => {
const t3 = Math.hypot(e34.width, e34.height) / 2;
return e34.center.x + t3 >= s2 && e34.center.x - t3 <= a2 && e34.center.y + t3 >= c2 && e34.center.y - t3 <= l2;
});
this.stats.boardObstaclesChecked = h2.length;
const d2 = { layerCount: n2, minTraceWidth: this.traceThickness, minViaDiameter: this.viaDiameter, bounds: { minX: o2.center.x - o2.width / 2, maxX: o2.center.x + o2.width / 2, minY: o2.center.y - o2.height / 2, maxY: o2.center.y + o2.height / 2 }, ...this.validationParams.boardGeometry, obstacles: h2.map((n3) => ({ ...n3, connectedTo: [...n3.connectedTo, ...e33.filter((e34) => vo(n3, e34, t2)).map((e34) => e34.connectionName)] })), connections: e33.map((e34) => ({ name: e34.connectionName, rootConnectionName: e34.rootConnectionName, __netConnectionName: e34.rootConnectionName ?? e34.connectionName, pointsToConnect: [...[e34.route[0], e34.route.at(-1)].map((e35) => ({ x: e35.x, y: e35.y, layer: Po(e35.z, n2) })), ...h2.filter((n3) => vo(n3, e34, t2)).flatMap((e35) => {
const t3 = e35.circuitJsonMetadata?.pcb_port_id;
return t3 ? [{ ...e35.center, layer: Po(0, n2), pcb_port_id: t3 }] : [];
})] })) }, u2 = NL(d2, e33.map((e34, t3) => ({ type: "pcb_trace", pcb_trace_id: `${e34.connectionName}_${t3}`, connection_name: e34.connectionName, route: Ro(e34, n2) })));
this.validationParams.boardGeometry && u2.push(wL(d2));
const { errors: p2 } = RM(u2, { traceClearance: this.traceMargin, viaClearance: this.traceMargin, includeTraceContinuity: false }), m2 = S_({ srj: { ...d2, traces: undefined }, routes: e33 });
this.stats.boardDrcIssueCount = p2.length + m2.length, (p2.length > 0 || m2.length > 0) && (this.solved = false, this.failed = true, this.error = `A13 candidate fails board copper validation: ${p2[0]?.message ?? "fixed obstacle clearance violation"}`);
}
};
var AL = (e33) => `${e33.x.toFixed(6)},${e33.y.toFixed(6)},${e33.z}`;
var OL = (e33) => [e33.route[0], e33.route[e33.route.length - 1]];
var kL = (e33, t2, n2) => {
const o2 = new Map, i2 = (e34, t3) => {
o2.has(e34) || o2.set(e34, new Set), o2.has(t3) || o2.set(t3, new Set), o2.get(e34).add(t3), o2.get(t3).add(e34);
};
for (const n3 of e33)
if (n3.connectionName === t2 && n3.route.length !== 0) {
if (n3.route.length === 1) {
const e34 = AL(n3.route[0]);
o2.has(e34) || o2.set(e34, new Set);
continue;
}
for (let e34 = 0;e34 < n3.route.length - 1; e34++)
i2(AL(n3.route[e34]), AL(n3.route[e34 + 1]));
}
const r2 = new Set([n2]), s2 = [n2];
for (;s2.length > 0; ) {
const e34 = s2.pop();
for (const t3 of o2.get(e34) ?? [])
r2.has(t3) || (r2.add(t3), s2.push(t3));
}
return r2;
};
var DL = Array.from({ length: 6 }, (e33, t2) => t2);
var LL = class extends Gs {
getSolverName() {
return "PortfolioSingleIntraNodeSolver";
}
constructorParams;
solvedRoutes = [];
nodeWithPortPoints;
connMap;
effort;
adaptiveSearchExpanded = false;
negotiatedSearchStarted = false;
enableNegotiatedSearch;
gridSearchSegmentWork;
gridSearchWorkScale;
rejectOverlappingTerminals;
precomputedIntraNodeRouteParams;
nodeSegmentCount;
totalCandidateWork = 0;
dynamicExpansionWorkBudget = 1;
candidateWorkBySolver = new WeakMap;
getSolvedSegmentCount(e33) {
const t2 = e33.solvedConnectionsMap;
if (!(t2 instanceof Map))
return null;
let n2 = 0;
for (const e34 of t2.values())
Array.isArray(e34) && (n2 += e34.length);
return n2;
}
getNodeSegmentCount() {
return this.nodeSegmentCount ??= Math.max(1, this.nodeWithPortPoints.portPointsInPairs?.length ?? new Set(this.nodeWithPortPoints.portPoints.map((e33) => e33.connectionName)).size), this.nodeSegmentCount;
}
getCandidateProgress(e33) {
if (e33 instanceof rr) {
if (e33.solved)
return 1;
const t3 = e33.connections.length;
if (t3 === 0)
return 0;
const n2 = e33.routedCount / t3, o2 = Math.max(0, (e33.routedCount - e33.conflictCount) / t3);
return Math.min(0.99, (n2 + o2) / 2);
}
const t2 = this.getSolvedSegmentCount(e33);
return t2 !== null ? Math.min(1, t2 / this.getNodeSegmentCount()) : Math.max(0, Math.min(1, e33.progress || 0));
}
constructor(e33) {
if (super(), this.nodeWithPortPoints = e33.nodeWithPortPoints, this.connMap = e33.connMap, this.constructorParams = e33, this.effort = e33.effort ?? 1, this.gridSearchSegmentWork = e33.gridSearchSegmentWork ?? 1e4, this.gridSearchWorkScale = e33.gridSearchWorkScale ?? 1, this.rejectOverlappingTerminals = e33.rejectOverlappingTerminals ?? false, this.enableNegotiatedSearch = e33.enableNegotiatedSearch ?? false, this.MAX_ITERATIONS = 20000000 * this.effort, this.GREEDY_MULTIPLIER = 5, this.MIN_SUBSTEPS = 100, this.rejectOverlappingTerminals) {
const t2 = this.nodeWithPortPoints.portPoints, n2 = e33.traceWidth ?? 0.15;
for (let e34 = 0;e34 < t2.length; e34++)
for (let o2 = e34 + 1;o2 < t2.length; o2++) {
const i2 = t2[e34], r2 = t2[o2];
if (i2.z === r2.z && (i2.rootConnectionName ?? i2.connectionName) !== (r2.rootConnectionName ?? r2.connectionName) && !this.connMap?.areIdsConnected(i2.connectionName, r2.connectionName) && Math.hypot(i2.x - r2.x, i2.y - r2.y) < n2 - 0.000001)
return this.failed = true, void (this.error = "Unrelated route terminals overlap at the requested trace width");
}
}
}
getGridSearchIterationBudget() {
const e33 = this.nodeWithPortPoints, t2 = e33.availableZ?.length ?? new Set(e33.portPoints.map((e34) => e34.z)).size, n2 = Math.floor(e33.width / 0.1) * Math.floor(e33.height / 0.1) * t2, o2 = t2 > 2 ? this.gridSearchWorkScale : 1;
return Math.round(o2 * Math.max(150000, (t2 <= 2 ? 1e4 : this.gridSearchSegmentWork) * this.getNodeSegmentCount() ** 2, Math.round(n2 * (8 + 1.2 * Math.sqrt(this.getNodeSegmentCount())) * this.effort)));
}
getCombinationDefs() {
return [["throughObstacle"], ["singleLayerNoDifferentRootIntersections"], ["multiHeadPolyLine"], ["majorCombinations", "orderings6", "cellSizeFactor"], ["noVias"], ["orderings50"], ["flipTraceAlignmentDirection", "orderings6"], ["closedFormSingleTrace"], ["highDensityA01"], ["highDensityA03"], ...this.enableNegotiatedSearch ? [["highDensityA13"]] : []];
}
getHyperParameterDefs() {
return [{ name: "singleLayerNoDifferentRootIntersections", possibleValues: [{ SINGLE_LAYER_NO_DIFFERENT_ROOT_INTERSECTIONS: true }] }, { 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: 0.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: DL.map((e33) => ({ SHUFFLE_SEED: e33 })) }, { name: "cellSizeFactor", possibleValues: [{ CELL_SIZE_FACTOR: 0.5 }, { CELL_SIZE_FACTOR: 1 }] }, { name: "flipTraceAlignmentDirection", possibleValues: [{ FLIP_TRACE_ALIGNMENT_DIRECTION: true }] }, { name: "noVias", possibleValues: [{ CELL_SIZE_FACTOR: 2, VIA_PENALTY_FACTOR_2: 10 }] }, { name: "orderings50", possibleValues: Array.from({ length: 20 }, (e33, t2) => ({ SHUFFLE_SEED: 100 + t2 })) }, { name: "throughObstacle", possibleValues: [{ THROUGH_OBSTACLE: true }] }, { name: "closedFormSingleTrace", possibleValues: [{ CLOSED_FORM_SINGLE_TRANSITION: true }] }, { name: "multiHeadPolyLine", possibleValues: [{ MULTI_HEAD_POLYLINE_SOLVER: true, SEGMENTS_PER_POLYLINE: 6, BOUNDARY_PADDING: 0.05 }, { MULTI_HEAD_POLYLINE_SOLVER: true, SEGMENTS_PER_POLYLINE: 6, BOUNDARY_PADDING: -0.05, ITERATION_PENALTY: 1e4, MINIMUM_FINAL_ACCEPTANCE_GAP: 0.001 }] }, { name: "highDensityA01", possibleValues: [{ HIGH_DENSITY_A01: true, SHUFFLE_SEED: DL[0] }] }, { name: "highDensityA03", possibleValues: [{ HIGH_DENSITY_A03: true }] }, { name: "highDensityA13", possibleValues: [{ HIGH_DENSITY_A13: true, SHUFFLE_SEED: 0 }] }];
}
initializeCandidateBudget(e33) {
if (e33 instanceof rr)
return;
const t2 = e33.setup;
typeof t2 == "function" && t2.call(e33), (e33 instanceof Mi || e33 instanceof Li) && (e33.MAX_ITERATIONS = Math.min(e33.MAX_ITERATIONS, this.getGridSearchIterationBudget()));
}
refreshDynamicIterationLimit() {
this.totalCandidateWork = 0, this.dynamicExpansionWorkBudget = 1;
const e33 = (this.supervisedSolvers ?? []).reduce((e34, { solver: t2 }) => {
if (t2 instanceof rr || (this.totalCandidateWork += t2.iterations, this.dynamicExpansionWorkBudget = Math.max(this.dynamicExpansionWorkBudget, t2.MAX_ITERATIONS), this.candidateWorkBySolver.set(t2, { iterations: t2.iterations, maxIterations: t2.MAX_ITERATIONS })), t2.solved || t2.failed)
return e34;
const n2 = Math.max(0, t2.MAX_ITERATIONS - t2.iterations + 1);
return e34 + Math.ceil(n2 / this.MIN_SUBSTEPS);
}, 0);
this.MAX_ITERATIONS = Math.max(this.iterations + 1, this.iterations + e33), this.stats.dynamicSupervisorIterationLimit = this.MAX_ITERATIONS;
}
initializeSolvers() {
super.initializeSolvers();
for (const { solver: e33 } of this.supervisedSolvers ?? [])
this.initializeCandidateBudget(e33);
this.refreshDynamicIterationLimit(), this.stats.dynamicExpansionWorkBudget = this.dynamicExpansionWorkBudget;
}
addSupervisedCandidate(e33) {
const t2 = this.generateSolver(e33);
this.initializeCandidateBudget(t2);
const n2 = this.computeG(t2);
this.supervisedSolvers.push({ hyperParameters: e33, solver: t2, h: 0, g: n2, f: n2 });
}
expandAdaptiveSearch() {
if (!this.adaptiveSearchExpanded) {
this.adaptiveSearchExpanded = true;
for (const e33 of DL.slice(1))
this.addSupervisedCandidate({ HIGH_DENSITY_A01: true, SHUFFLE_SEED: e33 });
this.refreshDynamicIterationLimit(), this.stats.adaptiveSearchExpanded = true, this.stats.adaptiveSearchExpandedAtIteration = this.iterations, this.stats.candidateWorkAtExpansion = this.totalCandidateWork, this.stats.bestProgressAtExpansion = Math.max(0, ...(this.supervisedSolvers ?? []).map(({ solver: e33 }) => this.getCandidateProgress(e33)));
}
}
shouldExpandPortfolio() {
if (this.adaptiveSearchExpanded)
return false;
const e33 = this.dynamicExpansionWorkBudget;
return this.stats.dynamicExpansionWorkBudget = e33, this.totalCandidateWork >= e33;
}
_step() {
this.supervisedSolvers || this.initializeSolvers(), this.adaptiveSearchExpanded || this.getSupervisedSolverWithBestFitness() || this.expandAdaptiveSearch(), super._step(), !this.negotiatedSearchStarted && this.activeSubSolver instanceof rr && (this.negotiatedSearchStarted = true, this.stats.negotiatedSearchStartedAtIteration = this.iterations), this.solved || this.failed || !this.shouldExpandPortfolio() || this.expandAdaptiveSearch();
}
computeG(e33) {
if (e33 instanceof rr)
return e33.routingIterations / 1e6;
const t2 = this.candidateWorkBySolver.get(e33);
if (t2 && (this.totalCandidateWork += e33.iterations - t2.iterations, t2.iterations = e33.iterations, t2.maxIterations !== e33.MAX_ITERATIONS)) {
t2.maxIterations = e33.MAX_ITERATIONS, this.dynamicExpansionWorkBudget = 1;
for (const { solver: e34 } of this.supervisedSolvers ?? [])
e34 instanceof rr || (this.dynamicExpansionWorkBudget = Math.max(this.dynamicExpansionWorkBudget, e34.MAX_ITERATIONS));
}
return e33 instanceof Mi || e33 instanceof Li || e33 instanceof rr ? e33.iterations / 1e6 : e33?.hyperParameters?.MULTI_HEAD_POLYLINE_SOLVER ? 1000 + ((e33.hyperParameters?.ITERATION_PENALTY ?? 0) + e33.iterations) / 1e4 + 1e4 * (e33.hyperParameters.SEGMENTS_PER_POLYLINE - 3) : e33.iterations / 1e4;
}
computeH(e33) {
return e33 instanceof rr || this.adaptiveSearchExpanded ? 1 - this.getCandidateProgress(e33) : 1 - (e33.progress || 0);
}
generateSolver(e33) {
if (this.precomputedIntraNodeRouteParams ??= Cr(this.nodeWithPortPoints), e33.SINGLE_LAYER_NO_DIFFERENT_ROOT_INTERSECTIONS) {
if (!Ps.isApplicable(this.nodeWithPortPoints)) {
const e34 = new wr({ nodeWithPortPoints: this.nodeWithPortPoints, connMap: this.connMap, traceWidth: this.constructorParams.traceWidth, viaDiameter: this.constructorParams.viaDiameter, obstacleMargin: this.constructorParams.obstacleMargin, precomputedIntraNodeRouteParams: this.precomputedIntraNodeRouteParams });
return e34.failed = true, e34.error = "Single-layer no-different-root-intersection solver not applicable", e34;
}
return new Ps({ nodeWithPortPoints: this.nodeWithPortPoints, traceWidth: this.constructorParams.traceWidth, viaDiameter: this.constructorParams.viaDiameter });
}
if (e33.HIGH_DENSITY_A13) {
const t2 = Math.max(1, Math.round(50000000 * this.effort)), n2 = new EL({ obstacles: this.constructorParams.obstacles ?? [], boardGeometry: this.constructorParams.boardGeometry, connMap: this.connMap, layerCount: this.constructorParams.layerCount ?? 2, nodeWithPortPoints: this.nodeWithPortPoints, cellSizeMm: 0.1, viaDiameter: this.constructorParams.viaDiameter ?? 0.3, viaMinDistFromBorder: (this.constructorParams.viaDiameter ?? 0.3) / 2, traceThickness: this.constructorParams.traceWidth ?? 0.15, traceMargin: 0.1, stepMultiplier: 1000, maxSearchIterations: t2, maxRounds: Math.max(1, Math.round(200 * this.effort)), hyperParameters: { shuffleSeed: e33.SHUFFLE_SEED ?? 0 } });
return n2.MAX_ITERATIONS = 2 * t2, n2;
}
if (e33.HIGH_DENSITY_A01) {
return new Mi({ nodeWithPortPoints: this.nodeWithPortPoints, cellSizeMm: 0.1, viaDiameter: this.constructorParams.viaDiameter ?? 0.3, viaMinDistFromBorder: (this.constructorParams.viaDiameter ?? 0.3) / 2, traceMargin: 0.1, traceThickness: this.constructorParams.traceWidth ?? 0.15, effort: this.effort, hyperParameters: { shuffleSeed: e33.SHUFFLE_SEED ?? 0 } });
}
if (e33.HIGH_DENSITY_A03) {
return new Li({ nodeWithPortPoints: this.nodeWithPortPoints, highResolutionCellSize: 0.1, highResolutionCellThickness: 8, lowResolutionCellSize: 0.4, viaDiameter: this.constructorParams.viaDiameter ?? 0.3, viaMinDistFromBorder: (this.constructorParams.viaDiameter ?? 0.3) / 2, traceMargin: 0.1, traceThickness: 0.1, effort: this.effort, hyperParameters: e33 });
}
return e33.CLOSED_FORM_TWO_TRACE_SAME_LAYER ? new Hs({ nodeWithPortPoints: this.nodeWithPortPoints, viaDiameter: this.constructorParams.viaDiameter }) : e33.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING ? new Ws({ nodeWithPortPoints: this.nodeWithPortPoints, viaDiameter: this.constructorParams.viaDiameter }) : e33.CLOSED_FORM_SINGLE_TRANSITION ? new ws({ nodeWithPortPoints: this.nodeWithPortPoints, viaDiameter: this.constructorParams.viaDiameter }) : e33.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 }) : e33.MULTI_HEAD_POLYLINE_SOLVER ? new is({ nodeWithPortPoints: this.nodeWithPortPoints, connMap: this.connMap, hyperParameters: e33, viaDiameter: this.constructorParams.viaDiameter }) : new Er({ ...this.constructorParams, hyperParameters: e33, precomputedIntraNodeRouteParams: this.precomputedIntraNodeRouteParams });
}
onSolve(e33) {
let t2;
t2 = e33.solver instanceof Mi || e33.solver instanceof Li || e33.solver instanceof rr ? e33.solver.getOutput() : e33.solver.solvedRoutes;
const n2 = t2.map((e34) => {
const t3 = this.nodeWithPortPoints.portPoints.find((t4) => t4.connectionName === e34.connectionName);
return t3?.rootConnectionName ? { ...e34, rootConnectionName: t3.rootConnectionName } : e34;
});
this.solvedRoutes = ((e34, t3) => {
const n3 = [...e34], o2 = new Map;
for (const e35 of t3.portPoints) {
const t4 = o2.get(e35.connectionName) ?? [];
t4.push(e35), o2.set(e35.connectionName, t4);
}
for (const [e35, t4] of o2) {
if (t4.length <= 1)
continue;
const o3 = t4[0]?.rootConnectionName ?? e35, i2 = new Set(t4.map(AL));
let r2 = kL(n3, e35, AL(t4[0]));
for (const s2 of t4.slice(1)) {
const a2 = AL(s2);
if (r2.has(a2))
continue;
const c2 = n3.find((t5) => {
if ((t5.rootConnectionName ?? t5.connectionName) !== o3)
return false;
if (t5.connectionName === e35)
return false;
const [n4, s3] = OL(t5);
if (!n4 || !s3)
return false;
const c3 = AL(n4), l2 = AL(s3);
return r2.has(c3) && l2 === a2 || r2.has(l2) && c3 === a2 || i2.has(c3) && i2.has(l2) && (c3 === a2 || l2 === a2);
});
c2 && (n3.push({ ...c2, connectionName: e35, rootConnectionName: o3, route: c2.route.map((t5) => ({ ...t5, connectionName: e35, rootConnectionName: o3 })), vias: c2.vias.map((e36) => ({ ...e36 })), jumpers: c2.jumpers?.map((e36) => ({ ...e36, start: { ...e36.start }, end: { ...e36.end } })) }), r2 = kL(n3, e35, AL(t4[0])));
}
}
return n3;
})(n2, this.nodeWithPortPoints);
}
};
function zL(e33, t2, n2, o2, i2) {
const r2 = n2 - t2, s2 = i2 - o2, a2 = 0.000001;
if (Math.abs(e33.y - i2) < a2)
return e33.x - t2;
if (Math.abs(e33.x - n2) < a2)
return r2 + (i2 - e33.y);
if (Math.abs(e33.y - o2) < a2)
return r2 + s2 + (n2 - e33.x);
if (Math.abs(e33.x - t2) < a2)
return 2 * r2 + s2 + (e33.y - o2);
const c2 = Math.abs(e33.y - i2), l2 = Math.abs(e33.x - n2), h2 = Math.abs(e33.y - o2), d2 = Math.abs(e33.x - t2), u2 = Math.min(c2, l2, h2, d2);
return u2 === c2 ? Math.max(0, Math.min(r2, e33.x - t2)) : u2 === l2 ? r2 + Math.max(0, Math.min(s2, i2 - e33.y)) : u2 === h2 ? r2 + s2 + Math.max(0, Math.min(r2, n2 - e33.x)) : 2 * r2 + s2 + Math.max(0, Math.min(s2, e33.y - o2));
}
function BL(e33, t2, n2 = 0.000001) {
return Math.abs(e33 - t2) < n2;
}
function FL(e33) {
if (e33.length < 2)
return 0;
const t2 = e33.map(([e34, t3]) => e34 < t3 ? [e34, t3] : [t3, e34]);
let n2 = 0;
for (let e34 = 0;e34 < t2.length; e34++) {
const [o2, i2] = t2[e34];
for (let r2 = e34 + 1;r2 < t2.length; r2++) {
const [e35, s2] = t2[r2];
BL(o2, e35) || BL(o2, s2) || BL(i2, e35) || BL(i2, s2) || (o2 < e35 && e35 < i2 && i2 < s2 || e35 < o2 && o2 < s2 && s2 < i2) && n2++;
}
}
return n2;
}
var jL = (e33) => {
const t2 = e33.center.x - e33.width / 2, n2 = e33.center.x + e33.width / 2, o2 = e33.center.y - e33.height / 2, i2 = e33.center.y + e33.height / 2, r2 = new Map;
for (const t3 of e33.portPoints) {
const e34 = r2.get(t3.connectionName) ?? [];
e34.some((e35) => e35.x === t3.x && e35.y === t3.y && e35.z === t3.z) || e34.push({ x: t3.x, y: t3.y, z: t3.z }), r2.set(t3.connectionName, e34);
}
const s2 = new Map, a2 = [];
let c2 = 0;
for (const [e34, l3] of r2) {
if (l3.length < 2)
continue;
const e35 = l3[0], r3 = l3[1], h2 = zL(e35, t2, n2, o2, i2), d2 = zL(r3, t2, n2, o2, i2);
if (e35.z === r3.z) {
const t3 = e35.z, n3 = s2.get(t3) ?? [];
n3.push([h2, d2]), s2.set(t3, n3);
} else
c2++, a2.push([h2, d2]);
}
let l2 = 0;
for (const [e34, t3] of s2)
l2 += FL(t3);
return { numSameLayerCrossings: l2, numEntryExitLayerChanges: c2, numTransitionPairCrossings: FL(a2) };
};
var $L = (e33) => e33.availableZ?.length ? [...new Set(e33.availableZ)].sort((e34, t2) => e34 - t2) : [...new Set(e33.portPoints.map((e34) => e34.z ?? 0))].sort((e34, t2) => e34 - t2);
var YL = (e33) => $L(e33).length === 1 && jL(e33).numSameLayerCrossings > 0;
var XL = (e33, t2, n2) => {
const o2 = new Map, [i2] = $L(e33);
for (const t3 of e33.portPoints)
o2.set(t3.connectionName, [...o2.get(t3.connectionName) ?? [], t3]);
return Array.from(o2.entries()).flatMap(([o3, r2]) => {
if (r2.length < 2)
return [];
const s2 = r2[0], a2 = r2[r2.length - 1];
return [{ connectionName: o3, rootConnectionName: s2.rootConnectionName, regionId: e33.capacityMeshNodeId, traceThickness: t2, viaDiameter: n2, route: [{ x: s2.x, y: s2.y, z: i2 ?? s2.z ?? 0 }, { x: a2.x, y: a2.y, z: i2 ?? a2.z ?? 0 }], vias: [] }];
});
};
var WL = XL;
var VL = (e33, t2, n2) => ({ ...e33, x: t2.x + (e33.x - t2.x) * n2, y: t2.y + (e33.y - t2.y) * n2 });
var HL = (e33, t2, n2) => VL(e33, t2, n2);
var GL = ["#dc2626", "#2563eb", "#16a34a", "#ca8a04", "#9333ea", "#0891b2"];
var UL = (e33, t2, n2 = []) => [e33, t2 ? `rootConnectionName: ${t2}` : undefined, ...n2].filter(Boolean).join(`
`);
var ZL = class extends ai {
getSolverName() {
return "GrowShrinkHighDensityIntraNodeSolver";
}
constructorParams;
nodeWithPortPoints;
solvedRoutes = [];
failedSolvers = [];
activeSubSolver = null;
winningSolver;
scaleFactor = 1;
growthAttempts = 0;
maxGrowthAttempts;
minimumGrowthAttempts;
constructor(e33) {
super(), this.constructorParams = e33, this.nodeWithPortPoints = e33.nodeWithPortPoints;
const t2 = Math.min(this.nodeWithPortPoints.width, this.nodeWithPortPoints.height), n2 = t2 > 0 ? Math.max(0, Math.ceil(Math.log2((e33.viaDiameter ?? 0.3) / t2))) : 0;
let o2 = Number.POSITIVE_INFINITY;
const i2 = this.nodeWithPortPoints.portPoints;
for (let e34 = 0;e34 < i2.length; e34++)
for (let t3 = e34 + 1;t3 < i2.length; t3++) {
const n3 = i2[e34], r3 = i2[t3];
if (n3.z !== r3.z || (n3.rootConnectionName ?? n3.connectionName) === (r3.rootConnectionName ?? r3.connectionName))
continue;
const s3 = Math.hypot(n3.x - r3.x, n3.y - r3.y);
s3 > 0.000000001 && (o2 = Math.min(o2, s3));
}
const r2 = Math.max(0, Math.ceil(Math.log2((e33.traceWidth ?? 0.15) / o2))), s2 = Math.max(n2, r2);
if (this.maxGrowthAttempts = e33.maxGrowthAttempts ?? 3 + s2, this.minimumGrowthAttempts = Math.min(e33.maxGrowthAttempts ?? 3 + n2, Math.max(n2, 0, r2 - 1)), this.MAX_ITERATIONS = 20000000 * (e33.effort ?? 1) * (this.maxGrowthAttempts + 1), YL(this.nodeWithPortPoints)) {
if (!e33.fallbackToInvalidGeometryOnFailure)
return this.failed = true, this.progress = 1, void (this.error = "GrowShrinkHighDensityIntraNodeSolver cannot route an impossible single-layer crossing");
this.solvedRoutes = WL(this.nodeWithPortPoints, e33.traceWidth ?? 0.15, e33.viaDiameter ?? 0.3), this.solved = true, this.progress = 1, this.stats = { invalidGeometryFallback: true, reason: "single-layer node has same-layer crossings" };
}
}
getConstructorParams() {
return this.constructorParams;
}
createActiveSubSolver() {
const { growShrinkSolutionValidator: e33, ...t2 } = this.constructorParams;
var n2, o2;
this.activeSubSolver = new LL({ ...t2, enableNegotiatedSearch: this.scaleFactor === 1 && (t2.enableNegotiatedSearch ?? true), nodeWithPortPoints: (n2 = this.nodeWithPortPoints, o2 = this.scaleFactor, { ...n2, width: n2.width * o2, height: n2.height * o2, portPoints: n2.portPoints.map((e34) => HL(e34, n2.center, o2)), portPointsInPairs: n2.portPointsInPairs?.map(([e34, t3]) => [HL(e34, n2.center, o2), HL(t3, n2.center, o2)]) }) }), this.constructorParams.maxInnerIterationsPerGrowthAttempt && (this.activeSubSolver.MAX_ITERATIONS = this.constructorParams.maxInnerIterationsPerGrowthAttempt);
}
acceptSolution(e33) {
const t2 = this.scaleFactor === 1 ? e33.solvedRoutes : e33.solvedRoutes.map((e34) => ((e35, t3, n2) => ({ ...e35, route: e35.route.map((e36) => VL(e36, t3, n2)), vias: e35.vias.map((e36) => VL(e36, t3, n2)), jumpers: e35.jumpers?.map((e36) => ({ ...e36, start: VL(e36.start, t3, n2), end: VL(e36.end, t3, n2) })) }))(e34, this.nodeWithPortPoints.center, 1 / this.scaleFactor));
return this.constructorParams.growShrinkSolutionValidator && !this.constructorParams.growShrinkSolutionValidator(t2) ? (e33.solved = false, e33.failed = true, e33.error = "High-density scale solution rejected by validator", false) : (this.winningSolver = e33, this.error = null, this.solvedRoutes = t2, this.solved = true, this.failed = false, true);
}
computeProgress() {
return Math.min(0.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 = XL(this.nodeWithPortPoints, this.constructorParams.traceWidth ?? 0.15, this.constructorParams.viaDiameter ?? 0.3), this.solved = true, this.failed = false, this.progress = 1, this.stats = { ...this.stats, invalidGeometryFallback: true, reason: "growth attempts exhausted", lastError: this.error }, void (this.error = null)) : (this.failed = true, void (this.error = `GrowShrinkHighDensityIntraNodeSolver failed after resizing to ${this.scaleFactor}x. Last error: ${this.error}`));
this.growthAttempts = Math.max(this.growthAttempts + 1, this.minimumGrowthAttempts), this.scaleFactor = 2 ** this.growthAttempts;
}
}
visualize() {
const e33 = this.activeSubSolver?.visualize() ?? this.winningSolver?.visualize();
return e33 || (this.solvedRoutes.length > 0 ? { title: this.stats.invalidGeometryFallback ? "Invalid same-layer crossing geometry" : "Grow/shrink high density routes", lines: this.solvedRoutes.flatMap((e34, t2) => e34.route.slice(0, -1).map((n2, o2) => ({ points: [n2, e34.route[o2 + 1]], strokeColor: GL[t2 % GL.length], strokeWidth: e34.traceThickness, layer: `z${n2.z}`, label: UL(e34.connectionName, e34.rootConnectionName, [`z${n2.z}`, this.stats.invalidGeometryFallback ? "invalid fallback route" : undefined].filter(Boolean)) }))), points: this.nodeWithPortPoints.portPoints.map((e34) => ({ x: e34.x, y: e34.y, color: GL[Math.max(0, this.solvedRoutes.findIndex((t2) => t2.connectionName === e34.connectionName)) % GL.length], label: UL(e34.connectionName, e34.rootConnectionName, [`z${e34.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(`
`) }], circles: [] } : e33 ?? { lines: [], points: [], rects: [], circles: [] });
}
};
var qL = (e33, t2, n2 = []) => [e33, t2 ? `rootConnectionName: ${t2}` : undefined, ...n2].filter(Boolean).join(`
`);
var JL = class extends ai {
getSolverName() {
return "HighDensitySolver";
}
unsolvedNodePortPoints;
routes;
colorMap;
defaultViaDiameter = 0.3;
defaultTraceThickness = 0.15;
viaDiameter;
traceWidth;
obstacleMargin;
effort;
obstacles;
layerCount;
useGrowShrinkHighDensityIntraNodeSolver;
enableNegotiatedSearch;
gridSearchSegmentWork;
gridSearchWorkScale;
rejectOverlappingTerminals;
boardGeometry;
preserveTerminalPcbPortIds;
growShrinkMaxInnerIterationsPerGrowthAttempt;
growShrinkFallbackToInvalidGeometryOnFailure;
growShrinkSolutionValidator;
captureSearchDebug;
failedSolvers;
activeSubSolver = null;
connMap;
nodePfById;
nodeSolveMetadataById;
constructor({ nodePortPoints: e33, colorMap: t2, connMap: n2, viaDiameter: o2, traceWidth: i2, obstacleMargin: r2, effort: s2, nodePfById: a2, obstacles: c2, layerCount: l2, useGrowShrinkHighDensityIntraNodeSolver: h2, enableNegotiatedSearch: d2 = false, gridSearchSegmentWork: u2 = 1e4, gridSearchWorkScale: p2 = 1, rejectOverlappingTerminals: m2 = false, boardGeometry: g2, preserveTerminalPcbPortIds: f2, growShrinkMaxInnerIterationsPerGrowthAttempt: _2, growShrinkFallbackToInvalidGeometryOnFailure: y2, growShrinkSolutionValidator: b2, captureSearchDebug: x2 }) {
super(), this.unsolvedNodePortPoints = e33, this.colorMap = t2 ?? {}, this.connMap = n2, this.routes = [], this.failedSolvers = [], this.effort = s2 ?? 1, this.viaDiameter = o2 ?? this.defaultViaDiameter, this.traceWidth = i2 ?? this.defaultTraceThickness, this.obstacleMargin = r2 ?? 0.15, this.obstacles = c2 ?? [], this.layerCount = l2 ?? 2, this.enableNegotiatedSearch = d2, this.gridSearchSegmentWork = u2, this.gridSearchWorkScale = p2, this.rejectOverlappingTerminals = m2, this.boardGeometry = g2, this.useGrowShrinkHighDensityIntraNodeSolver = h2 ?? false, this.preserveTerminalPcbPortIds = f2 ?? false, this.growShrinkMaxInnerIterationsPerGrowthAttempt = _2, this.growShrinkFallbackToInvalidGeometryOnFailure = y2 ?? false, this.growShrinkSolutionValidator = b2, this.captureSearchDebug = x2 ?? true, this.MAX_ITERATIONS = 1e7 * this.effort * (this.useGrowShrinkHighDensityIntraNodeSolver ? 4 : 1), this.nodePfById = a2 instanceof Map ? new Map(a2) : new Map(Object.entries(a2 ?? {})), this.nodeSolveMetadataById = new Map, this.stats = { solverNodeCount: {}, difficultNodePfs: {}, highDensityResizeCount: 0 };
}
getSolvedNodeSolverType(e33) {
return e33 instanceof ZL && e33.winningSolver ? this.getSolvedNodeSolverType(e33.winningSolver) : e33 instanceof LL && e33.winningSolver ? this.getConcreteSolverTypeName(e33.winningSolver) : this.getConcreteSolverTypeName(e33);
}
recordNodeSolveMetadata(e33, t2) {
const n2 = e33.nodeWithPortPoints, o2 = this.nodePfById.get(n2.capacityMeshNodeId) ?? null;
this.nodeSolveMetadataById.set(n2.capacityMeshNodeId, { node: n2, status: t2, solverType: this.getSolvedNodeSolverType(e33), iterations: e33.iterations, routeCount: e33.solvedRoutes.length, nodePf: o2, error: e33.error ?? undefined });
}
createNodeMarkerLabel(e33, t2) {
return ["hd_node_marker", `node: ${e33}`, `status: ${t2.status}`, `solver: ${t2.solverType}`, `iterations: ${t2.iterations}`, `routes: ${t2.routeCount}`, `nodePf: ${t2.nodePf ?? "n/a"}`, `portPoints: ${t2.node.portPoints.length}`, ...t2.error ? [`error: ${t2.error}`] : []].join(`
`);
}
getConcreteSolverTypeName(e33) {
if (e33 instanceof Er) {
const t2 = this.getIntraNodeStrategyName(e33.hyperParameters);
return e33.cacheHit ? `${t2} [cached]` : t2;
}
return e33 instanceof wr ? this.getIntraNodeStrategyName(e33.hyperParameters) : e33.getSolverName();
}
getIntraNodeStrategyName(e33) {
return e33?.MULTI_HEAD_POLYLINE_SOLVER ? "MultiHeadPolyLineIntraNodeSolver3" : e33?.SINGLE_LAYER_NO_DIFFERENT_ROOT_INTERSECTIONS ? "SingleLayerNoDifferentRootIntersectionsIntraNodeSolver" : e33?.CLOSED_FORM_SINGLE_TRANSITION ? "SingleTransitionIntraNodeSolver" : e33?.CLOSED_FORM_TWO_TRACE_SAME_LAYER ? "TwoCrossingRoutesHighDensitySolver" : e33?.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING ? "SingleTransitionCrossingRouteSolver" : e33?.HIGH_DENSITY_A01 ? "HighDensitySolverA01" : e33?.HIGH_DENSITY_A03 ? "HighDensitySolverA03" : "SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost";
}
recordSolvedNodeStats(e33, t2) {
const n2 = this.getSolvedNodeSolverType(e33), o2 = this.stats.solverNodeCount, i2 = this.stats.difficultNodePfs;
o2[n2] = (o2[n2] ?? 0) + 1;
const r2 = this.nodePfById.get(t2.capacityMeshNodeId) ?? null;
r2 !== null && r2 > 0.05 && (i2[n2] || (i2[n2] = []), i2[n2].push(r2));
}
recordResizeStats(e33) {
e33 instanceof ZL && (this.stats.highDensityResizeCount = (this.stats.highDensityResizeCount ?? 0) + e33.growthAttempts);
}
getSolvedRoutesWithTerminalPcbPortIds(e33) {
const t2 = e33.nodeWithPortPoints.portPoints.filter((e34) => e34.pcb_port_id !== undefined);
if (t2.length === 0)
return e33.solvedRoutes;
const n2 = (e34, n3) => {
const o2 = t2.filter((t3) => t3.connectionName === e34.connectionName && t3.x === n3.x && t3.y === n3.y && t3.z === n3.z);
if (o2.length > 1)
throw new Error(`HighDensitySolver found multiple PCB terminals at an endpoint of "${e34.connectionName}"`);
const i2 = o2[0];
if (i2?.pcb_port_id)
return i2.pcb_port_id;
};
return e33.solvedRoutes.map((e34) => ({ ...e34, startPcbPortId: e34.route[0] ? n2(e34, e34.route[0]) : undefined, endPcbPortId: e34.route.length > 1 ? n2(e34, e34.route[e34.route.length - 1]) : undefined }));
}
_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 (this.unsolvedNodePortPoints.length === 0)
return this.failedSolvers.length > 0 ? (this.solved = false, this.failed = true, this.error = `Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0, 5).map((e34) => e34.nodeWithPortPoints.capacityMeshNodeId)}. err0: ${this.failedSolvers[0].error}.`, void this.updateCacheStats()) : (this.solved = true, void this.updateCacheStats());
const e33 = { nodeWithPortPoints: this.unsolvedNodePortPoints.pop(), enableNegotiatedSearch: this.enableNegotiatedSearch, gridSearchSegmentWork: this.gridSearchSegmentWork, gridSearchWorkScale: this.gridSearchWorkScale, rejectOverlappingTerminals: this.rejectOverlappingTerminals, boardGeometry: this.boardGeometry, 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 ZL(e33) : new LL(e33), this.updateCacheStats();
}
updateCacheStats() {
const e33 = io();
this.stats.intraNodeCacheHits = e33.cacheHits, this.stats.intraNodeCacheMisses = e33.cacheMisses;
}
visualize() {
let e33 = { lines: [], points: [], rects: [], circles: [] };
for (const t2 of this.routes) {
const n2 = gi(t2.route, t2.connectionName, this.colorMap[t2.connectionName]);
for (const o2 of n2)
e33.lines.push({ points: o2.points, label: qL(t2.connectionName, t2.rootConnectionName), strokeColor: o2.z === 0 ? o2.color : Oo(o2.color, 0.5), layer: `z${o2.z}`, strokeWidth: t2.traceThickness, strokeDash: o2.z !== 0 ? [0.1, 0.3] : undefined });
for (const n3 of t2.vias)
e33.circles.push({ center: n3, layer: "z0,1", radius: t2.viaDiameter / 2, fill: this.colorMap[t2.connectionName], label: qL(t2.connectionName, t2.rootConnectionName, ["via"]) });
}
if (this.solved || this.failed)
for (const [t2, n2] of this.nodeSolveMetadataById) {
const o2 = n2.node.center.x - n2.node.width / 2, i2 = n2.node.center.x + n2.node.width / 2, r2 = n2.node.center.y - n2.node.height / 2, s2 = n2.node.center.y + n2.node.height / 2, a2 = this.createNodeMarkerLabel(t2, n2), c2 = n2.status === "solved" ? "blue" : "red";
if (e33.lines.push({ points: [{ x: o2, y: r2 }, { x: i2, y: r2 }], layer: "hd_node_boundaries", strokeColor: c2, strokeDash: "6, 4", strokeWidth: 0.03, label: a2 }, { points: [{ x: i2, y: r2 }, { x: i2, y: s2 }], layer: "hd_node_boundaries", strokeColor: c2, strokeDash: "6, 4", strokeWidth: 0.03, label: a2 }, { points: [{ x: i2, y: s2 }, { x: o2, y: s2 }], layer: "hd_node_boundaries", strokeColor: c2, strokeDash: "6, 4", strokeWidth: 0.03, label: a2 }, { points: [{ x: o2, y: s2 }, { x: o2, y: r2 }], layer: "hd_node_boundaries", strokeColor: c2, strokeDash: "6, 4", strokeWidth: 0.03, label: a2 }), n2.status === "solved")
e33.points.push({ x: n2.node.center.x, y: n2.node.center.y, color: c2, layer: "hd_node_markers", label: a2 });
else {
e33.lines.push({ points: [{ x: 0, y: 0 }, { x: n2.node.center.x, y: n2.node.center.y }], layer: "hd_failed_node_guides", strokeColor: "red", strokeDash: "8, 6", strokeWidth: 0.05, label: a2 });
const t3 = Math.max(0.1 * n2.node.width, 0.12), o3 = Math.max(0.1 * n2.node.height, 0.12);
e33.rects.push({ center: n2.node.center, layer: "hd_node_markers", width: t3, height: o3, fill: "red", label: a2 });
}
}
return this.activeSubSolver && (e33 = mi(e33, this.activeSubSolver.visualize())), e33;
}
};
var ez = (e33, t2 = 1, n2 = {}) => {
const o2 = n2.viaDiameter ?? 0.3, i2 = "width" in e33 ? e33.width : e33, r2 = n2.obstacleMargin ?? 0.2, s2 = "height" in e33 && typeof e33.height == "number" ? e33.height : i2;
if (!Number.isFinite(i2) || !Number.isFinite(s2))
return 0;
if (i2 <= 0 || s2 <= 0)
return 0;
const a2 = Math.min(i2, s2) / (o2 + r2), c2 = (Math.sqrt(i2 * s2) * Math.min(1.2, Math.max(0.85, a2 ** 0.05)) / (o2 / 2 + r2) / 2) ** 1.1 * t2;
return Number.isFinite(c2) ? e33.availableZ?.length === 1 && c2 > 1 ? 1 : c2 : 0;
};
var tz = (e33, t2 = 0.5, n2 = 16) => {
let o2 = 0, i2 = e33;
for (;o2 < n2; ) {
if (ez({ width: i2 }) <= t2)
break;
i2 /= 2, o2++;
}
return Math.max(1, o2);
};
var nz = (e33, t2, n2, o2) => {
if (e33?._containsTarget)
return 0;
if ((e33.availableZ?.length ?? 2) === 1 && (t2 > 0 || n2 > 0 || o2 > 0))
return 1;
const i2 = ((0.82 * t2 + 0.41 * n2 + 0.2 * o2) / 2) ** 1.1;
if (!Number.isFinite(i2))
return 1;
const r2 = ez(e33);
if (!Number.isFinite(r2) || r2 <= 0)
return i2 > 0 ? 1 : 0;
const s2 = i2 / r2;
if (Number.isNaN(s2))
throw new Error("calculateNodeProbabilityOfFailure returned NaN");
return Number.isFinite(s2) ? s2 : i2 > 0 ? 1 : 0;
};
var bz = class {
parent = {};
constructor(e33) {
for (const t2 of e33)
this.parent[t2] = t2;
}
find(e33) {
return this.parent[e33] === e33 ? e33 : this.parent[e33] = this.find(this.parent[e33]);
}
union(e33, t2) {
const n2 = this.find(e33), o2 = this.find(t2);
n2 !== o2 && (this.parent[o2] = n2);
}
getGroup(e33) {
const t2 = this.find(e33), n2 = [];
for (const e34 in this.parent)
this.find(e34) === t2 && n2.push(e34);
return n2;
}
};
var xz = class {
point;
left = null;
right = null;
constructor(e33) {
this.point = e33;
}
};
var vz = class {
root = null;
constructor(e33) {
e33.length > 0 && (this.root = this.buildTree(e33, 0));
}
buildTree(e33, t2) {
const n2 = t2 % 2 == 0 ? "x" : "y";
e33.sort((e34, t3) => e34[n2] - t3[n2]);
const o2 = Math.floor(e33.length / 2), i2 = new xz(e33[o2]);
return o2 > 0 && (i2.left = this.buildTree(e33.slice(0, o2), t2 + 1)), o2 < e33.length - 1 && (i2.right = this.buildTree(e33.slice(o2 + 1), t2 + 1)), i2;
}
findNearestNeighbor(e33) {
if (!this.root)
throw new Error("Tree is empty");
const t2 = this.root.point, n2 = this.distance(e33, t2);
return this.nearestNeighborSearch(this.root, e33, 0, t2, n2), t2;
}
nearestNeighborSearch(e33, t2, n2, o2, i2) {
if (!e33)
return o2;
const r2 = n2 % 2 ? "x" : "y", s2 = this.distance(t2, e33.point);
s2 < i2 && (o2 = e33.point, i2 = s2);
const a2 = t2[r2] - e33.point[r2], c2 = a2 <= 0 ? e33.left : e33.right, l2 = a2 <= 0 ? e33.right : e33.left;
return o2 = this.nearestNeighborSearch(c2, t2, n2 + 1, o2, i2), i2 = this.distance(t2, o2), Math.abs(a2) < i2 && (o2 = this.nearestNeighborSearch(l2, t2, n2 + 1, o2, i2)), o2;
}
findKNearestNeighbors(e33, t2) {
if (!this.root)
return [];
const n2 = [];
return this.kNearestNeighborSearch(this.root, e33, 0, n2, t2), n2.sort((e34, t3) => e34.distance - t3.distance).slice(0, t2).map((e34) => e34.point);
}
kNearestNeighborSearch(e33, t2, n2, o2, i2) {
if (!e33)
return;
const r2 = n2 % 2 ? "x" : "y", s2 = this.distance(t2, e33.point);
o2.push({ point: e33.point, distance: s2 });
const a2 = t2[r2] - e33.point[r2], c2 = a2 <= 0 ? e33.left : e33.right, l2 = a2 <= 0 ? e33.right : e33.left;
this.kNearestNeighborSearch(c2, t2, n2 + 1, o2, i2);
let h2 = 1 / 0;
o2.length >= i2 && (o2.sort((e34, t3) => e34.distance - t3.distance), h2 = o2[i2 - 1]?.distance || 1 / 0), (Math.abs(a2) < h2 || o2.length < i2) && this.kNearestNeighborSearch(l2, t2, n2 + 1, o2, i2);
}
distance(e33, t2) {
return Math.sqrt((e33.x - t2.x) ** 2 + (e33.y - t2.y) ** 2);
}
};
var Iz = class {
parent = new Map;
rank = new Map;
constructor(e33) {
for (const t2 of e33) {
const e34 = this.pointToKey(t2);
this.parent.set(e34, e34), this.rank.set(e34, 0);
}
}
pointToKey(e33) {
return `${e33.x},${e33.y}`;
}
find(e33) {
const t2 = this.pointToKey(e33);
if (!this.parent.has(t2))
throw new Error(`Point ${t2} not found in DisjointSet`);
let n2 = t2;
for (;n2 !== this.parent.get(n2); )
n2 = this.parent.get(n2);
let o2 = t2;
for (;o2 !== n2; ) {
const e34 = this.parent.get(o2);
this.parent.set(o2, n2), o2 = e34;
}
return n2;
}
union(e33, t2) {
const n2 = this.find(e33), o2 = this.find(t2);
if (n2 === o2)
return false;
const i2 = this.rank.get(n2) || 0, r2 = this.rank.get(o2) || 0;
return i2 < r2 ? this.parent.set(n2, o2) : i2 > r2 ? this.parent.set(o2, n2) : (this.parent.set(o2, n2), this.rank.set(n2, i2 + 1)), true;
}
};
function Sz(e33, t2 = {}) {
if (e33.length <= 1)
return [];
const n2 = [...e33], o2 = new vz(n2), i2 = [], r2 = Math.min(10, e33.length - 1);
for (const e34 of n2) {
const t3 = o2.findKNearestNeighbors(e34, r2 + 1);
for (const n3 of t3) {
if (e34.x === n3.x && e34.y === n3.y)
continue;
const t4 = Math.sqrt((e34.x - n3.x) ** 2 + (e34.y - n3.y) ** 2);
i2.push({ from: e34, to: n3, weight: t4 });
}
}
t2.extraEdges && i2.push(...t2.extraEdges), i2.sort((e34, t3) => e34.weight - t3.weight);
const s2 = new Iz(n2), a2 = [];
for (const e34 of i2)
if (s2.union(e34.from, e34.to) && (a2.push(e34), a2.length === n2.length - 1))
break;
return a2;
}
var Cz = (e33, t2) => {
const n2 = new Map;
for (const o3 of e33.pointsToConnect) {
if (!o3.pointId)
continue;
const e34 = t2.getNetConnectedToId(o3.pointId);
if (!e34)
continue;
const i2 = n2.get(e34) ?? [];
i2.push(o3), n2.set(e34, i2);
}
const o2 = [];
for (const e34 of n2.values()) {
const t3 = e34[0];
if (t3)
for (const n3 of e34.slice(1))
o2.push({ from: t3, to: n3, weight: 0 });
}
return o2;
};
var Pz = (e33, t2) => ({ zeroWeightEdges: Cz(e33, t2), arePointsConnected: (e34, n2) => Boolean(e34.pointId && n2.pointId && ((e35, t3, n3) => {
const o2 = e35.getNetConnectedToId(t3);
return !!o2 && o2 === e35.getNetConnectedToId(n3);
})(t2, e34.pointId, n2.pointId)) });
function Mz(e33) {
if (e33.pointId)
return e33.pointId;
const t2 = [...Co(e33)].sort().join("-");
return `${e33.x.toFixed(4)},${e33.y.toFixed(4)},${t2}`;
}
function wz(e33) {
if (e33.length === 0)
return [];
const t2 = e33.map((e34, t3) => `conn_${t3}`), n2 = new bz(t2), o2 = new Map;
e33.forEach((e34, t3) => {
const n3 = `conn_${t3}`;
e34.pointsToConnect.forEach((e35) => {
const t4 = Mz(e35);
o2.has(t4) || o2.set(t4, []), o2.get(t4).push(n3);
});
});
for (const e34 of o2.values())
if (e34.length > 1) {
const t3 = e34[0];
for (let o3 = 1;o3 < e34.length; o3++)
n2.union(t3, e34[o3]);
}
const i2 = new Map;
e33.forEach((e34, t3) => {
const o3 = `conn_${t3}`, r3 = n2.find(o3);
i2.has(r3) || i2.set(r3, []), i2.get(r3).push(e34);
});
const r2 = [];
for (const e34 of i2.values()) {
if (e34.length === 1) {
r2.push(e34[0]);
continue;
}
const t3 = new Map, n3 = new Set;
let o3 = false;
const i3 = [], s2 = new Set;
let a2;
e34.forEach((e35) => {
e35.pointsToConnect.forEach((e36) => t3.set(Mz(e36), e36));
const r3 = e35.__rootConnectionNames;
if (r3 && r3.length > 0)
for (const e36 of r3)
n3.add(e36);
else
n3.add(e35.name);
e35.isOffBoard && (o3 = true), e35.externallyConnectedPointIds && i3.push(...e35.externallyConnectedPointIds), e35.__netConnectionName && s2.add(e35.__netConnectionName), a2 === undefined && e35.nominalTraceWidth !== undefined && (a2 = e35.nominalTraceWidth);
});
const c2 = { name: e34.map((e35) => e35.name).join("__"), pointsToConnect: Array.from(t3.values()), isOffBoard: o3, externallyConnectedPointIds: i3.length > 0 ? i3 : undefined, __netConnectionName: s2.size > 0 ? Array.from(s2).join("__") : undefined, __rootConnectionNames: Array.from(n3), nominalTraceWidth: a2 };
r2.push(c2);
}
return r2;
}
var Nz = class extends ai {
constructor(e33, t2 = {}, n2) {
super(), this.ogSrj = e33, this.colorMap = t2;
const o2 = new Map;
for (const t3 of e33.buses ?? [])
if (t3.traceWidth !== undefined)
for (const e34 of t3.connectionNames)
o2.set(e34, Math.max(o2.get(e34) ?? 0, t3.traceWidth));
const i2 = e33.connections.map((e34) => {
const t3 = o2.get(e34.name);
return t3 === undefined ? e34 : { ...e34, nominalTraceWidth: Math.max(e34.nominalTraceWidth ?? 0, t3) };
});
this.unprocessedConnections = wz(i2), this.newConnections = [], this.initiallyConnectedMap = n2;
}
ogSrj;
colorMap;
getSolverName() {
return "NetToPointPairsSolver";
}
unprocessedConnections;
newConnections;
initiallyConnectedMap;
_step() {
if (this.unprocessedConnections.length === 0)
return void (this.solved = true);
const e33 = this.unprocessedConnections.pop(), { zeroWeightEdges: t2, arePointsConnected: n2 } = Pz(e33, this.initiallyConnectedMap);
if (e33.pointsToConnect.length === 2) {
const [t3, o3] = e33.pointsToConnect;
if (t3 && o3 && n2(t3, o3))
return;
return void this.newConnections.push({ ...e33, __rootConnectionNames: e33.__rootConnectionNames ?? [e33.name] });
}
const o2 = Sz(e33.pointsToConnect, { extraEdges: t2 });
let i2 = 0;
for (const t3 of o2)
n2(t3.from, t3.to) || this.newConnections.push({ ...e33, pointsToConnect: [t3.from, t3.to], name: `${e33.name}_mst${i2++}`, __rootConnectionNames: e33.__rootConnectionNames ?? [e33.name], __netConnectionName: e33.__netConnectionName });
}
getNewSimpleRouteJson() {
return { ...structuredClone(this.ogSrj), connections: structuredClone(this.newConnections) };
}
visualize() {
const e33 = { lines: [], points: [], rects: [], circles: [], coordinateSystem: "cartesian", title: "Net To Point Pairs Visualization" };
return this.unprocessedConnections.forEach((t2) => {
t2.pointsToConnect.forEach((t3) => {
e33.points.push({ x: t3.x, y: t3.y, color: "red", label: t3.pcb_port_id ?? t3.pointId });
});
const n2 = t2.pointsToConnect.length ** 2, o2 = ur(0), i2 = new Set;
for (let r2 = 0;r2 < Math.max(n2, 2 * t2.pointsToConnect.length); r2++) {
const n3 = Math.floor(o2() * t2.pointsToConnect.length), r3 = Math.floor(o2() * t2.pointsToConnect.length);
i2.has(`${n3}-${r3}`) || (i2.add(`${n3}-${r3}`), e33.lines.push({ points: [t2.pointsToConnect[n3], t2.pointsToConnect[r3]], strokeColor: "rgba(255,0,0,0.25)", label: t2.name }));
}
}), this.newConnections.forEach((t2) => {
const n2 = this.colorMap?.[t2.name] || "blue";
t2.pointsToConnect.forEach((t3) => {
e33.points.push({ x: t3.x, y: t3.y, color: n2, label: t3.pcb_port_id ?? t3.pointId });
});
for (let o2 = 0;o2 < t2.pointsToConnect.length - 1; o2++)
for (let i2 = o2 + 1;i2 < t2.pointsToConnect.length; i2++)
e33.lines.push({ points: [t2.pointsToConnect[o2], t2.pointsToConnect[i2]], strokeColor: n2, label: t2.name });
}), e33;
}
};
var Tz = class extends Nz {
constructor(e33, t2 = {}, n2) {
const o2 = e33.connections.flatMap((e34) => e34.pointsToConnect), i2 = new Map;
for (const e34 of o2)
e34.pointId && i2.set(e34.pointId, e34);
const r2 = o2.map((e34) => e34.pointId).filter((e34) => !!e34), s2 = new bz(r2), a2 = [];
for (const t3 of e33.connections)
t3.isOffBoard ? t3.pointsToConnect.length >= 2 && t3.pointsToConnect[0].pointId && t3.pointsToConnect[1].pointId && s2.union(t3.pointsToConnect[0].pointId, t3.pointsToConnect[1].pointId) : a2.push(t3);
super({ ...e33, connections: a2 }, t2, n2), this.ogSrj = e33, this.colorMap = t2, this.connectionPointDsu = s2, this.connectionPointMap = i2, this.ogSrj = e33;
}
ogSrj;
colorMap;
getSolverName() {
return "NetToPointPairsSolver2_OffBoardConnection";
}
connectionPointDsu;
connectionPointMap;
_findBestConnectionPointsFromDisjointSets(e33, t2) {
if (!e33.pointId || !t2.pointId)
return { pointsToConnect: [e33, t2] };
const n2 = this.connectionPointDsu.getGroup(e33.pointId).map((e34) => this.connectionPointMap.get(e34)), o2 = this.connectionPointDsu.getGroup(t2.pointId).map((e34) => this.connectionPointMap.get(e34));
let i2 = e33, r2 = t2, s2 = 1 / 0;
for (const e34 of n2)
for (const t3 of o2) {
const n3 = Math.sqrt(Math.pow(e34.x - t3.x, 2) + Math.pow(e34.y - t3.y, 2));
n3 < s2 && (s2 = n3, i2 = e34, r2 = t3);
}
return { pointsToConnect: [i2, r2] };
}
_step() {
if (this.unprocessedConnections.length === 0)
return void (this.solved = true);
const e33 = this.unprocessedConnections.pop(), { zeroWeightEdges: t2, arePointsConnected: n2 } = Pz(e33, this.initiallyConnectedMap);
if (e33.pointsToConnect.length === 2) {
const [t3, o3] = e33.pointsToConnect;
if (t3 && o3 && n2(t3, o3))
return;
const i3 = this._findBestConnectionPointsFromDisjointSets(e33.pointsToConnect[0], e33.pointsToConnect[1]);
return void this.newConnections.push({ ...e33, pointsToConnect: i3.pointsToConnect, __rootConnectionNames: e33.__rootConnectionNames ?? [e33.name] });
}
const o2 = Sz(e33.pointsToConnect, { extraEdges: t2 });
let i2 = 0;
for (const t3 of o2) {
if (n2(t3.from, t3.to))
continue;
const o3 = this._findBestConnectionPointsFromDisjointSets(t3.from, t3.to);
this.newConnections.push({ ...e33, pointsToConnect: o3.pointsToConnect, name: `${e33.name}_mst${i2++}`, __rootConnectionNames: e33.__rootConnectionNames ?? [e33.name], __netConnectionName: e33.__netConnectionName });
}
}
};
var Rz = class {
netMap;
idToNetMap;
constructor(e33) {
this.netMap = e33, this.idToNetMap = {};
for (const [t2, n2] of Object.entries(e33))
for (const e34 of n2)
this.idToNetMap[e34] = t2;
}
addConnections(e33) {
for (const t2 of e33) {
const e34 = new Set;
for (const n3 of t2) {
const t3 = this.idToNetMap[n3];
t3 && e34.add(t3);
}
let n2;
if (e34.size === 0)
n2 = `connectivity_net${Object.keys(this.netMap).length}`, this.netMap[n2] = [];
else if (e34.size === 1)
n2 = e34.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
else {
n2 = e34.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
for (const t3 of e34)
if (t3 !== n2) {
const e35 = this.netMap[n2], o2 = this.netMap[t3];
if (e35 && o2) {
e35.push(...o2), this.netMap[t3] = e35;
for (const t4 of e35)
this.idToNetMap[t4] = n2;
}
}
}
for (const e35 of t2) {
const t3 = this.netMap[n2];
t3 && !t3.includes(e35) && t3.push(e35), this.idToNetMap[e35] = n2;
}
}
}
getIdsConnectedToNet(e33) {
return this.netMap[e33] || [];
}
getNetConnectedToId(e33) {
return this.idToNetMap[e33];
}
areIdsConnected(e33, t2) {
if (e33 === t2)
return true;
const n2 = this.getNetConnectedToId(e33);
if (!n2)
return false;
const o2 = this.getNetConnectedToId(t2);
return !!o2 && (n2 === o2 || o2 === e33 || o2 === e33);
}
areAllIdsConnected(e33) {
if (e33.length === 0)
return true;
const t2 = this.getNetConnectedToId(e33[0]);
if (!t2)
return false;
for (const n2 of e33) {
const e34 = this.getNetConnectedToId(n2);
if (e34 === undefined)
return false;
if (e34 !== t2)
return false;
}
return true;
}
};
function Ez(e33, t2 = {}) {
const n2 = [], o2 = [], i2 = t2.color ?? "gray", r2 = t2.label, s2 = Wo[e33.footprint] ?? Wo["0603"], a2 = e33.end.x - e33.start.x, c2 = e33.end.y - e33.start.y, l2 = Math.abs(a2) > Math.abs(c2), h2 = l2 ? s2.padLength : s2.padWidth, d2 = l2 ? s2.padWidth : s2.padLength;
return n2.push({ center: e33.start, width: h2, height: d2, fill: Oo(i2, 0.5), stroke: "rgba(0, 0, 0, 0.5)", layer: "jumper", label: r2 ? `${r2} (start)` : undefined }), n2.push({ center: e33.end, width: h2, height: d2, fill: Oo(i2, 0.5), stroke: "rgba(0, 0, 0, 0.5)", layer: "jumper", label: r2 ? `${r2} (end)` : undefined }), o2.push({ points: [e33.start, e33.end], strokeColor: "rgba(100, 100, 100, 0.8)", strokeWidth: 0.3 * s2.padWidth, layer: "jumper-body" }), { rects: n2, lines: o2 };
}
function Az(e33, t2 = {}) {
const n2 = { rects: [], lines: [] };
for (const o2 of e33) {
const { rects: e34, lines: i2 } = Ez(o2, t2);
n2.rects.push(...e34), n2.lines.push(...i2);
}
return n2;
}
var Fz = class {
MAX_ITERATIONS = 1000;
solved = false;
failed = false;
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 (e33) {
throw this.error = `${this.getSolverName()} error: ${e33}`, console.error(this.error), this.failed = true, e33;
}
!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 = true), "computeProgress" in this && (this.progress = this.computeProgress());
}
}
_step() {}
getConstructorParams() {
throw new Error("getConstructorParams not implemented");
}
solve() {
const e33 = Date.now();
for (;!this.solved && !this.failed; )
this.step();
const t2 = Date.now();
this.timeToSolve = t2 - e33;
}
visualize() {
return { lines: [], points: [], rects: [], circles: [] };
}
tryFinalAcceptance() {}
preview() {
return { lines: [], points: [], rects: [], circles: [] };
}
};
var jz = class {
tree;
constructor(e33 = 9) {
this.tree = new tt(e33);
}
insert(e33, t2, n2, o2, i2) {
this.tree.insert({ minX: t2, minY: n2, maxX: o2, maxY: i2, data: e33 });
}
bulkLoad(e33) {
const t2 = e33.map(({ item: e34, minX: t3, minY: n2, maxX: o2, maxY: i2 }) => ({ minX: t3, minY: n2, maxX: o2, maxY: i2, data: e34 }));
this.tree.load(t2);
}
search(e33, t2, n2, o2) {
return this.tree.search({ minX: e33, minY: t2, maxX: n2, maxY: o2 }).map((e34) => e34.data);
}
clear() {
this.tree.clear();
}
};
var $z = class {
index;
items = [];
currentIndex = 0;
capacity;
constructor(e33) {
this.capacity = Math.max(1, e33), this.index = new je(this.capacity);
}
insert(e33, t2, n2, o2, i2) {
if (this.currentIndex >= this.index.numItems)
throw new Error("Exceeded initial capacity");
this.items[this.currentIndex] = e33, this.index.add(t2, n2, o2, i2), this.currentIndex++;
}
finish() {
this.index.finish();
}
search(e33, t2, n2, o2) {
return this.index.search(e33, t2, n2, o2).map((e34) => this.items[e34] || null).filter(Boolean);
}
clear() {
this.items = [], this.currentIndex = 0, this.index = new je(this.capacity);
}
};
var Yz = class {
idx;
storage = [];
constructor(e33 = "native", t2 = []) {
e33 === "flatbush" ? t2.length === 0 ? (this.idx = new jz, e33 = "rbush") : this.idx = new $z(t2.length) : this.idx = e33 === "rbush" ? new jz : new class {
shi = new Xz(t2);
insert(e34) {}
search(e34, t3, n2, o2) {
const i2 = (e34 + n2) / 2, r2 = (t3 + o2) / 2, s2 = n2 - e34, a2 = o2 - t3;
return this.shi.getNodesInArea(i2, r2, s2, a2);
}
clear() {}
}, t2.forEach((e34) => this.insert(e34)), e33 === "flatbush" && t2.length > 0 && this.idx.finish?.();
}
insert(e33) {
this.storage.push(e33), this.idx.insert(e33, e33.center.x - e33.width / 2, e33.center.y - e33.height / 2, e33.center.x + e33.width / 2, e33.center.y + e33.height / 2);
}
search(e33) {
return this.idx.search(e33.minX, e33.minY, e33.maxX, e33.maxY);
}
searchArea(e33, t2, n2, o2) {
return this.search({ minX: e33 - n2 / 2, minY: t2 - o2 / 2, maxX: e33 + n2 / 2, maxY: t2 + o2 / 2 });
}
};
var Xz = class {
constructor(e33) {
this.obstacles = e33, this.buckets = new Map;
for (let t2 = 0;t2 < e33.length; t2++) {
const n2 = e33[t2], o2 = n2.center.x - n2.width / 2, i2 = n2.center.y - n2.height / 2, r2 = n2.center.x + n2.width / 2, s2 = n2.center.y + n2.height / 2;
for (let e34 = o2;e34 <= r2; e34 += this.CELL_SIZE)
for (let o3 = i2;o3 <= s2; o3 += this.CELL_SIZE) {
const i3 = this.getBucketKey(e34, o3), r3 = this.buckets.get(i3);
r3 ? r3.push([n2, t2]) : this.buckets.set(i3, [[n2, t2]]);
}
}
}
obstacles;
buckets;
CELL_SIZE = 0.4;
getBucketKey(e33, t2) {
return `${Math.floor(e33 / this.CELL_SIZE)}x${Math.floor(t2 / this.CELL_SIZE)}`;
}
getNodesInArea(e33, t2, n2, o2) {
const i2 = [], r2 = new Set, s2 = t2 - o2 / 2, a2 = e33 + n2 / 2, c2 = t2 + o2 / 2;
for (let t3 = e33 - n2 / 2;t3 <= a2; t3 += this.CELL_SIZE)
for (let e34 = s2;e34 <= c2; e34 += this.CELL_SIZE) {
const n3 = this.getBucketKey(t3, e34), o3 = this.buckets.get(n3) || [];
for (const e35 of o3)
r2.has(e35[1]) || (r2.add(e35[1]), i2.push(e35[0]));
}
return i2;
}
};
var Wz = (e33) => ({ minX: Math.min(e33[0].x, e33[1].x), maxX: Math.max(e33[0].x, e33[1].x), minY: Math.min(e33[0].y, e33[1].y), maxY: Math.max(e33[0].y, e33[1].y) });
function Vz(e33, t2) {
const n2 = e33.x - t2.x, o2 = e33.y - t2.y;
return n2 * n2 + o2 * o2;
}
function Hz(e33, t2, n2) {
const o2 = Vz(t2, n2);
if (o2 === 0)
return Vz(e33, t2);
let i2 = ((e33.x - t2.x) * (n2.x - t2.x) + (e33.y - t2.y) * (n2.y - t2.y)) / o2;
i2 = Math.max(0, Math.min(1, i2));
return Vz(e33, { x: t2.x + i2 * (n2.x - t2.x), y: t2.y + i2 * (n2.y - t2.y) });
}
function Gz(e33, t2, n2, o2) {
if (_t(e33, t2, n2, o2))
return 0;
const i2 = { x: e33.x, y: e33.y }, r2 = { x: t2.x, y: t2.y }, s2 = { x: n2.x, y: n2.y }, a2 = { x: o2.x, y: o2.y };
return Math.min(Hz(i2, s2, a2), Hz(r2, s2, a2), Hz(s2, i2, r2), Hz(a2, i2, r2));
}
var Uz = class {
segmentBuckets;
viaBuckets;
CELL_SIZE;
maximumCopperRadius = 0;
constructor(e33, t2 = 1) {
this.segmentBuckets = new Map, this.viaBuckets = new Map, this.CELL_SIZE = t2;
for (const t3 of e33)
if (t3 && t3.connectionName) {
if (this.maximumCopperRadius = Math.max(this.maximumCopperRadius, t3.traceThickness / 2, t3.viaDiameter / 2), t3.route && t3.route.length >= 2)
for (let e34 = 0;e34 < t3.route.length - 1; e34++) {
const n2 = t3.route[e34], o2 = t3.route[e34 + 1];
if (n2.x === o2.x && n2.y === o2.y)
continue;
if (n2.insideJumperPad && o2.insideJumperPad)
continue;
const i2 = [n2, o2], r2 = Wz(i2), s2 = { segmentId: `${t3.connectionName}-seg-${e34}`, segment: i2, parentRoute: t3 }, a2 = Math.floor(r2.minX / this.CELL_SIZE), c2 = Math.floor((r2.maxX + 0.000000001) / this.CELL_SIZE), l2 = Math.floor(r2.minY / this.CELL_SIZE), h2 = Math.floor((r2.maxY + 0.000000001) / this.CELL_SIZE);
for (let e35 = a2;e35 <= c2; e35++)
for (let t4 = l2;t4 <= h2; t4++) {
const n3 = `${e35}x${t4}`;
let o3 = this.segmentBuckets.get(n3);
o3 || (o3 = [], this.segmentBuckets.set(n3, o3)), o3.push(s2);
}
}
if (t3.vias && t3.vias.length > 0)
for (let e34 = 0;e34 < t3.vias.length; e34++) {
const n2 = t3.vias[e34];
if (n2 == null)
continue;
const o2 = { viaId: `${t3.connectionName}-via-${e34}`, x: n2.x, y: n2.y, parentRoute: t3 }, i2 = `${Math.floor(n2.x / this.CELL_SIZE)}x${Math.floor(n2.y / this.CELL_SIZE)}`;
let r2 = this.viaBuckets.get(i2);
r2 || (r2 = [], this.viaBuckets.set(i2, r2)), r2.push(o2);
}
} else
console.warn("Skipping route with missing data:", t3);
}
getConflictingRoutesForSegment(e33, t2, n2) {
const o2 = Wz([e33, t2]), i2 = n2 + this.maximumCopperRadius, r2 = o2.minX - i2, s2 = o2.minY - i2, a2 = o2.maxX + i2, c2 = o2.maxY + i2, l2 = Math.floor(r2 / this.CELL_SIZE), h2 = Math.floor((a2 + 0.000000001) / this.CELL_SIZE), d2 = Math.floor(s2 / this.CELL_SIZE), u2 = Math.floor((c2 + 0.000000001) / this.CELL_SIZE), p2 = new Map, m2 = new Set, g2 = new Set, f2 = { x: e33.x, y: e33.y }, _2 = { x: t2.x, y: t2.y };
for (let o3 = l2;o3 <= h2; o3++)
for (let i3 = d2;i3 <= u2; i3++) {
const r3 = `${o3}x${i3}`, s3 = this.segmentBuckets.get(r3);
if (s3)
for (const o4 of s3) {
if (m2.has(o4.segmentId))
continue;
m2.add(o4.segmentId);
const i4 = o4.parentRoute, [r4, s4] = o4.segment;
if (e33.z !== t2.z || r4.z !== s4.z || r4.z !== e33.z)
continue;
const a4 = n2 + i4.traceThickness / 2, c3 = a4 * a4, l3 = Gz(e33, t2, r4, s4);
if (l3 < c3) {
const e34 = i4.connectionName, t3 = p2.get(e34);
(!t3 || l3 < t3.minDistSq) && p2.set(e34, { route: i4, minDistSq: l3 });
}
}
const a3 = this.viaBuckets.get(r3);
if (a3)
for (const e34 of a3) {
if (g2.has(e34.viaId))
continue;
g2.add(e34.viaId);
const t3 = e34.parentRoute, o4 = { x: e34.x, y: e34.y }, i4 = n2 + t3.viaDiameter / 2, r4 = i4 * i4, s4 = Hz(o4, f2, _2);
if (s4 < r4) {
const e35 = t3.connectionName, n3 = p2.get(e35);
(!n3 || s4 < n3.minDistSq) && p2.set(e35, { route: t3, minDistSq: s4 });
}
}
}
const y2 = [];
for (const e34 of p2.values())
y2.push({ conflictingRoute: e34.route, distance: Math.sqrt(e34.minDistSq) });
return y2;
}
removeRoute(e33) {
for (const [t2, n2] of this.segmentBuckets) {
const o2 = n2.filter((t3) => t3.parentRoute.connectionName !== e33);
o2.length === 0 ? this.segmentBuckets.delete(t2) : o2.length !== n2.length && this.segmentBuckets.set(t2, o2);
}
for (const [t2, n2] of this.viaBuckets) {
const o2 = n2.filter((t3) => t3.parentRoute.connectionName !== e33);
o2.length === 0 ? this.viaBuckets.delete(t2) : o2.length !== n2.length && this.viaBuckets.set(t2, o2);
}
}
addRoute(e33) {
if (!e33 || !e33.connectionName)
return void console.warn("Skipping route with missing data:", e33);
this.maximumCopperRadius = Math.max(this.maximumCopperRadius, e33.traceThickness / 2, e33.viaDiameter / 2);
if (e33.route && e33.route.length >= 2)
for (let t2 = 0;t2 < e33.route.length - 1; t2++) {
const n2 = e33.route[t2], o2 = e33.route[t2 + 1];
if (n2.x === o2.x && n2.y === o2.y)
continue;
if (n2.insideJumperPad && o2.insideJumperPad)
continue;
const i2 = [n2, o2], r2 = Wz(i2), s2 = { segmentId: `${e33.connectionName}-seg-${t2}`, segment: i2, parentRoute: e33 }, a2 = Math.floor(r2.minX / this.CELL_SIZE), c2 = Math.floor((r2.maxX + 0.000000001) / this.CELL_SIZE), l2 = Math.floor(r2.minY / this.CELL_SIZE), h2 = Math.floor((r2.maxY + 0.000000001) / this.CELL_SIZE);
for (let e34 = a2;e34 <= c2; e34++)
for (let t3 = l2;t3 <= h2; t3++) {
const n3 = `${e34}x${t3}`;
let o3 = this.segmentBuckets.get(n3);
o3 || (o3 = [], this.segmentBuckets.set(n3, o3)), o3.push(s2);
}
}
if (e33.vias && e33.vias.length > 0)
for (let t2 = 0;t2 < e33.vias.length; t2++) {
const n2 = e33.vias[t2];
if (n2 == null)
continue;
const o2 = { viaId: `${e33.connectionName}-via-${t2}`, x: n2.x, y: n2.y, parentRoute: e33 }, i2 = `${Math.floor(n2.x / this.CELL_SIZE)}x${Math.floor(n2.y / this.CELL_SIZE)}`;
let r2 = this.viaBuckets.get(i2);
r2 || (r2 = [], this.viaBuckets.set(i2, r2)), r2.push(o2);
}
}
getConflictingRoutesNearPoint(e33, t2) {
const n2 = t2 + this.maximumCopperRadius, o2 = e33.x - n2, i2 = e33.y - n2, r2 = e33.x + n2, s2 = e33.y + n2, a2 = Math.floor(o2 / this.CELL_SIZE), c2 = Math.floor((r2 + 0.000000001) / this.CELL_SIZE), l2 = Math.floor(i2 / this.CELL_SIZE), h2 = Math.floor((s2 + 0.000000001) / this.CELL_SIZE), d2 = new Map, u2 = new Set, p2 = new Set;
for (let n3 = a2;n3 <= c2; n3++)
for (let o3 = l2;o3 <= h2; o3++) {
const i3 = `${n3}x${o3}`, r3 = this.segmentBuckets.get(i3);
if (r3)
for (const n4 of r3) {
if (u2.has(n4.segmentId))
continue;
u2.add(n4.segmentId);
const o4 = n4.segment[0], i4 = n4.segment[1];
if (o4.z !== i4.z || o4.z !== e33.z)
continue;
const r4 = n4.parentRoute, s4 = { x: n4.segment[0].x, y: n4.segment[0].y }, a3 = { x: n4.segment[1].x, y: n4.segment[1].y }, c3 = t2 + r4.traceThickness / 2, l3 = c3 * c3, h3 = Hz(e33, s4, a3);
if (h3 < l3) {
const e34 = r4.connectionName, t3 = d2.get(e34);
(!t3 || h3 < t3.minDistSq) && d2.set(e34, { route: r4, minDistSq: h3 });
}
}
const s3 = this.viaBuckets.get(i3);
if (s3)
for (const n4 of s3) {
if (p2.has(n4.viaId))
continue;
p2.add(n4.viaId);
const o4 = n4.parentRoute, i4 = { x: n4.x, y: n4.y }, r4 = t2 + o4.viaDiameter / 2, s4 = r4 * r4, a3 = Vz(e33, i4);
if (a3 < s4) {
const e34 = o4.connectionName, t3 = d2.get(e34);
(!t3 || a3 < t3.minDistSq) && d2.set(e34, { route: o4, minDistSq: a3 });
}
}
}
const m2 = [];
for (const e34 of d2.values())
m2.push({ conflictingRoute: e34.route, distance: Math.sqrt(e34.minDistSq) });
return m2;
}
};
var Zz = (e33, t2) => {
const n2 = [], o2 = Math.abs(t2.x - e33.x), i2 = Math.abs(t2.y - e33.y), r2 = t2.x > e33.x ? 1 : -1, s2 = t2.y > e33.y ? 1 : -1, a2 = { x: t2.x - r2 * Math.abs(t2.y - e33.y), y: e33.y };
(a2.x - e33.x) * r2 >= 0 && (a2.x - t2.x) * r2 <= 0 && n2.push([e33, a2, t2]);
const c2 = { x: e33.x, y: t2.y - s2 * Math.abs(t2.x - e33.x) };
(c2.y - e33.y) * s2 >= 0 && (c2.y - t2.y) * s2 <= 0 && n2.push([e33, c2, t2]);
const l2 = Math.min(o2, i2), h2 = { x: e33.x + r2 * l2, y: e33.y + s2 * l2 };
return (h2.x - e33.x) * r2 >= 0 && (h2.x - t2.x) * r2 <= 0 && (h2.y - e33.y) * s2 >= 0 && (h2.y - t2.y) * s2 <= 0 && n2.push([e33, h2, t2]), n2;
};
var qz = (e33, t2) => {
const n2 = Math.max(Math.abs(e33), Math.abs(t2));
if (n2 === 0 || n2 === Number.POSITIVE_INFINITY)
return n2;
const o2 = e33 / n2, i2 = t2 / n2;
return n2 * Math.sqrt(o2 * o2 + i2 * i2);
};
function Jz(e33, t2, n2, o2) {
if (_t(e33, t2, n2, o2))
return 0;
const i2 = Qz(e33, n2, o2), r2 = Qz(t2, n2, o2), s2 = Qz(n2, e33, t2), a2 = Qz(o2, e33, t2);
return Math.min(i2, r2, s2, a2);
}
function Qz(e33, t2, n2) {
const o2 = { x: n2.x - t2.x, y: n2.y - t2.y }, i2 = Kz({ x: e33.x - t2.x, y: e33.y - t2.y }, o2);
if (i2 <= 0)
return eB(e33, t2);
const r2 = Kz(o2, o2);
if (r2 <= i2)
return eB(e33, n2);
const s2 = i2 / r2;
return eB(e33, { x: t2.x + s2 * o2.x, y: t2.y + s2 * o2.y });
}
function Kz(e33, t2) {
return e33.x * t2.x + e33.y * t2.y;
}
function eB(e33, t2) {
const n2 = t2.x - e33.x, o2 = t2.y - e33.y;
return Math.sqrt(n2 * n2 + o2 * o2);
}
var tB = 0.000001;
var nB = (e33, t2, n2) => xt(e33, t2, n2) <= tB;
var oB = (e33, t2) => Math.abs(e33.x - t2.x) <= tB && Math.abs(e33.y - t2.y) <= tB;
var iB = (e33, t2) => {
if (!t2 || t2.length < 3)
return false;
for (let n3 = 0;n3 < t2.length; n3++) {
const o2 = t2[n3], i2 = t2[(n3 + 1) % t2.length];
if (nB(e33, o2, i2))
return true;
}
let n2 = false;
for (let o2 = 0, i2 = t2.length - 1;o2 < t2.length; i2 = o2++) {
const r2 = t2[o2], s2 = t2[i2];
r2.y > e33.y != s2.y > e33.y && e33.x < (s2.x - r2.x) * (e33.y - r2.y) / (s2.y - r2.y) + r2.x && (n2 = !n2);
}
return n2;
};
var rB = ({ start: e33, end: t2, polygon: n2, margin: o2 = 0.2 }) => {
if (!n2 || n2.length < 3)
return false;
const i2 = iB(e33, n2), r2 = iB(t2, n2);
if (!i2 || !r2)
return true;
for (let i3 = 0;i3 < n2.length; i3++) {
const r3 = n2[i3], s2 = n2[(i3 + 1) % n2.length], a2 = nB(e33, r3, s2), c2 = nB(t2, r3, s2);
if (a2 && c2)
continue;
if (!_t(e33, t2, r3, s2)) {
if (!a2 && !c2) {
if (Jz(e33, t2, r3, s2) < o2 - tB)
return true;
}
continue;
}
const l2 = It(e33, t2, r3, s2);
if ((!l2 || !(a2 && oB(l2, e33) || c2 && oB(l2, t2))) && (!l2 || !oB(l2, e33) && !oB(l2, t2)))
return true;
}
return false;
};
var sB = (e33) => {
const t2 = [], n2 = e33.route;
if (n2.length === 0)
return [];
let o2 = { startIndex: 0, endIndex: -1, z: n2[0].z, points: [n2[0]] };
for (let e34 = 1;e34 < n2.length; e34++)
n2[e34].z === o2.z ? o2.points.push(n2[e34]) : (o2.endIndex = e34 - 1, t2.push(o2), o2 = { startIndex: e34, endIndex: -1, z: n2[e34].z, points: [n2[e34]] });
return o2.endIndex = n2.length - 1, t2.push(o2), t2;
};
var aB = ({ endpointX: e33, endpointY: t2, targetZ: n2, endpointPcbPortId: o2, terminalLayerIndicesByPcbPortId: i2, obstacleSHI: r2, route: s2, connMap: a2 }) => {
const c2 = o2 ? i2?.get(o2) : undefined;
if (c2 && !c2.has(n2))
return false;
const l2 = [s2.connectionName, s2.rootConnectionName].filter((e34) => e34 !== undefined), h2 = r2.searchArea(e33, t2, 2, 2).filter((n3) => {
if (!l2.some((e34) => n3.connectedTo.some((t3) => t3 === e34 || a2.areIdsConnected(e34, t3))))
return false;
const o3 = n3.width / 2 + 0.05, i3 = n3.height / 2 + 0.05, r3 = Math.abs(e33 - n3.center.x) <= o3, s3 = Math.abs(t2 - n3.center.y) <= i3;
return r3 && s3;
});
return h2.length > 0 && h2.some((e34) => e34.__zLayers?.includes(n2));
};
var cB = ({ currentSection: e33, targetZ: t2, route: n2, hdRouteSHI: o2, obstacleSHI: i2, connMap: r2, defaultTraceThickness: s2, obstacleMargin: a2, traceMargin: c2, shouldCheckStaticGeometryForSegment: l2 }) => {
const h2 = n2.traceThickness ?? s2, d2 = c2 ?? 0, u2 = [n2.connectionName, n2.rootConnectionName].filter((e34) => e34 !== undefined);
for (let n3 = 0;n3 < e33.points.length - 1; n3++) {
const c3 = { ...e33.points[n3], z: t2 }, p2 = { ...e33.points[n3 + 1], z: t2 }, m2 = o2.getConflictingRoutesForSegment(c3, p2, h2 / 2 + d2);
for (const { conflictingRoute: e34, distance: t3 } of m2) {
const n4 = [e34.connectionName, e34.rootConnectionName].filter((e35) => e35 !== undefined);
if (u2.some((e35) => n4.some((t4) => t4 === e35 || r2.areIdsConnected(t4, e35))))
continue;
const o3 = e34.traceThickness ?? s2;
if (t3 < h2 / 2 + (d2 > 0 ? Math.max(o3 / 2, e34.viaDiameter / 2) : o3 / 2) + d2)
return false;
}
if (l2?.(c3, p2) === false)
continue;
const g2 = { centerX: (c3.x + p2.x) / 2, centerY: (c3.y + p2.y) / 2, width: Math.abs(c3.x - p2.x), height: Math.abs(c3.y - p2.y) }, f2 = h2 / 2 + a2, _2 = i2.searchArea(g2.centerX, g2.centerY, g2.width + 2 * f2, g2.height + 2 * f2);
for (const e34 of _2) {
if (u2.some((t3) => e34.connectedTo.some((e35) => e35 === t3 || r2.areIdsConnected(e35, t3))))
continue;
if (e34.__zLayers?.includes(t2)) {
if (Math.abs(c3.x - e34.center.x) < 0.01 && Math.abs(c3.y - e34.center.y) < 0.01 || Math.abs(p2.x - e34.center.x) < 0.01 && Math.abs(p2.y - e34.center.y) < 0.01)
continue;
}
if (Lt(c3, p2, e34) < f2)
return false;
}
}
return true;
};
var lB = class extends Fz {
getSolverName() {
return "SingleRouteUselessViaRemovalSolver";
}
obstacleSHI;
hdRouteSHI;
unsimplifiedRoute;
connMap;
outline;
terminalLayerIndicesByPcbPortId;
routeSections;
currentSectionIndex;
TRACE_THICKNESS = 0.15;
OBSTACLE_MARGIN = 0.1;
GEOMETRY_SHORTCUT_TRACE_MARGIN = 0.1;
GEOMETRY_SHORTCUT_OBSTACLE_MARGIN = 0.15;
MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH = 4;
ENABLE_GEOMETRY_SHORTCUTS = true;
ENABLE_OBSTACLE_DETOUR_SHORTCUTS = false;
PRESERVE_ROUTE_ENDPOINTS = false;
geometryShortcutsApplied = 0;
multilayerSectionsCollapsed = 0;
obstacleDetourCandidatesValidated = 0;
constructor(e33) {
super(), this.currentSectionIndex = 0, this.obstacleSHI = e33.obstacleSHI, this.hdRouteSHI = e33.hdRouteSHI, this.unsimplifiedRoute = e33.unsimplifiedRoute, this.connMap = e33.connMap, this.outline = e33.outline, this.terminalLayerIndicesByPcbPortId = e33.terminalLayerIndicesByPcbPortId, this.GEOMETRY_SHORTCUT_TRACE_MARGIN = e33.geometryShortcutTraceMargin ?? this.GEOMETRY_SHORTCUT_TRACE_MARGIN, this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN = e33.geometryShortcutObstacleMargin ?? this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN, this.ENABLE_GEOMETRY_SHORTCUTS = e33.enableGeometryShortcuts ?? true, this.ENABLE_OBSTACLE_DETOUR_SHORTCUTS = e33.enableObstacleDetourShortcuts ?? false, this.PRESERVE_ROUTE_ENDPOINTS = e33.preserveRouteEndpoints ?? false, this.routeSections = sB(this.unsimplifiedRoute);
}
getPathLength(e33) {
let t2 = 0;
for (let n2 = 1;n2 < e33.length; n2++)
t2 += qz(e33[n2].x - e33[n2 - 1].x, e33[n2].y - e33[n2 - 1].y);
return t2;
}
normalizeShortcutPath(e33, t2, n2) {
const o2 = e33.filter((t3, n3) => {
const o3 = e33[n3 - 1];
return !o3 || t3.x !== o3.x || t3.y !== o3.y;
});
return o2.map((e34, i2) => i2 === 0 ? { ...t2 } : i2 === o2.length - 1 ? { ...n2 } : { x: e34.x, y: e34.y, z: t2.z });
}
shortcutCrossesOutline(e33) {
if (!this.outline || this.outline.length < 3)
return false;
for (let t2 = 1;t2 < e33.length; t2++)
if (rB({ start: e33[t2 - 1], end: e33[t2], polygon: this.outline }))
return true;
return false;
}
getObstacleDetourPaths(e33, t2, n2, o2) {
const i2 = (this.unsimplifiedRoute.traceThickness ?? this.TRACE_THICKNESS) / 2 + this.GEOMETRY_SHORTCUT_OBSTACLE_MARGIN + 0.000001, r2 = this.MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH / 2 + i2, s2 = Math.min(e33.x, t2.x) - r2, a2 = Math.max(e33.x, t2.x) + r2, c2 = Math.min(e33.y, t2.y) - r2, l2 = Math.max(e33.y, t2.y) + r2, h2 = this.obstacleSHI.search({ minX: s2, minY: c2, maxX: a2, maxY: l2 }).filter((e34) => e34.__zLayers?.includes(n2));
if (h2.length === 0)
return [];
const d2 = new Set, u2 = new Set;
for (const e34 of h2)
d2.add(e34.center.x - e34.width / 2 - i2), d2.add(e34.center.x + e34.width / 2 + i2), u2.add(e34.center.y - e34.height / 2 - i2), u2.add(e34.center.y + e34.height / 2 + i2);
const p2 = [], m2 = new Set, g2 = (n3) => {
let i3 = 0;
for (let e34 = 1;e34 < n3.length; e34++)
i3 += qz(n3[e34].x - n3[e34 - 1].x, n3[e34].y - n3[e34 - 1].y);
if (i3 > o2)
return;
const r3 = this.normalizeShortcutPath(n3, e33, t2);
let s3 = 0, a3 = -1;
for (let e34 = 0;e34 < r3.length - 1; e34++) {
const t3 = r3[e34 + 1].x - r3[e34].x, n4 = r3[e34 + 1].y - r3[e34].y, o3 = t3 * t3 + n4 * n4;
o3 > a3 && (s3 = e34, a3 = o3);
}
const c3 = r3.map((e34) => `${e34.x}:${e34.y}`).join("|");
m2.has(c3) || (m2.add(c3), p2.push({ path: r3, length: i3, longestSegmentIndex: s3 }));
};
for (const n3 of u2)
g2([e33, { x: e33.x, y: n3 }, { x: t2.x, y: n3 }, t2]);
for (const n3 of d2)
g2([e33, { x: n3, y: e33.y }, { x: n3, y: t2.y }, t2]);
return p2;
}
getDirectGeometryShortcut(e33, t2, n2) {
let o2 = null;
for (let i2 = 0;i2 < e33.points.length; i2++) {
const r2 = e33.points[i2];
for (let s2 = 0;s2 < n2.points.length; s2++) {
const a2 = n2.points[s2], c2 = [...e33.points.slice(i2), ...t2.points, ...n2.points.slice(0, s2 + 1)];
if (!c2.some((e34) => e34.insideJumperPad || e34.toNextSegmentType))
for (const t3 of Zz(r2, a2)) {
const l2 = this.normalizeShortcutPath(t3, r2, a2), h2 = this.getPathLength(c2) - this.getPathLength(l2);
if (h2 < -1e-6 || this.shortcutCrossesOutline(l2))
continue;
const d2 = { startIndex: e33.startIndex + i2, endIndex: n2.startIndex + s2, z: e33.z, points: l2 };
cB({ currentSection: d2, targetZ: e33.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 }) && ((!o2 || h2 > o2.savedLength) && (o2 = { path: l2, previousPointIndex: i2, nextPointIndex: s2, savedLength: h2 }));
}
}
}
return o2;
}
getObstacleDetourShortcut(e33, t2, n2) {
const o2 = e33.points.length - 1, i2 = [];
for (let e34 = 0;e34 <= o2; e34++)
i2.push([e34, 0]);
for (let e34 = 1;e34 < n2.points.length; e34++)
i2.push([o2, e34]);
const r2 = [];
for (const [o3, s3] of i2) {
const i3 = e33.points[o3], a3 = n2.points[s3], c3 = [...e33.points.slice(o3), ...t2.points, ...n2.points.slice(0, s3 + 1)];
if (c3.some((e34) => e34.insideJumperPad || e34.toNextSegmentType))
continue;
const l2 = this.getPathLength(c3);
for (const { path: t3, length: n3, longestSegmentIndex: c4 } of this.getObstacleDetourPaths(i3, a3, e33.z, l2 + this.MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH + 0.000001)) {
const e34 = l2 - n3;
e34 < -this.MAX_GEOMETRY_SHORTCUT_ADDED_LENGTH - 0.000001 || r2.push({ path: t3, previousPointIndex: o3, nextPointIndex: s3, savedLength: e34, validationFirstSegmentIndex: c4 });
}
}
r2.sort((e34, t3) => t3.savedLength - e34.savedLength);
let s2 = 0;
const a2 = r2.length >= 256, c2 = (({ targetZ: e34, route: t3, hdRouteSHI: n3, obstacleSHI: o3, connMap: i3, defaultTraceThickness: r3, obstacleMargin: s3, traceMargin: a3, useNumericSegmentKeys: c3 }) => {
const l2 = t3.traceThickness ?? r3, h2 = l2 / 2 + a3, d2 = l2 / 2 + s3, u2 = t3.connectionName, p2 = t3.rootConnectionName, m2 = new Map, g2 = new WeakMap, f2 = new WeakMap, _2 = c3 ? new Map : undefined;
let y2 = 0;
const b2 = (e35) => {
let t4 = _2.get(e35.x);
t4 || (t4 = new Map, _2.set(e35.x, t4));
let n4 = t4.get(e35.y);
return n4 === undefined && (n4 = y2++, t4.set(e35.y, n4)), n4;
}, x2 = (e35, t4) => {
if (c3) {
const n4 = b2(e35), o4 = b2(t4), i4 = Math.max(n4, o4);
return i4 * (i4 + 1) / 2 + Math.min(n4, o4);
}
return e35.x < t4.x || e35.x === t4.x && e35.y <= t4.y ? `${e35.x}:${e35.y}|${t4.x}:${t4.y}` : `${t4.x}:${t4.y}|${e35.x}:${e35.y}`;
}, v2 = (e35) => e35 === u2 || i3.areIdsConnected(e35, u2) || p2 !== undefined && (e35 === p2 || i3.areIdsConnected(e35, p2));
return (t4, i4) => {
const s4 = t4.length - 1;
for (let c4 = 0;c4 < s4; c4++) {
const s5 = c4 - 1, u3 = i4 === 0 ? c4 : c4 === 0 ? i4 : s5 >= i4 ? s5 + 1 : s5, p3 = t4[u3], _3 = t4[u3 + 1], y3 = x2(p3, _3), b3 = m2.get(y3);
if (b3 !== undefined) {
if (!b3)
return false;
continue;
}
const I2 = p3.z === e34 ? p3 : { ...p3, z: e34 }, S2 = _3.z === e34 ? _3 : { ..._3, z: e34 }, C2 = { centerX: (I2.x + S2.x) / 2, centerY: (I2.y + S2.y) / 2, width: Math.abs(I2.x - S2.x), height: Math.abs(I2.y - S2.y) }, P2 = o3.searchArea(C2.centerX, C2.centerY, C2.width + 2 * d2, C2.height + 2 * d2);
for (const t5 of P2) {
let n4 = g2.get(t5);
if ((n4 === undefined && (n4 = t5.connectedTo.some(v2), g2.set(t5, n4)), !n4) && ((!t5.__zLayers?.includes(e34) || !(Math.abs(I2.x - t5.center.x) < 0.01 && Math.abs(I2.y - t5.center.y) < 0.01 || Math.abs(S2.x - t5.center.x) < 0.01 && Math.abs(S2.y - t5.center.y) < 0.01)) && Lt(I2, S2, t5) < d2))
return m2.set(y3, false), false;
}
const M2 = n3.getConflictingRoutesForSegment(I2, S2, h2);
for (const { conflictingRoute: e35, distance: t5 } of M2) {
let n4 = f2.get(e35);
if (n4 === undefined && (n4 = v2(e35.connectionName) || e35.rootConnectionName !== undefined && v2(e35.rootConnectionName), f2.set(e35, n4)), n4)
continue;
const o4 = e35.traceThickness ?? r3, i5 = Math.max(o4 / 2, e35.viaDiameter / 2);
if (t5 < l2 / 2 + i5 + a3)
return m2.set(y3, false), false;
}
m2.set(y3, true);
}
return true;
};
})({ targetZ: e33.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: a2 });
for (const e34 of r2) {
s2++;
const { path: t3 } = e34;
if (c2(t3, e34.validationFirstSegmentIndex ?? 0) && !this.shortcutCrossesOutline(t3))
return this.obstacleDetourCandidatesValidated += s2, this.stats.obstacleDetourCandidatesValidated = this.obstacleDetourCandidatesValidated, e34;
}
return this.obstacleDetourCandidatesValidated += s2, this.stats.obstacleDetourCandidatesValidated = this.obstacleDetourCandidatesValidated, null;
}
findGeometryShortcut(e33, t2, n2) {
if (this.unsimplifiedRoute.jumpers?.length)
return null;
if (this.ENABLE_GEOMETRY_SHORTCUTS) {
const o2 = this.getDirectGeometryShortcut(e33, t2, n2);
if (o2)
return o2;
}
return this.ENABLE_OBSTACLE_DETOUR_SHORTCUTS ? this.getObstacleDetourShortcut(e33, t2, n2) : null;
}
applyGeometryShortcut(e33) {
const t2 = this.routeSections[this.currentSectionIndex - 1], n2 = this.routeSections[this.currentSectionIndex + 1], o2 = [...t2.points.slice(0, e33.previousPointIndex), ...e33.path, ...n2.points.slice(e33.nextPointIndex + 1)].filter((e34, t3, n3) => {
const o3 = n3[t3 - 1];
return !o3 || e34.x !== o3.x || e34.y !== o3.y || e34.z !== o3.z;
});
this.routeSections.splice(this.currentSectionIndex - 1, 3, { startIndex: t2.startIndex, endIndex: n2.endIndex, z: t2.z, points: o2 }), this.geometryShortcutsApplied++, this.stats.geometryShortcutsApplied = this.geometryShortcutsApplied, this.stats.viasRemovedByGeometryShortcuts = 2 * this.geometryShortcutsApplied, this.currentSectionIndex = Math.max(0, this.currentSectionIndex - 1);
}
findMultilayerSectionCollapse(e33, t2, n2) {
if (e33.z === n2.z || this.unsimplifiedRoute.jumpers?.length)
return null;
const o2 = e33.points[e33.points.length - 1];
if (o2?.insideJumperPad || o2?.toNextSegmentType || t2.points.some((e34) => e34.insideJumperPad || e34.toNextSegmentType))
return null;
const i2 = [{ targetZ: e33.z, mergeWith: "previous" }, { targetZ: n2.z, mergeWith: "next" }];
for (const e34 of i2)
if (e34.targetZ !== t2.z && cB({ currentSection: t2, targetZ: e34.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 e34;
return null;
}
applyMultilayerSectionCollapse(e33) {
const t2 = this.routeSections[this.currentSectionIndex - 1], n2 = this.routeSections[this.currentSectionIndex], o2 = this.routeSections[this.currentSectionIndex + 1], i2 = n2.points.map((t3) => ({ ...t3, z: e33.targetZ })), r2 = (e34) => e34.filter((t3, n3) => {
const o3 = e34[n3 - 1];
return !o3 || t3.x !== o3.x || t3.y !== o3.y || t3.z !== o3.z;
});
e33.mergeWith === "previous" ? this.routeSections.splice(this.currentSectionIndex - 1, 2, { startIndex: t2.startIndex, endIndex: n2.endIndex, z: e33.targetZ, points: r2([...t2.points, ...i2]) }) : this.routeSections.splice(this.currentSectionIndex, 2, { startIndex: n2.startIndex, endIndex: o2.endIndex, z: e33.targetZ, points: r2([...i2, ...o2.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 = true);
if (this.currentSectionIndex === 0 && this.routeSections.length > 1) {
const e34 = this.routeSections[0], t3 = this.routeSections[1];
if (!this.PRESERVE_ROUTE_ENDPOINTS && e34.z !== t3.z) {
const n3 = t3.z, o3 = e34.points[0];
if (aB({ endpointX: o3.x, endpointY: o3.y, targetZ: n3, endpointPcbPortId: this.unsimplifiedRoute.startPcbPortId, terminalLayerIndicesByPcbPortId: this.terminalLayerIndicesByPcbPortId, obstacleSHI: this.obstacleSHI, route: this.unsimplifiedRoute, connMap: this.connMap }) && cB({ currentSection: e34, targetZ: n3, route: this.unsimplifiedRoute, hdRouteSHI: this.hdRouteSHI, obstacleSHI: this.obstacleSHI, connMap: this.connMap, defaultTraceThickness: this.TRACE_THICKNESS, obstacleMargin: this.OBSTACLE_MARGIN }))
return e34.z = n3, e34.points = e34.points.map((e35) => ({ ...e35, z: n3 })), 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 e34 = this.routeSections[this.routeSections.length - 1], t3 = this.routeSections[this.routeSections.length - 2];
if (e34.z !== t3.z) {
const n3 = t3.z, o3 = e34.points[e34.points.length - 1];
aB({ endpointX: o3.x, endpointY: o3.y, targetZ: n3, endpointPcbPortId: this.unsimplifiedRoute.endPcbPortId, terminalLayerIndicesByPcbPortId: this.terminalLayerIndicesByPcbPortId, obstacleSHI: this.obstacleSHI, route: this.unsimplifiedRoute, connMap: this.connMap }) && cB({ currentSection: e34, targetZ: n3, route: this.unsimplifiedRoute, hdRouteSHI: this.hdRouteSHI, obstacleSHI: this.obstacleSHI, connMap: this.connMap, defaultTraceThickness: this.TRACE_THICKNESS, obstacleMargin: this.OBSTACLE_MARGIN }) && (e34.z = n3, e34.points = e34.points.map((e35) => ({ ...e35, z: n3 })));
}
}
return void (this.solved = true);
}
const e33 = this.routeSections[this.currentSectionIndex - 1], t2 = this.routeSections[this.currentSectionIndex], n2 = this.routeSections[this.currentSectionIndex + 1];
if (e33.z !== n2.z) {
const o3 = this.findMultilayerSectionCollapse(e33, t2, n2);
return o3 ? void this.applyMultilayerSectionCollapse(o3) : void this.currentSectionIndex++;
}
const o2 = e33.z;
if (cB({ currentSection: t2, targetZ: o2, route: this.unsimplifiedRoute, hdRouteSHI: this.hdRouteSHI, obstacleSHI: this.obstacleSHI, connMap: this.connMap, defaultTraceThickness: this.TRACE_THICKNESS, obstacleMargin: this.OBSTACLE_MARGIN }))
return t2.z = o2, t2.points = t2.points.map((e34) => ({ ...e34, z: o2 })), void (this.currentSectionIndex += 2);
const i2 = this.findGeometryShortcut(e33, t2, n2);
i2 ? this.applyGeometryShortcut(i2) : 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 e33 = this.routeSections.flatMap((e34) => e34.points), t2 = [];
for (let n2 = 0;n2 < e33.length - 1; n2++)
e33[n2].z !== e33[n2 + 1].z && t2.push({ x: e33[n2].x, y: e33[n2].y });
return { connectionName: this.unsimplifiedRoute.connectionName, rootConnectionName: this.unsimplifiedRoute.rootConnectionName, startPcbPortId: this.unsimplifiedRoute.startPcbPortId, endPcbPortId: this.unsimplifiedRoute.endPcbPortId, route: e33, traceThickness: this.unsimplifiedRoute.traceThickness, vias: t2, viaDiameter: this.unsimplifiedRoute.viaDiameter, jumpers: this.unsimplifiedRoute.jumpers };
}
visualize() {
const e33 = { circles: [], lines: [], points: [], rects: [], coordinateSystem: "cartesian", title: "Single Route Useless Via Removal Solver" };
for (let t2 = 0;t2 < this.routeSections.length; t2++) {
const n2 = this.routeSections[t2];
e33.lines.push({ points: n2.points, strokeWidth: this.TRACE_THICKNESS, strokeColor: t2 === this.currentSectionIndex ? "orange" : n2.z === 0 ? "red" : "blue" });
}
return e33;
}
};
var hB = (e33, t2) => {
try {
return Re(t2, e33);
} catch (t3) {
return console.error(t3), e33;
}
};
var dB = { "0603": { length: 1.65, width: 0.95, padLength: 0.8, padWidth: 0.95 }, 1206: { length: 3.2, width: 1.6, padLength: 0.6, padWidth: 1.6 }, "1206x4_pair": { length: 2.7, width: 0.5, padLength: 0.8, padWidth: 0.5 } };
function uB(e33, t2 = {}) {
const n2 = [], o2 = [], i2 = t2.color ?? "gray", r2 = t2.label, s2 = dB[e33.footprint] ?? dB["0603"], a2 = e33.end.x - e33.start.x, c2 = e33.end.y - e33.start.y, l2 = Math.abs(a2) > Math.abs(c2), h2 = l2 ? s2.padLength : s2.padWidth, d2 = l2 ? s2.padWidth : s2.padLength;
return n2.push({ center: e33.start, width: h2, height: d2, fill: hB(i2, 0.5), stroke: "rgba(0, 0, 0, 0.5)", layer: "jumper", label: r2 ? `${r2} (start)` : undefined }), n2.push({ center: e33.end, width: h2, height: d2, fill: hB(i2, 0.5), stroke: "rgba(0, 0, 0, 0.5)", layer: "jumper", label: r2 ? `${r2} (end)` : undefined }), o2.push({ points: [e33.start, e33.end], strokeColor: "rgba(100, 100, 100, 0.8)", strokeWidth: 0.3 * s2.padWidth, layer: "jumper-body" }), { rects: n2, lines: o2 };
}
function pB(e33, t2 = {}) {
const n2 = { rects: [], lines: [] };
for (const o2 of e33) {
const { rects: e34, lines: i2 } = uB(o2, t2);
n2.rects.push(...e34), n2.lines.push(...i2);
}
return n2;
}
function mB(e33, t2) {
return [...new Set(e33)].filter((e34) => Number.isInteger(e34) && e34 >= 0 && e34 < t2).sort((e34, t3) => e34 - t3);
}
function gB(e33, t2) {
return mB(e33.map((e34) => ((e35, t3) => e35 === "top" ? 0 : e35 === "bottom" ? t3 - 1 : parseInt(e35.slice(5)))(e34, t2)), t2);
}
var fB = (e33, t2 = 2) => {
const n2 = Array.from({ length: t2 }, (e34, t3) => t3);
return e33.map((e34) => {
const o2 = mB(e34.__zLayers ?? (e34.layers ? gB(e34.layers, t2) : undefined) ?? n2, t2);
return { ...e34, __zLayers: o2.length > 0 ? o2 : n2 };
});
};
var _B = class extends Fz {
constructor(e33) {
super(), this.input = e33, this.input = { ...e33, obstacles: fB(e33.obstacles, e33.layerCount) }, this.MAX_ITERATIONS = 1e6, this.unsimplifiedHdRoutes = e33.unsimplifiedHdRoutes, this.optimizedHdRoutes = [], this.unprocessedRoutes = [...e33.unsimplifiedHdRoutes], this.obstacleSHI = new Yz("flatbush", this.input.obstacles), this.hdRouteSHI = new Uz([...this.unsimplifiedHdRoutes, ...e33.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 e34 = this.activeSubSolver.getOptimizedHdRoute();
this.hdRouteSHI.removeRoute(e34.connectionName), this.hdRouteSHI.addRoute(e34), this.optimizedHdRoutes.push(e34), this.activeSubSolver = null;
} else
(this.activeSubSolver.failed || this.activeSubSolver.error) && (this.error = this.activeSubSolver.error, this.failed = true);
return;
}
const e33 = this.unprocessedRoutes.shift();
e33 ? this.activeSubSolver = new lB({ hdRouteSHI: this.hdRouteSHI, obstacleSHI: this.obstacleSHI, unsimplifiedRoute: e33, 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 = true;
}
getOptimizedHdRoutes() {
return this.optimizedHdRoutes;
}
visualize() {
const e33 = { lines: [], points: [], rects: [], circles: [], coordinateSystem: "cartesian", title: "Useless Via Removal Solver" };
for (const t2 of this.input.obstacles) {
let n2 = "rgba(128, 128, 128, 0.2)";
const o2 = t2.__zLayers?.includes(0), i2 = t2.__zLayers?.includes(1);
o2 && i2 ? n2 = "rgba(128, 0, 128, 0.2)" : o2 ? n2 = "rgba(255, 0, 0, 0.2)" : i2 && (n2 = "rgba(0, 0, 255, 0.2)"), e33.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: n2, label: `Obstacle (Z: ${t2.__zLayers?.join(", ")})` });
}
for (const t2 of this.optimizedHdRoutes) {
if (t2.route.length === 0)
continue;
const n2 = this.input.colorMap[t2.connectionName] || "#888888";
for (let n3 = 0;n3 < t2.route.length - 1; n3++) {
const o2 = t2.route[n3], i2 = t2.route[n3 + 1];
o2.z === i2.z && e33.lines.push({ points: [{ x: o2.x, y: o2.y }, { x: i2.x, y: i2.y }], strokeColor: o2.z === 0 ? "red" : "blue", strokeWidth: t2.traceThickness, label: `${t2.connectionName} (z=${o2.z})` });
}
for (const n3 of t2.vias)
e33.circles.push({ center: { x: n3.x, y: n3.y }, radius: t2.viaDiameter / 2, fill: "rgba(255, 0, 255, 0.5)", label: `${t2.connectionName} via` });
if (t2.jumpers && t2.jumpers.length > 0) {
const o2 = pB(t2.jumpers, { color: n2, label: t2.connectionName });
e33.rects.push(...o2.rects ?? []), e33.lines.push(...o2.lines ?? []);
}
}
return this.activeSubSolver && e33.lines.push(...this.activeSubSolver.visualize().lines ?? []), e33;
}
};
var yB = class extends Fz {
getSolverName() {
return "SingleSimplifiedPathSolver";
}
newRoute;
newVias;
headIndex = 0;
tailIndex = 0;
inputRoute;
otherHdRoutes;
obstacles;
connMap;
colorMap;
outline;
minBoardEdgeClearance;
constructor(e33) {
super(), this.inputRoute = e33.inputRoute, this.otherHdRoutes = e33.otherHdRoutes, this.obstacles = e33.obstacles, this.connMap = e33.connMap, this.colorMap = e33.colorMap, this.outline = e33.outline, this.minBoardEdgeClearance = e33.minBoardEdgeClearance ?? 0.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(e33) {
throw new Error("Not implemented");
}
_step() {
throw new Error("Not implemented");
}
getVisualsForNewRouteAndObstacles() {
const e33 = { lines: [], points: [], circles: [], rects: [], coordinateSystem: "cartesian", title: "Simplified Path Solver" };
for (let t2 = 0;t2 < this.inputRoute.route.length - 1; t2++)
e33.lines.push({ points: [{ x: this.inputRoute.route[t2].x, y: this.inputRoute.route[t2].y }, { x: this.inputRoute.route[t2 + 1].x, y: this.inputRoute.route[t2 + 1].y }], strokeColor: "rgba(255, 0, 0, 0.8)", strokeDash: this.inputRoute.route[t2].z === 1 ? "5, 5" : undefined, layer: `z${this.inputRoute.route[t2].z.toString()}` });
for (let t2 = 0;t2 < this.newRoute.length; t2++)
t2 < this.newRoute.length - 1 && e33.lines.push({ points: [{ x: this.newRoute[t2].x, y: this.newRoute[t2].y }, { x: this.newRoute[t2 + 1].x, y: this.newRoute[t2 + 1].y }], strokeWidth: 0.15, strokeColor: "rgba(0, 255, 0, 0.8)", strokeDash: this.newRoute[t2].z === 1 ? [0.4, 0.4] : undefined, layer: `z${this.newRoute[t2].z.toString()}` }), e33.points.push({ x: this.newRoute[t2].x, y: this.newRoute[t2].y, color: "rgba(0, 255, 0, 0.8)", label: `z: ${this.newRoute[t2].z}`, layer: `z${this.newRoute[t2].z.toString()}` });
for (const t2 of this.newVias)
e33.circles.push({ center: t2, radius: this.inputRoute.viaDiameter / 2, fill: "rgba(0, 0, 255, 0.5)" });
for (const t2 of this.obstacles)
e33.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: t2.layers?.includes("top") ? "rgba(255, 0, 0, 0.3)" : t2.layers?.includes("bottom") ? "rgba(0, 0, 255, 0.3)" : "rgba(128, 128, 128, 0.3)" });
for (const t2 of this.otherHdRoutes)
for (let n2 = 0;n2 < t2.route.length - 1; n2++)
e33.lines.push({ points: [{ x: t2.route[n2].x, y: t2.route[n2].y }, { x: t2.route[n2 + 1].x, y: t2.route[n2 + 1].y }], strokeWidth: 0.15, strokeColor: t2.route[n2].z === 0 ? "rgba(255, 0, 255, 0.5)" : t2.route[n2].z === 1 ? "rgba(128, 0, 128, 0.5)" : "rgba(0, 0, 255, 0.5)", layer: `z${t2.route[n2].z.toString()}` });
if ("filteredObstaclePathSegments" in this) {
const t2 = this.filteredObstaclePathSegments;
for (const [n2, o2] of t2)
e33.lines.push({ points: [n2, o2] });
}
return e33;
}
};
var bB = (e33) => ({ minX: Math.min(e33[0].x, e33[1].x), maxX: Math.max(e33[0].x, e33[1].x), minY: Math.min(e33[0].y, e33[1].y), maxY: Math.max(e33[0].y, e33[1].y) });
var xB = class {
constructor(e33, t2 = 0.4) {
this.segments = e33, this.buckets = new Map, this.SEGMENT_MARGIN = t2;
const n2 = new Map;
for (const t3 of e33) {
const e34 = this.getSegmentKey(t3);
if (n2.has(e34))
continue;
n2.set(e34, t3);
const o2 = bB(t3), i2 = Math.floor(o2.minX / this.CELL_SIZE), r2 = Math.floor(o2.maxX / this.CELL_SIZE), s2 = Math.floor(o2.minY / this.CELL_SIZE), a2 = Math.floor(o2.maxY / this.CELL_SIZE);
for (let n3 = i2;n3 <= r2; n3++)
for (let o3 = s2;o3 <= a2; o3++) {
const i3 = `${n3}x${o3}`, r3 = this.buckets.get(i3), s3 = [t3[0], t3[1], e34];
r3 ? r3.push(s3) : this.buckets.set(i3, [s3]);
}
}
}
segments;
buckets;
CELL_SIZE = 0.4;
SEGMENT_MARGIN;
getBucketKey(e33, t2) {
return `${Math.floor(e33 / this.CELL_SIZE)}x${Math.floor(t2 / this.CELL_SIZE)}`;
}
getSegmentKey(e33) {
return `${e33[0].x}-${e33[0].y}-${e33[0].z}-${e33[1].x}-${e33[1].y}-${e33[1].z}`;
}
getSegmentsThatCouldIntersect(e33, t2) {
const n2 = [], o2 = new Set, i2 = Math.min(e33.x, t2.x) - this.SEGMENT_MARGIN, r2 = Math.min(e33.y, t2.y) - this.SEGMENT_MARGIN, s2 = Math.max(e33.x, t2.x) + this.SEGMENT_MARGIN, a2 = Math.max(e33.y, t2.y) + this.SEGMENT_MARGIN, c2 = Math.floor(i2 / this.CELL_SIZE), l2 = Math.floor(s2 / this.CELL_SIZE), h2 = Math.floor(r2 / this.CELL_SIZE), d2 = Math.floor(a2 / this.CELL_SIZE);
for (let e34 = c2;e34 <= l2; e34++)
for (let t3 = h2;t3 <= d2; t3++) {
const i3 = `${e34}x${t3}`, r3 = this.buckets.get(i3);
if (r3)
for (const e35 of r3) {
const t4 = e35[2];
o2.has(t4) || (o2.add(t4), n2.push(e35));
}
}
return n2;
}
};
var vB = class extends yB {
pathSegments = [];
totalPathLength = 0;
headDistanceAlongPath = 0;
tailDistanceAlongPath = 0;
minStepSize = 0.25;
lastValidPath = null;
lastValidPathHeadDistance = 0;
STEP_SIZE_REDUCTION_FACTOR = 0.25;
maxStepSize = 4;
currentStepSize = this.maxStepSize;
lastHeadMoveDistance = 0;
cachedValidPathSegments;
filteredObstacles = [];
filteredObstaclePathSegments = [];
traceThicknessByObstacleSegmentId = new Map;
filteredVias = [];
filteredJumperPads = [];
jumperPadPointIndices = new Set;
segmentTree;
OBSTACLE_MARGIN = 0.1;
TRACE_THICKNESS = 0.15;
useTraceWidthAwareClearance = false;
clearanceTraceThickness = this.TRACE_THICKNESS;
TAIL_JUMP_RATIO = 0.8;
isSameNetRoute(e33) {
const t2 = [this.inputRoute.connectionName, this.inputRoute.rootConnectionName].filter((e34) => e34 !== undefined), n2 = [e33.connectionName, e33.rootConnectionName].filter((e34) => e34 !== undefined);
return t2.some((e34) => n2.some((t3) => e34 === t3 || this.connMap.areIdsConnected(e34, t3)));
}
constructor(e33) {
if (super(e33), this.cachedValidPathSegments = new Set, this.useTraceWidthAwareClearance = e33.useTraceWidthAwareClearance ?? false, this.clearanceTraceThickness = this.useTraceWidthAwareClearance ? this.inputRoute.traceThickness : this.TRACE_THICKNESS, this.inputRoute.route.length <= 1)
return this.newRoute = [...this.inputRoute.route], void (this.solved = true);
const t2 = this.inputRoute.route.reduce((e34, t3) => (e34.minX = Math.min(e34.minX, t3.x), e34.maxX = Math.max(e34.maxX, t3.x), e34.minY = Math.min(e34.minY, t3.y), e34.maxY = Math.max(e34.maxY, t3.y), e34), { minX: 1 / 0, maxX: -1 / 0, minY: 1 / 0, maxY: -1 / 0 }), n2 = this.useTraceWidthAwareClearance ? Math.max(0, ...this.otherHdRoutes.flatMap((e34) => [e34.traceThickness, ...e34.route.map((t3) => t3.traceThickness ?? e34.traceThickness)])) : this.TRACE_THICKNESS, o2 = this.useTraceWidthAwareClearance ? this.OBSTACLE_MARGIN + this.clearanceTraceThickness / 2 + n2 / 2 : this.OBSTACLE_MARGIN + this.TRACE_THICKNESS, i2 = { center: { x: (t2.minX + t2.maxX) / 2, y: (t2.minY + t2.maxY) / 2 }, width: t2.maxX - t2.minX, height: t2.maxY - t2.minY };
this.filteredObstacles = this.obstacles.filter((e34) => !e34.connectedTo.some((e35) => this.connMap.areIdsConnected(this.inputRoute.connectionName, e35))).filter((e34) => {
if (e34.connectedTo.some((e35) => this.connMap.areIdsConnected(this.inputRoute.connectionName, e35)))
return false;
return function(e35, t3) {
const n3 = At(e35), o3 = At(t3), i3 = Math.max(n3.minX - o3.maxX, o3.minX - n3.maxX, 0), r3 = Math.max(n3.minY - o3.maxY, o3.minY - n3.maxY, 0);
return Math.hypot(i3, r3);
}(i2, e34) < this.OBSTACLE_MARGIN + this.clearanceTraceThickness / 2;
}), this.filteredObstaclePathSegments = this.otherHdRoutes.flatMap((e34) => {
if (this.isSameNetRoute(e34))
return [];
const n3 = e34.route, i3 = [];
for (let r3 = 0;r3 < n3.length - 1; r3++) {
const s2 = n3[r3], a2 = n3[r3 + 1];
if (Dt(s2, a2, t2) <= o2) {
i3.push([s2, a2]);
const t3 = `${s2.x}-${s2.y}-${s2.z}-${a2.x}-${a2.y}-${a2.z}`;
if (this.useTraceWidthAwareClearance) {
const n4 = Math.max(s2.traceThickness ?? e34.traceThickness, a2.traceThickness ?? e34.traceThickness);
this.traceThicknessByObstacleSegmentId.set(t3, Math.max(this.traceThicknessByObstacleSegmentId.get(t3) ?? 0, n4));
}
}
}
return i3;
}), this.segmentTree = this.useTraceWidthAwareClearance ? new xB(this.filteredObstaclePathSegments, o2) : new xB(this.filteredObstaclePathSegments), this.filteredVias = this.otherHdRoutes.flatMap((e34) => {
if (this.isSameNetRoute(e34))
return [];
const n3 = e34.vias, o3 = [];
for (const i3 of n3) {
const n4 = this.OBSTACLE_MARGIN + this.clearanceTraceThickness / 2 + e34.viaDiameter / 2, r3 = i3.x - n4, s2 = i3.x + n4, a2 = i3.y - n4, c2 = i3.y + n4;
r3 <= t2.maxX && s2 >= t2.minX && a2 <= t2.maxY && c2 >= t2.minY && o3.push({ ...i3, diameter: e34.viaDiameter });
}
return o3;
});
const r2 = (e34, n3) => {
const o3 = [];
for (const i3 of e34) {
const e35 = dB[i3.footprint] ?? dB["0603"], r3 = i3.end.x - i3.start.x, s2 = i3.end.y - i3.start.y, a2 = Math.abs(r3) > Math.abs(s2), c2 = a2 ? e35.padLength : e35.padWidth, l2 = a2 ? e35.padWidth : e35.padLength, h2 = this.OBSTACLE_MARGIN + this.clearanceTraceThickness / 2;
i3.start.x - c2 / 2 - h2 <= t2.maxX && i3.start.x + c2 / 2 + h2 >= t2.minX && i3.start.y - l2 / 2 - h2 <= t2.maxY && i3.start.y + l2 / 2 + h2 >= t2.minY && o3.push({ center: i3.start, width: c2, height: l2, connectionName: n3 }), i3.end.x - c2 / 2 - h2 <= t2.maxX && i3.end.x + c2 / 2 + h2 >= t2.minX && i3.end.y - l2 / 2 - h2 <= t2.maxY && i3.end.y + l2 / 2 + h2 >= t2.minY && o3.push({ center: i3.end, width: c2, height: l2, connectionName: n3 });
}
return o3;
};
if (this.filteredJumperPads = this.otherHdRoutes.flatMap((e34) => this.isSameNetRoute(e34) ? [] : r2(e34.jumpers ?? [], e34.connectionName)), this.inputRoute.jumpers && this.inputRoute.jumpers.length > 0) {
this.filteredJumperPads.push(...r2(this.inputRoute.jumpers, this.inputRoute.connectionName));
for (const e34 of this.inputRoute.jumpers)
for (let t3 = 0;t3 < this.inputRoute.route.length; t3++) {
const n3 = this.inputRoute.route[t3];
(Math.abs(n3.x - e34.start.x) < 0.01 && Math.abs(n3.y - e34.start.y) < 0.01 || Math.abs(n3.x - e34.end.x) < 0.01 && Math.abs(n3.y - e34.end.y) < 0.01) && this.jumperPadPointIndices.add(t3);
}
}
this.computePathSegments();
}
computePathSegments() {
let e33 = 0;
for (let t2 = 0;t2 < this.inputRoute.route.length - 1; t2++) {
const n2 = this.inputRoute.route[t2], o2 = this.inputRoute.route[t2 + 1], i2 = Math.sqrt((o2.x - n2.x) ** 2 + (o2.y - n2.y) ** 2) + t2 / 1e4;
this.pathSegments.push({ start: n2, end: o2, length: i2, startDistance: e33, endDistance: e33 + i2 }), e33 += i2;
}
this.totalPathLength = e33;
}
arePointsEqual(e33, t2) {
return e33.x === t2.x && e33.y === t2.y && e33.z === t2.z;
}
getPointAtDistance(e33) {
e33 = Math.max(0, Math.min(e33, this.totalPathLength));
const t2 = this.pathSegments.find((t3) => e33 >= t3.startDistance && e33 <= t3.endDistance);
if (!t2)
return this.inputRoute.route[this.inputRoute.route.length - 1];
const n2 = (e33 - t2.startDistance) / t2.length;
return { x: t2.start.x + n2 * (t2.end.x - t2.start.x), y: t2.start.y + n2 * (t2.end.y - t2.start.y), z: n2 < 0.5 ? t2.start.z : t2.end.z };
}
getNearestIndexForDistance(e33) {
if (e33 <= 0)
return 0;
if (e33 >= this.totalPathLength)
return this.inputRoute.route.length - 1;
const t2 = this.pathSegments.findIndex((t3) => e33 >= t3.startDistance && e33 <= t3.endDistance);
if (t2 === -1)
return 0;
const n2 = this.pathSegments[t2], o2 = (n2.startDistance + n2.endDistance) / 2;
return e33 > o2 ? t2 + 1 : t2;
}
isValidPathSegment(e33, t2) {
for (const n3 of this.filteredObstacles) {
if (!n3.__zLayers?.includes(e33.z))
continue;
if (Lt(e33, t2, n3) < this.OBSTACLE_MARGIN + this.clearanceTraceThickness / 2)
return false;
}
const n2 = this.segmentTree.getSegmentsThatCouldIntersect(e33, t2);
for (const [o2, i2, r2] of n2)
if (o2.z === e33.z && i2.z === e33.z) {
const n3 = Jz({ x: e33.x, y: e33.y }, { x: t2.x, y: t2.y }, { x: o2.x, y: o2.y }, { x: i2.x, y: i2.y });
if (!this.useTraceWidthAwareClearance) {
if (n3 < this.OBSTACLE_MARGIN + this.TRACE_THICKNESS)
return false;
continue;
}
const s2 = this.traceThicknessByObstacleSegmentId.get(r2);
if (s2 === undefined)
throw new Error(`Missing trace thickness for segment "${r2}"`);
if (n3 < this.OBSTACLE_MARGIN + this.clearanceTraceThickness / 2 + s2 / 2)
return false;
}
for (const n3 of this.filteredVias)
if (xt(n3, e33, t2) < this.OBSTACLE_MARGIN + n3.diameter / 2 + this.clearanceTraceThickness / 2)
return false;
for (const n3 of this.filteredJumperPads) {
if (Lt(e33, t2, n3) < this.OBSTACLE_MARGIN + this.clearanceTraceThickness / 2)
return false;
}
if (this.outline && this.outline.length >= 3) {
if (rB({ start: { x: e33.x, y: e33.y }, end: { x: t2.x, y: t2.y }, polygon: this.outline, margin: this.minBoardEdgeClearance + this.inputRoute.traceThickness / 2 }))
return false;
}
return true;
}
isValidPath(e33) {
if (e33.length < 2)
return true;
for (let t2 = 0;t2 < e33.length - 1; t2++)
if (e33[t2].z !== e33[t2 + 1].z)
return false;
for (let t2 = 0;t2 < e33.length - 1; t2++)
if (!this.isValidPathSegment(e33[t2], e33[t2 + 1]))
return false;
return true;
}
find45DegreePath(e33, t2) {
if (this.arePointsEqual(e33, t2))
return [e33];
if (e33.z !== t2.z)
return null;
const n2 = Zz({ x: e33.x, y: e33.y }, { x: t2.x, y: t2.y });
for (const t3 of n2) {
const n3 = t3.map((t4) => ({ x: t4.x, y: t4.y, z: e33.z }));
if (this.isValidPath(n3))
return n3;
}
return null;
}
addPathToResult(e33) {
if (e33.length !== 0) {
for (let t2 = 0;t2 < e33.length; t2++)
t2 === 0 && this.newRoute.length > 0 && this.arePointsEqual(this.newRoute[this.newRoute.length - 1], e33[t2]) || this.newRoute.push(e33[t2]);
this.currentStepSize = this.maxStepSize;
}
}
appendOriginalRouteSlice(e33, t2) {
const n2 = this.pathSegments.findIndex((t3) => e33 >= t3.startDistance && e33 <= t3.endDistance);
if (n2 === -1)
throw new Error(`Could not find path segment containing distance ${e33}`);
for (let e34 = n2 + 1;e34 <= t2 && e34 < this.inputRoute.route.length; e34++) {
const t3 = this.inputRoute.route[e34], n3 = this.newRoute[this.newRoute.length - 1];
n3 && this.arePointsEqual(n3, t3) || this.newRoute.push({ ...t3 });
}
}
moveHead(e33) {
this.lastHeadMoveDistance = e33, this.headDistanceAlongPath = Math.min(this.headDistanceAlongPath + e33, 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 e33 = this.tailDistanceAlongPath >= this.totalPathLength, t2 = this.headDistanceAlongPath >= this.totalPathLength;
if (e33) {
const e34 = this.inputRoute.route[this.inputRoute.route.length - 1];
return this.newRoute.length !== 0 && this.arePointsEqual(this.newRoute[this.newRoute.length - 1], e34) || this.newRoute.push(e34), void (this.solved = true);
}
if (t2) {
const e34 = this.getPointAtDistance(this.tailDistanceAlongPath), t3 = this.inputRoute.route[this.inputRoute.route.length - 1], n3 = this.find45DegreePath(e34, t3);
if (n3)
return this.addPathToResult(n3), void (this.solved = true);
const o3 = this.lastValidPath ? this.lastValidPathHeadDistance : this.tailDistanceAlongPath;
this.lastValidPath && (this.addPathToResult(this.lastValidPath), this.lastValidPath = null);
this.getNearestIndexForDistance(o3);
return this.appendOriginalRouteSlice(o3, this.inputRoute.route.length - 1), this.tailDistanceAlongPath = this.totalPathLength, this.headDistanceAlongPath = this.totalPathLength, void (this.solved = true);
}
this.moveHead(this.currentStepSize);
const n2 = this.getPointAtDistance(this.tailDistanceAlongPath), o2 = this.getPointAtDistance(this.headDistanceAlongPath), i2 = this.getNearestIndexForDistance(this.tailDistanceAlongPath), r2 = this.getNearestIndexForDistance(this.headDistanceAlongPath);
let s2 = false, a2 = -1;
for (let e34 = i2;e34 < r2; e34++)
if (e34 + 1 < this.inputRoute.route.length && this.inputRoute.route[e34].z !== this.inputRoute.route[e34 + 1].z) {
s2 = true;
const t3 = e34;
a2 = this.pathSegments[t3].startDistance;
break;
}
if (s2 && this.lastHeadMoveDistance > this.minStepSize)
return void this.stepBackAndReduceStepSize();
let c2 = false, l2 = -1, h2 = -1;
for (let e34 = i2 + 1;e34 <= r2; e34++)
if (this.jumperPadPointIndices.has(e34)) {
c2 = true, l2 = e34, h2 = e34 > 0 && e34 - 1 < this.pathSegments.length ? this.pathSegments[e34 - 1].endDistance : this.pathSegments[0]?.startDistance ?? 0;
break;
}
if (c2 && this.lastHeadMoveDistance > this.minStepSize)
return void this.stepBackAndReduceStepSize();
if (c2 && l2 >= 0) {
const e34 = this.inputRoute.route[l2];
this.lastValidPath && (this.addPathToResult(this.lastValidPath), this.lastValidPath = null);
const t3 = this.newRoute[this.newRoute.length - 1];
return t3 && t3.x === e34.x && t3.y === e34.y || this.newRoute.push({ x: e34.x, y: e34.y, z: e34.z }), this.currentStepSize = this.maxStepSize, this.tailDistanceAlongPath = h2, this.headDistanceAlongPath = this.tailDistanceAlongPath, this.lastValidPath = null, void (this.lastValidPathHeadDistance = this.tailDistanceAlongPath);
}
if (s2 && a2 > 0) {
const e34 = this.lastValidPath ? this.lastValidPathHeadDistance : this.tailDistanceAlongPath, t3 = this.getNearestIndexForDistance(a2) + 1, n3 = this.inputRoute.route[t3], o3 = { x: n3.x, y: n3.y };
this.lastValidPath && (this.addPathToResult(this.lastValidPath), this.lastValidPath = null);
const i3 = this.newRoute[this.newRoute.length - 1], r3 = { x: o3.x, y: o3.y, z: i3.z };
if (!this.arePointsEqual(i3, r3)) {
const n4 = this.find45DegreePath(i3, r3);
n4 ? this.addPathToResult(n4) : this.appendOriginalRouteSlice(e34, t3 - 1);
}
this.newVias.push(o3), this.newRoute.push({ x: o3.x, y: o3.y, z: n3.z }), this.currentStepSize = this.maxStepSize;
const s3 = this.pathSegments.findIndex((e35) => e35.start === n3);
if (s3 !== -1)
this.tailDistanceAlongPath = this.pathSegments[s3].startDistance, this.headDistanceAlongPath = this.tailDistanceAlongPath, this.lastValidPath = null, this.lastValidPathHeadDistance = this.tailDistanceAlongPath;
else if (t3 < this.inputRoute.route.length) {
if (t3 === this.inputRoute.route.length - 1)
return void (this.solved = true);
console.warn("Fallback used for tailDistanceAlongPath after layer change");
const e35 = this.pathSegments.find((e36) => e36.start === this.inputRoute.route[t3]);
e35 ? (this.tailDistanceAlongPath = e35.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.
Index sought: ${t3}, Point: (${this.inputRoute.route[t3].x.toFixed(3)}, ${this.inputRoute.route[t3].y.toFixed(3)}, z=${this.inputRoute.route[t3].z})
Route Length: ${this.inputRoute.route.length}, Path Segments: ${this.pathSegments.length}`), this.solved = true);
} else
console.warn("Layer change occurred at the end of the path."), this.solved = true;
return;
}
const d2 = this.find45DegreePath(n2, o2);
if (!d2 && this.lastHeadMoveDistance > this.minStepSize)
this.stepBackAndReduceStepSize();
else {
if (!d2 && !this.lastValidPath) {
const e34 = this.getPointAtDistance(this.tailDistanceAlongPath);
this.tailDistanceAlongPath += this.minStepSize, this.moveHead(this.minStepSize);
const t3 = this.getNearestIndexForDistance(this.tailDistanceAlongPath), n3 = this.inputRoute.route[t3], o3 = this.inputRoute.route[this.inputRoute.route.length - 1];
return void (this.arePointsEqual(e34, n3) || this.arePointsEqual(n3, o3) || (this.newRoute.push(n3), this.tailDistanceAlongPath = t3 === 0 ? 0 : this.pathSegments[t3 - 1].endDistance));
}
if (d2)
return this.lastValidPath = d2, void (this.lastValidPathHeadDistance = this.headDistanceAlongPath);
this.lastValidPath && (this.addPathToResult(this.lastValidPath), this.lastValidPath = null, this.tailDistanceAlongPath = this.lastValidPathHeadDistance, this.moveHead(this.minStepSize));
}
}
visualize() {
const e33 = this.getVisualsForNewRouteAndObstacles(), t2 = this.getPointAtDistance(this.tailDistanceAlongPath), n2 = this.getPointAtDistance(this.headDistanceAlongPath);
e33.points.push({ x: t2.x, y: t2.y, color: "yellow", label: ["Tail", `z: ${t2.z}`].join(`
`) }), e33.points.push({ x: n2.x, y: n2.y, color: "orange", label: ["Head", `z: ${n2.z}`].join(`
`) });
const o2 = this.getPointAtDistance(this.headDistanceAlongPath + this.currentStepSize);
e33.points.push({ x: o2.x, y: o2.y, color: "red", label: ["Tentative Head", `z: ${o2.z}`].join(`
`) });
let i2 = 0;
for (;i2 < this.totalPathLength; ) {
const t3 = this.getPointAtDistance(i2);
e33.circles.push({ center: { x: t3.x, y: t3.y }, radius: 0.05, fill: "rgba(100, 100, 100, 0.5)" }), i2 += this.totalPathLength / 20;
}
if (this.lastValidPath && this.lastValidPath.length > 1)
for (let t3 = 0;t3 < this.lastValidPath.length - 1; t3++)
e33.lines.push({ points: [{ x: this.lastValidPath[t3].x, y: this.lastValidPath[t3].y }, { x: this.lastValidPath[t3 + 1].x, y: this.lastValidPath[t3 + 1].y }], strokeColor: "rgba(0, 255, 255, 0.9)", strokeDash: "3, 3" });
return e33;
}
};
var IB = class extends vB {
vertexIndex = 0;
constructor(e33) {
super(e33), this.newRoute = this.inputRoute.route.slice(0, 1).map((e34) => ({ ...e34 })), this.newVias = this.inputRoute.vias.map((e34) => ({ ...e34 }));
}
getSolverName() {
return "VertexShortcutPathSolver";
}
_step() {
const e33 = this.inputRoute.route, t2 = e33[this.vertexIndex];
if (this.vertexIndex >= e33.length - 1)
return void (this.solved = true);
let n2 = this.vertexIndex + 1;
const o2 = [0];
for (let t3 = this.vertexIndex;t3 < e33.length - 1; t3++) {
const i2 = e33[t3], r2 = e33[t3 + 1];
if (i2.z !== r2.z || i2.toNextSegmentType || i2.traceThickness !== r2.traceThickness || i2.traceThickness !== undefined && i2.traceThickness !== this.inputRoute.traceThickness || i2.insideJumperPad || r2.insideJumperPad)
break;
if (o2.push(o2.at(-1) + Math.hypot(r2.x - i2.x, r2.y - i2.y)), n2 = t3 + 1, r2.pcb_port_id || this.jumperPadPointIndices.has(n2))
break;
}
for (let i2 = n2;i2 > this.vertexIndex + 1; i2--) {
const n3 = e33[i2], r2 = o2[i2 - this.vertexIndex];
for (const e34 of Zz(t2, n3)) {
const o3 = e34.filter((t3, n4) => n4 === 0 || t3.x !== e34[n4 - 1].x || t3.y !== e34[n4 - 1].y).map((e35) => ({ ...e35, z: t2.z, traceThickness: t2.traceThickness })), s2 = o3.reduce((e35, t3, n4) => n4 === 0 ? e35 : e35 + Math.hypot(t3.x - o3[n4 - 1].x, t3.y - o3[n4 - 1].y), 0);
if (!(o3.length < 2 || s2 > r2 + 0.000000001 || s2 >= r2 - 0.000000001 && o3.length >= i2 - this.vertexIndex + 1) && this.isValidPath(o3))
return o3[o3.length - 1] = { ...n3 }, this.newRoute.push(...o3.slice(1)), void (this.vertexIndex = i2);
}
}
this.vertexIndex++, this.newRoute.push({ ...e33[this.vertexIndex] });
}
};
var SB = class extends Fz {
getSolverName() {
return "MultiSimplifiedPathSolver";
}
simplifiedHdRoutes;
currentUnsimplifiedHdRouteIndex = 0;
activeSubSolver = null;
unsimplifiedHdRoutes;
otherHdRoutes;
obstacles;
connMap;
colorMap;
outline;
minBoardEdgeClearance;
defaultViaDiameter;
useTraceWidthAwareClearance;
enableVertexShortcuts;
constructor(e33) {
super(), this.MAX_ITERATIONS = 1e8, this.unsimplifiedHdRoutes = e33.unsimplifiedHdRoutes, this.otherHdRoutes = e33.otherHdRoutes ?? [];
const t2 = Math.max(2, ...[...e33.unsimplifiedHdRoutes, ...this.otherHdRoutes].flatMap((e34) => e34.route.map((e35) => e35.z + 1))) || 2;
this.obstacles = fB(e33.obstacles, t2), this.connMap = e33.connMap || new ti({}), this.colorMap = e33.colorMap || {}, this.outline = e33.outline, this.minBoardEdgeClearance = e33.minBoardEdgeClearance ?? 0.2, this.defaultViaDiameter = e33.defaultViaDiameter ?? 0.3, this.useTraceWidthAwareClearance = e33.useTraceWidthAwareClearance ?? false, this.enableVertexShortcuts = e33.enableVertexShortcuts ?? false, this.simplifiedHdRoutes = [];
}
_step() {
const e33 = this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];
if (!this.activeSubSolver)
return e33 ? (this.activeSubSolver = new vB({ inputRoute: e33, 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 = true);
if (this.activeSubSolver.step(), this.activeSubSolver.solved) {
if (this.enableVertexShortcuts && !(this.activeSubSolver instanceof IB))
return void (this.activeSubSolver = new IB({ 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 e33 = { lines: [], points: [], circles: [], rects: [], coordinateSystem: "cartesian", title: "Multi Simplified Path Solver" };
for (const t2 of this.unsimplifiedHdRoutes)
if (!this.simplifiedHdRoutes.some((e34) => e34.connectionName === t2.connectionName)) {
for (let n2 = 0;n2 < t2.route.length - 1; n2++)
e33.lines.push({ points: [{ x: t2.route[n2].x, y: t2.route[n2].y }, { x: t2.route[n2 + 1].x, y: t2.route[n2 + 1].y }], strokeColor: t2.route[n2].z === 1 ? "rgba(0, 0, 255, 0.4)" : "rgba(255, 0, 0, 0.4)", strokeWidth: 0.15, strokeDash: t2.route[n2].z === 1 ? [0.5, 0.5] : undefined });
for (const n2 of t2.vias || [])
e33.circles.push({ center: n2, radius: (t2.viaDiameter ?? this.defaultViaDiameter) / 2, fill: "rgba(0, 0, 255, 0.4)" });
}
for (const t2 of this.simplifiedHdRoutes) {
const n2 = this.colorMap?.[t2.connectionName] || "rgba(128, 128, 128, 0.8)";
for (let o2 = 0;o2 < t2.route.length - 1; o2++)
e33.lines.push({ points: [{ x: t2.route[o2].x, y: t2.route[o2].y }, { x: t2.route[o2 + 1].x, y: t2.route[o2 + 1].y }], strokeWidth: 0.15, strokeColor: n2, strokeDash: t2.route[o2].z === 1 ? [0.5, 0.5] : undefined, step: 1 });
for (const n3 of t2.vias || [])
e33.circles.push({ center: n3, radius: t2.viaDiameter / 2, fill: "rgba(0, 0, 255, 0.5)", step: 1 });
}
for (const t2 of this.unsimplifiedHdRoutes) {
for (let n2 = 0;n2 < t2.route.length - 1; n2++)
e33.lines.push({ points: [{ x: t2.route[n2].x, y: t2.route[n2].y }, { x: t2.route[n2 + 1].x, y: t2.route[n2 + 1].y }], strokeWidth: 0.15, strokeColor: "rgba(255, 0, 0, 0.2)", strokeDash: [0.5, 0.5], step: 0, layer: `z${t2.route[n2].z.toString()}` });
for (const n2 of t2.vias)
e33.circles.push({ center: { x: n2.x, y: n2.y }, radius: t2.viaDiameter / 2, fill: "rgba(255, 0, 0, 0.2)", step: 0 });
}
for (const t2 of this.obstacles)
e33.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: t2.layers?.includes("top") ? "rgba(255, 0, 0, 0.3)" : t2.layers?.includes("bottom") ? "rgba(0, 0, 255, 0.3)" : "rgba(128, 128, 128, 0.3)" });
if (this.currentUnsimplifiedHdRouteIndex < this.unsimplifiedHdRoutes.length) {
const t2 = this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];
t2.route.length > 0 && e33.circles.push({ center: { x: t2.route[0].x, y: t2.route[0].y }, radius: 0.2, fill: "yellow", label: "Current" });
}
return e33;
}
};
var CB = (e33, t2) => {
for (let n2 = 0;n2 < e33.route.length - 1; n2++) {
const o2 = e33.route[n2], i2 = e33.route[n2 + 1];
if (o2.z === i2.z || o2.x !== t2.x || o2.y !== t2.y || i2.x !== t2.x || i2.y !== t2.y)
continue;
let r2 = n2;
for (;r2 > 0 && e33.route[r2 - 1].x === t2.x && e33.route[r2 - 1].y === t2.y; )
r2--;
let s2 = n2 + 1;
for (;s2 < e33.route.length - 1 && e33.route[s2 + 1].x === t2.x && e33.route[s2 + 1].y === t2.y; )
s2++;
if (r2 === 0 || s2 === e33.route.length - 1)
return true;
}
return false;
};
var PB = (e33, t2, n2) => n2?.get(t2.connectionName) ?? e33.idToNetMap[t2.connectionName] ?? (t2.rootConnectionName ? e33.idToNetMap[t2.rootConnectionName] : undefined);
var MB = (e33, t2, n2) => {
for (const o2 of t2.connectedTo) {
if (o2 === n2.net)
return true;
if (e33.idToNetMap[o2] === n2.net)
return true;
if (e33.areIdsConnected(o2, n2.net))
return true;
}
return false;
};
var wB = (e33, t2, n2) => {
const o2 = n2.mergedViaHdRoutes[e33.routeIndex];
if (!o2)
throw new Error(`SameNetViaMergerSolver could not find route for via at index ${e33.routeIndex}`);
const i2 = new Set;
for (let t3 = 1;t3 < o2.route.length; t3++) {
const n3 = o2.route[t3 - 1], r2 = o2.route[t3];
n3.z !== r2.z && (n3.x === e33.x && n3.y === e33.y && r2.x === e33.x && r2.y === e33.y && (i2.add(n3.z), i2.add(r2.z)));
}
if (i2.size === 0)
throw new Error(`SameNetViaMergerSolver could not find transition layers for via at (${e33.x}, ${e33.y})`);
for (const r2 of i2) {
const i3 = o2.traceThickness, s2 = { x: e33.x, y: e33.y, z: r2 }, a2 = { x: t2.x, y: t2.y, z: r2 };
if (s2.x === a2.x && s2.y === a2.y)
continue;
const c2 = n2.hdRouteSHI.getConflictingRoutesForSegment(s2, a2, i3 / 2);
for (const { conflictingRoute: t3, distance: r3 } of c2) {
if (t3.connectionName === o2.connectionName)
continue;
if (PB(n2.connMap, t3, n2.netByConnectionName) === e33.net)
continue;
if (r3 < i3 / 2 + t3.traceThickness / 2)
return false;
}
const l2 = { centerX: (s2.x + a2.x) / 2, centerY: (s2.y + a2.y) / 2, width: Math.abs(s2.x - a2.x), height: Math.abs(s2.y - a2.y) }, h2 = i3 / 2 + 0.1, d2 = n2.obstacleSHI.searchArea(l2.centerX, l2.centerY, l2.width + 2 * h2, l2.height + 2 * h2);
for (const t3 of d2) {
if (!t3.__zLayers)
throw new Error(`SameNetViaMergerSolver found obstacle without zLayers near via at (${e33.x}, ${e33.y})`);
if (t3.__zLayers.includes(r2) && (!MB(n2.connMap, t3, e33) && Lt(s2, a2, t3) < h2))
return false;
}
}
return true;
};
var NB = class extends Fz {
constructor(e33) {
if (super(), this.input = e33, !e33.connMap)
throw new Error("SameNetViaMergerSolver requires connMap");
this.input = { ...e33, obstacles: fB(e33.obstacles, e33.layerCount) }, this.MAX_ITERATIONS = 1e6, this.inputHdRoutes = this.input.inputHdRoutes, this.mergedViaHdRoutes = structuredClone(this.inputHdRoutes);
for (const e34 of this.mergedViaHdRoutes)
this.dedupeRouteVias(e34);
this.unprocessedRoutes = [...this.input.inputHdRoutes], this.colorMap = this.input.colorMap, this.outline = this.input.outline, this.obstacles = this.input.obstacles, this.obstacleSHI = new Yz("flatbush", this.input.obstacles), this.hdRouteSHI = this.createHdRouteSpatialIndex(), this.vias = [], this.offendingVias = [], this.connMap = e33.connMap, this.netByConnectionName = e33.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 Uz([...this.mergedViaHdRoutes, ...this.input.otherHdRoutes ?? []]);
}
rebuildVias() {
this.vias = [], this.viasByNet = new Map;
const e33 = (e34, t2, n2) => {
if (e34.vias.length === 0)
return;
const o2 = n2 ? ((e35, t3, n3) => {
const o3 = PB(e35, t3, n3);
if (!o3)
throw new Error(`SameNetViaMergerSolver could not find net for route "${t3.connectionName}"`);
return o3;
})(this.connMap, e34, this.netByConnectionName) : PB(this.connMap, e34, this.netByConnectionName);
if (o2)
for (let i2 = 0;i2 < e34.vias.length; i2++) {
const r2 = e34.vias[i2], s2 = [...new Set(e34.route.map((e35) => e35.z))];
if (s2.length === 0)
throw new Error(`SameNetViaMergerSolver found via on route "${e34.connectionName}" with no route points`);
const a2 = { x: r2.x, y: r2.y, diameter: e34.viaDiameter, net: o2, layers: s2, routeIndex: t2, mutable: n2 && !(this.input.preserveRouteEndpoints && CB(e34, r2)) };
this.vias.push(a2);
const c2 = this.viasByNet.get(a2.net);
c2 ? c2.push(a2) : this.viasByNet.set(a2.net, [a2]);
}
};
for (let t2 = 0;t2 < this.mergedViaHdRoutes.length; t2++)
e33(this.mergedViaHdRoutes[t2], t2, true);
for (let t2 = 0;t2 < (this.input.otherHdRoutes?.length ?? 0); t2++)
e33(this.input.otherHdRoutes[t2], this.mergedViaHdRoutes.length + t2, false);
}
getViaLocationKey(e33) {
return [e33.net, e33.x, e33.y].join(":");
}
dedupeRouteVias(e33) {
const t2 = new Set;
e33.vias = e33.vias.filter((e34) => {
const n2 = `${e34.x}:${e34.y}`;
return !t2.has(n2) && (t2.add(n2), true);
});
}
getOffendingViaGroupsBatch() {
const e33 = [], t2 = new Set, n2 = [];
for (const e34 of this.viasByNet.values()) {
if (e34.length < 2)
continue;
const t3 = Math.max(0.000001, ...e34.map((e35) => e35.diameter)), o2 = new Map, i2 = new Map;
for (let n3 = 0;n3 < e34.length; n3++) {
const r2 = e34[n3], s2 = this.getViaLocationKey(r2), a2 = i2.get(s2);
a2 ? a2.push(r2) : i2.set(s2, [r2]);
const c2 = `${Math.floor(r2.x / t3)}:${Math.floor(r2.y / t3)}`, l2 = o2.get(c2);
l2 ? l2.push(n3) : o2.set(c2, [n3]);
}
for (let r2 = 0;r2 < e34.length; r2++) {
const s2 = e34[r2], a2 = Math.floor(s2.x / t3), c2 = Math.floor(s2.y / t3), l2 = Math.ceil(2.5), h2 = [];
for (let t4 = -l2;t4 <= l2; t4++)
for (let n3 = -l2;n3 <= l2; n3++) {
const i3 = o2.get(`${a2 + t4}:${c2 + n3}`);
if (i3)
for (const t5 of i3) {
if (t5 === r2)
continue;
const n4 = e34[t5];
if (!n4.mutable)
continue;
const o3 = s2.x - n4.x, i4 = s2.y - n4.y, a3 = o3 * o3 + i4 * i4, c3 = s2.diameter / 2 + n4.diameter / 2, l3 = 2.5 * c3;
a3 !== 0 && ((a3 <= c3 * c3 || a3 <= l3 * l3 && wB(n4, s2, { connMap: this.connMap, mergedViaHdRoutes: this.mergedViaHdRoutes, hdRouteSHI: this.hdRouteSHI, obstacleSHI: this.obstacleSHI, netByConnectionName: this.netByConnectionName })) && h2.push(n4));
}
}
const d2 = new Set(h2), u2 = h2.filter((e35) => e35.x === s2.x && e35.y === s2.y || i2.get(this.getViaLocationKey(e35)).every((e36) => e36.mutable && d2.has(e36)));
u2.length > 0 && n2.push({ keep: s2, remove: u2 });
}
}
n2.sort((e34, t3) => t3.remove.length !== e34.remove.length ? t3.remove.length - e34.remove.length : e34.keep.mutable !== t3.keep.mutable ? e34.keep.mutable ? 1 : -1 : t3.keep.layers.length !== e34.keep.layers.length ? t3.keep.layers.length - e34.keep.layers.length : e34.keep.routeIndex - t3.keep.routeIndex);
for (const o2 of n2) {
const n3 = this.getViaLocationKey(o2.keep);
if (t2.has(n3))
continue;
const i2 = o2.remove.filter((e34) => !t2.has(this.getViaLocationKey(e34)));
if (i2.length !== 0) {
e33.push({ keep: o2.keep, remove: i2 }), t2.add(n3);
for (const e34 of i2)
t2.add(this.getViaLocationKey(e34));
}
}
return e33;
}
moveViaTo(e33, t2, n2 = true) {
if (!e33.mutable)
throw new Error("SameNetViaMergerSolver cannot mutate an immutable via anchor");
const o2 = this.mergedViaHdRoutes[e33.routeIndex];
if (!o2)
throw new Error(`SameNetViaMergerSolver could not find route for via at index ${e33.routeIndex}`);
const i2 = o2.route, r2 = new Set;
let s2 = false;
for (let t3 = i2.length - 1;t3 >= 1; t3--) {
const n3 = i2[t3 - 1], o3 = i2[t3];
if (n3.z === o3.z)
continue;
if (n3.x !== e33.x || n3.y !== e33.y)
continue;
if (o3.x !== e33.x || o3.y !== e33.y)
continue;
let s3 = t3 - 1;
for (;s3 > 0 && i2[s3 - 1].x === e33.x && i2[s3 - 1].y === e33.y; )
s3--;
let a2 = t3;
for (;a2 < i2.length - 1 && i2[a2 + 1].x === e33.x && i2[a2 + 1].y === e33.y; )
a2++;
for (let e34 = s3;e34 <= a2; e34++)
r2.add(e34);
}
if (r2.size === 0)
throw new Error(`SameNetViaMergerSolver could not find route transition for via at (${e33.x}, ${e33.y}) on route "${o2.connectionName}"`);
for (const e34 of r2) {
const n3 = i2[e34];
i2[e34] = { ...n3, x: t2.x, y: t2.y };
}
if (o2.vias = o2.vias.map((n3) => n3.x !== e33.x || n3.y !== e33.y ? n3 : (s2 = true, { x: t2.x, y: t2.y })), !s2)
throw new Error(`SameNetViaMergerSolver could not find via at (${e33.x}, ${e33.y}) on route "${o2.connectionName}"`);
this.dedupeRouteVias(o2), n2 && this.rebuildVias();
}
_step() {
const e33 = this.getOffendingViaGroupsBatch();
if (e33.length === 0)
return void (this.solved = true);
let t2 = 0;
for (const n2 of e33)
for (const e34 of n2.remove)
this.moveViaTo(e34, n2.keep, false), t2++;
this.rebuildVias(), this.hdRouteSHI = this.createHdRouteSpatialIndex(), this.stats.mergedViaGroups = e33.length, this.stats.mergedViaCount = t2;
}
getMergedViaHdRoutes() {
return this.mergedViaHdRoutes;
}
visualize() {
const e33 = { lines: [], points: [], rects: [], circles: [], coordinateSystem: "cartesian", title: "Same Net Via Merger Solver" };
for (const t2 of this.input.obstacles) {
if (!t2.__zLayers)
throw new Error("SameNetViaMergerSolver found obstacle without zLayers while visualizing");
let n2 = "rgba(128, 128, 128, 0.2)";
const o2 = t2.__zLayers.includes(0), i2 = t2.__zLayers.includes(1);
o2 && i2 ? n2 = "rgba(128, 0, 128, 0.2)" : o2 ? n2 = "rgba(255, 0, 0, 0.2)" : i2 && (n2 = "rgba(0, 0, 255, 0.2)"), e33.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: n2, label: `Obstacle (Z: ${t2.__zLayers?.join(", ")})` });
}
for (const t2 of this.mergedViaHdRoutes) {
if (t2.route.length === 0)
continue;
const n2 = this.input.colorMap[t2.connectionName];
if (!n2)
throw new Error(`SameNetViaMergerSolver could not find color for route "${t2.connectionName}"`);
for (let n3 = 0;n3 < t2.route.length - 1; n3++) {
const o2 = t2.route[n3], i2 = t2.route[n3 + 1];
o2.z === i2.z && e33.lines.push({ points: [{ x: o2.x, y: o2.y }, { x: i2.x, y: i2.y }], strokeColor: o2.z === 0 ? "rgba(255, 0, 0, 0.5)" : "rgba(0, 0, 255, 0.5)", strokeWidth: t2.traceThickness, label: `${t2.connectionName} (z=${o2.z})` });
}
for (const n3 of t2.vias)
e33.circles.push({ center: { x: n3.x, y: n3.y }, radius: t2.viaDiameter / 2, fill: "rgba(255, 0, 255, 0.5)", label: `${t2.connectionName} via` });
if (t2.jumpers && t2.jumpers.length > 0) {
const o2 = pB(t2.jumpers, { color: n2, label: t2.connectionName });
if (!o2.rects || !o2.lines)
throw new Error(`SameNetViaMergerSolver expected jumper graphics for route "${t2.connectionName}"`);
e33.rects.push(...o2.rects), e33.lines.push(...o2.lines);
}
}
return e33;
}
};
var TB = { getConflictingRoutesForSegment: () => [], getConflictingRoutesNearPoint: () => [] };
var RB = 0.000001;
var EB = (e33, t2) => {
const n2 = `${e33.x}:${e33.y}:${e33.z}`, o2 = `${t2.x}:${t2.y}:${t2.z}`;
return n2 < o2 ? `${n2}|${o2}` : `${o2}|${n2}`;
};
var AB = (e33) => {
const t2 = new Set;
for (let n2 = 1;n2 < e33.route.length; n2++) {
const o2 = e33.route[n2 - 1], i2 = e33.route[n2];
o2.z === i2.z && t2.add(EB(o2, i2));
}
return t2;
};
var OB = (e33) => e33.filter((t2, n2) => {
const o2 = e33[n2 - 1];
return !o2 || t2.x !== o2.x || t2.y !== o2.y || t2.z !== o2.z;
});
var kB = (e33) => {
const t2 = [], n2 = new Set;
for (let o2 = 1;o2 < e33.length; o2++) {
const i2 = e33[o2 - 1], r2 = e33[o2];
if (i2.z === r2.z)
continue;
if (i2.toNextSegmentType === "through_obstacle")
continue;
if (i2.x !== r2.x || i2.y !== r2.y)
throw new Error(`CrossingViaReductionSolver found a layer transition without a via at route point ${o2}`);
const s2 = `${r2.x}:${r2.y}`;
n2.has(s2) || (n2.add(s2), t2.push({ x: r2.x, y: r2.y }));
}
return t2;
};
var DB = (e33) => {
const t2 = [e33.connectionName];
return e33.rootConnectionName && t2.push(e33.rootConnectionName), t2;
};
var LB = (e33, t2, n2) => {
const o2 = DB(e33), i2 = DB(t2);
return o2.some((e34) => i2.some((t3) => e34 === t3 || n2.areIdsConnected(e34, t3)));
};
var zB = (e33, t2, n2) => {
const o2 = DB(t2);
return e33.connectedTo.some((e34) => o2.some((t3) => e34 === t3 || n2.areIdsConnected(e34, t3)));
};
var BB = (e33) => {
let t2 = 0;
for (let n2 = 1;n2 < e33.length; n2++)
t2 += Math.hypot(e33[n2].x - e33[n2 - 1].x, e33[n2].y - e33[n2 - 1].y);
return t2;
};
var FB = (e33, t2) => {
const n2 = BB(e33);
if (t2 <= RB || t2 >= n2 - RB)
return null;
let o2 = 0;
for (let n3 = 1;n3 < e33.length; n3++) {
const i2 = e33[n3 - 1], r2 = e33[n3], s2 = Math.hypot(r2.x - i2.x, r2.y - i2.y);
if (o2 + s2 < t2 - RB) {
o2 += s2;
continue;
}
const a2 = t2 - o2;
if (a2 <= RB)
return { prefix: e33.slice(0, n3).map((e34) => ({ ...e34 })), suffix: e33.slice(n3 - 1).map((e34) => ({ ...e34 })), point: { ...i2 } };
if (s2 - a2 <= RB)
return { prefix: e33.slice(0, n3 + 1).map((e34) => ({ ...e34 })), suffix: e33.slice(n3).map((e34) => ({ ...e34 })), point: { ...r2 } };
const c2 = a2 / s2, l2 = { x: i2.x + (r2.x - i2.x) * c2, y: i2.y + (r2.y - i2.y) * c2, z: i2.z };
return { prefix: [...e33.slice(0, n3), l2].map((e34) => ({ ...e34 })), suffix: [l2, ...e33.slice(n3)].map((e34) => ({ ...e34 })), point: l2 };
}
return null;
};
var jB = (e33, t2, n2, o2) => {
const i2 = It(e33, t2, n2, o2);
if (!i2)
return null;
const r2 = Math.hypot(i2.x - e33.x, i2.y - e33.y), s2 = Math.hypot(i2.x - t2.x, i2.y - t2.y), a2 = Math.hypot(i2.x - n2.x, i2.y - n2.y), c2 = Math.hypot(i2.x - o2.x, i2.y - o2.y);
return Math.min(r2, s2, a2, c2) <= RB ? null : r2;
};
var $B = (e33) => e33.points.some((e34) => e34.insideJumperPad || e34.toNextSegmentType);
var YB = ({ sections: e33, sectionIndex: t2, side: n2 }) => {
const o2 = e33[t2], i2 = n2 === "start" ? e33[t2 - 1] : e33[t2 + 1];
if (!i2)
return null;
const r2 = n2 === "start" ? o2.points[0] : o2.points.at(-1), s2 = n2 === "start" ? i2.points.at(-1) : i2.points[0];
return r2.x !== s2.x || r2.y !== s2.y ? null : i2.z;
};
var XB = ({ sections: e33, sectionIndex: t2, targetZ: n2, side: o2 }) => YB({ sections: e33, sectionIndex: t2, side: o2 }) === n2;
var WB = ({ baseIndexes: e33, otherCandidateRoutes: t2, ignoredConnectionNames: n2, originalRouteSegmentKeys: o2 }) => {
const i2 = new Uz([...t2]);
return { getConflictingRoutesForSegment: (t3, r2, s2) => {
const a2 = o2.has(EB(t3, r2));
return [...a2 ? [] : e33.mutableRoutes.getConflictingRoutesForSegment(t3, r2, s2).filter(({ conflictingRoute: e34 }) => !n2.has(e34.connectionName)), ...a2 ? [] : e33.immutableRoutes?.getConflictingRoutesForSegment(t3, r2, s2) ?? [], ...i2.getConflictingRoutesForSegment(t3, r2, s2)];
}, getConflictingRoutesNearPoint: (t3, o3) => [...e33.mutableRoutes.getConflictingRoutesNearPoint(t3, o3).filter(({ conflictingRoute: e34 }) => !n2.has(e34.connectionName)), ...e33.immutableRoutes?.getConflictingRoutesNearPoint(t3, o3) ?? [], ...i2.getConflictingRoutesNearPoint(t3, o3)] };
};
var VB = class extends Fz {
input;
obstacleSHI;
traceMargin;
obstacleMargin;
reducedHdRoutes;
getSolverName() {
return "CrossingViaReductionSolver";
}
constructor(e33) {
super(), this.input = { ...e33, obstacles: fB(e33.obstacles, e33.layerCount) }, this.traceMargin = e33.traceMargin ?? 0.1, this.obstacleMargin = e33.obstacleMargin ?? 0.15, this.reducedHdRoutes = structuredClone([...e33.inputHdRoutes]), this.obstacleSHI = new Yz("flatbush", [...this.input.obstacles]), this.MAX_ITERATIONS = 1e6;
}
collapseDetourSection({ route: e33, section: t2, targetZ: n2 }) {
const o2 = t2.points.map((e34) => ({ ...e34, z: n2 })), i2 = OB([...e33.route.slice(0, t2.startIndex).map((e34) => ({ ...e34 })), ...o2, ...e33.route.slice(t2.endIndex + 1).map((e34) => ({ ...e34 }))]);
return { ...e33, route: i2, vias: kB(i2) };
}
relocateTransitionVia({ route: e33, section: t2, targetZ: n2, side: o2, newViaDistance: i2 }) {
const r2 = FB(t2.points, i2);
if (!r2)
return null;
const s2 = o2 === "start" ? n2 : t2.z, a2 = o2 === "start" ? t2.z : n2, c2 = [...r2.prefix.map((e34) => ({ ...e34, z: s2 })), ...r2.suffix.map((e34) => ({ ...e34, z: a2 }))], l2 = OB([...e33.route.slice(0, t2.startIndex).map((e34) => ({ ...e34 })), ...c2, ...e33.route.slice(t2.endIndex + 1).map((e34) => ({ ...e34 }))]);
return { route: { ...e33, route: l2, vias: kB(l2) }, relocatedVia: { x: r2.point.x, y: r2.point.y } };
}
relocateTransitionVias({ route: e33, sections: t2, crossingGroups: n2, detourZ: o2, detourTraceThickness: i2 }) {
const r2 = new Map;
for (const e34 of n2) {
const t3 = r2.get(e34.transitionSectionIndex) ?? [];
t3.push(e34), r2.set(e34.transitionSectionIndex, t3);
}
const s2 = [], a2 = [], c2 = e33.viaDiameter / 2 + i2 / 2 + this.traceMargin + RB;
for (const [e34, n3] of r2) {
if (n3.length !== 1)
return null;
const i3 = t2[e34], r3 = n3[0];
if (!XB({ sections: t2, sectionIndex: e34, targetZ: o2, side: r3.side }))
return null;
const l3 = r3.side === "start" ? Math.max(...r3.crossingDistances) + c2 : Math.min(...r3.crossingDistances) - c2, h2 = FB(i3.points, l3);
if (!h2)
return null;
const d2 = r3.side === "start" ? o2 : i3.z, u2 = r3.side === "start" ? i3.z : o2;
s2.push({ section: i3, points: [...h2.prefix.map((e35) => ({ ...e35, z: d2 })), ...h2.suffix.map((e35) => ({ ...e35, z: u2 }))] }), a2.push({ x: h2.point.x, y: h2.point.y });
}
let l2 = e33.route.map((e34) => ({ ...e34 }));
for (const e34 of s2.sort((e35, t3) => t3.section.startIndex - e35.section.startIndex))
l2 = [...l2.slice(0, e34.section.startIndex), ...e34.points, ...l2.slice(e34.section.endIndex + 1)];
return l2 = OB(l2), { route: { ...e33, route: l2, vias: kB(l2) }, relocatedVias: a2 };
}
routeIsClear(e33, t2, n2) {
for (const o2 of sB(e33)) {
for (let t3 = 1;t3 < o2.points.length; t3++) {
const i2 = o2.points[t3 - 1], r2 = o2.points[t3];
if (!n2.has(EB(i2, r2)) && this.input.outline && rB({ start: i2, end: r2, polygon: [...this.input.outline], margin: e33.traceThickness / 2 }))
return false;
}
if (!cB({ currentSection: o2, targetZ: o2.z, route: e33, hdRouteSHI: t2, obstacleSHI: this.obstacleSHI, connMap: this.input.connMap, defaultTraceThickness: e33.traceThickness, obstacleMargin: this.obstacleMargin, traceMargin: this.traceMargin, shouldCheckStaticGeometryForSegment: (e34, t3) => !n2.has(EB(e34, t3)) }))
return false;
}
return true;
}
relocatedViaIsClear(e33, t2, n2) {
const o2 = e33.viaDiameter / 2;
for (let i3 = 0;i3 < this.input.layerCount; i3++) {
if (n2.getConflictingRoutesNearPoint({ ...t2, z: i3 }, o2 + this.traceMargin).some(({ conflictingRoute: t3 }) => !LB(e33, t3, this.input.connMap)))
return false;
}
const i2 = o2 + this.obstacleMargin, r2 = this.obstacleSHI.searchArea(t2.x, t2.y, 2 * i2, 2 * i2);
for (const n3 of r2)
if (!zB(n3, e33, this.input.connMap) && Lt(t2, t2, n3) < i2)
return false;
if (this.input.outline)
for (let e34 = 0;e34 < this.input.outline.length; e34++) {
if (xt(t2, this.input.outline[e34], this.input.outline[(e34 + 1) % this.input.outline.length]) < o2 + this.traceMargin)
return false;
}
return true;
}
changedSectionsAreStaticallyClear(e33, t2) {
for (const n2 of sB(e33)) {
if (n2.points.some((e34, o2) => {
const i2 = n2.points[o2 - 1];
return i2 !== undefined && !t2.has(EB(i2, e34));
})) {
if (this.input.outline) {
for (let t3 = 1;t3 < n2.points.length; t3++)
if (rB({ start: n2.points[t3 - 1], end: n2.points[t3], polygon: [...this.input.outline], margin: e33.traceThickness / 2 }))
return false;
}
if (!cB({ currentSection: n2, targetZ: n2.z, route: e33, hdRouteSHI: TB, obstacleSHI: this.obstacleSHI, connMap: this.input.connMap, defaultTraceThickness: e33.traceThickness, obstacleMargin: Math.min(this.obstacleMargin, 0.1), traceMargin: this.traceMargin }))
return false;
}
}
return true;
}
candidateIsClear(e33, t2) {
const n2 = [{ routeIndex: e33.detourRouteIndex, route: e33.detourRoute }, ...e33.transitionUpdates], o2 = new Set(n2.map(({ routeIndex: e34 }) => this.reducedHdRoutes[e34].connectionName)), i2 = AB(this.reducedHdRoutes[e33.detourRouteIndex]), r2 = WB({ baseIndexes: t2, otherCandidateRoutes: e33.transitionUpdates.map(({ route: e34 }) => e34), ignoredConnectionNames: o2, originalRouteSegmentKeys: i2 });
if (this.stats.candidateClearanceChecks = (this.stats.candidateClearanceChecks ?? 0) + 1, !this.routeIsClear(e33.detourRoute, r2, i2))
return false;
for (const i3 of e33.transitionUpdates) {
const e34 = AB(this.reducedHdRoutes[i3.routeIndex]), r3 = WB({ baseIndexes: t2, otherCandidateRoutes: n2.filter(({ routeIndex: e35 }) => e35 !== i3.routeIndex).map(({ route: e35 }) => e35), ignoredConnectionNames: o2, originalRouteSegmentKeys: e34 });
if (!this.routeIsClear(i3.route, r3, e34) || i3.relocatedVias.some((e35) => !this.relocatedViaIsClear(i3.route, e35, r3)))
return false;
}
return this.changedSectionsAreStaticallyClear(e33.detourRoute, i2);
}
candidateRoutesHaveNoExternalCopperConflicts(e33, t2) {
const n2 = [e33.detourRoute, ...e33.transitionUpdates.map(({ route: e34 }) => e34)], o2 = new Set(n2.map(({ connectionName: e34 }) => e34)), i2 = [t2.mutableRoutes, ...t2.immutableRoutes ? [t2.immutableRoutes] : []];
for (const e34 of n2)
for (const t3 of sB(e34))
for (let n3 = 1;n3 < t3.points.length; n3++) {
const r2 = t3.points[n3 - 1], s2 = t3.points[n3];
for (const t4 of i2) {
if (t4.getConflictingRoutesForSegment(r2, s2, e34.traceThickness / 2 + this.traceMargin).some(({ conflictingRoute: t5 }) => !o2.has(t5.connectionName) && !LB(e34, t5, this.input.connMap)))
return false;
}
}
return true;
}
buildTransitionSegmentIndex(e33, t2) {
const n2 = [];
for (let o3 = 0;o3 < this.reducedHdRoutes.length; o3++) {
if (this.reducedHdRoutes[o3].jumpers?.length)
continue;
const i2 = e33[o3];
for (let e34 = 0;e34 < i2.length; e34++) {
const r2 = i2[e34];
if (!$B(r2))
for (const s2 of ["start", "end"]) {
const a2 = YB({ sections: i2, sectionIndex: e34, side: s2 });
if (a2 === null || a2 === r2.z)
continue;
if (!t2.has(`${r2.z}:${a2}`))
continue;
let c2 = 0;
for (let t3 = 1;t3 < r2.points.length; t3++) {
const i3 = r2.points[t3 - 1], l2 = r2.points[t3], h2 = Math.hypot(l2.x - i3.x, l2.y - i3.y);
h2 > RB && n2.push({ routeIndex: o3, sectionIndex: e34, side: s2, adjacentZ: a2, start: i3, end: l2, distanceFromSectionStart: c2 }), c2 += h2;
}
}
}
}
if (this.stats.transitionSegmentsIndexed = (this.stats.transitionSegmentsIndexed ?? 0) + n2.length, n2.length === 0)
return null;
const o2 = new $z(n2.length);
for (const e34 of n2)
o2.insert(e34, Math.min(e34.start.x, e34.end.x), Math.min(e34.start.y, e34.end.y), Math.max(e34.start.x, e34.end.x), Math.max(e34.start.y, e34.end.y));
return o2.finish(), o2;
}
getIndexedCrossingGroups({ detourRouteIndex: e33, detourSection: t2, targetZ: n2, transitionSegmentIndex: o2 }) {
const i2 = new Map;
for (let r2 = 1;r2 < t2.points.length; r2++) {
const s2 = t2.points[r2 - 1], a2 = t2.points[r2];
if (Math.hypot(a2.x - s2.x, a2.y - s2.y) <= RB)
continue;
this.stats.indexedDetourSegmentQueries = (this.stats.indexedDetourSegmentQueries ?? 0) + 1;
const c2 = o2.search(Math.min(s2.x, a2.x) - RB, Math.min(s2.y, a2.y) - RB, Math.max(s2.x, a2.x) + RB, Math.max(s2.y, a2.y) + RB);
for (const o3 of c2) {
if (o3.routeIndex === e33 || o3.start.z !== n2 || o3.adjacentZ !== t2.z)
continue;
this.stats.exactSegmentIntersectionChecks = (this.stats.exactSegmentIntersectionChecks ?? 0) + 1;
const r3 = jB(o3.start, o3.end, s2, a2);
if (r3 === null)
continue;
const c3 = `${o3.routeIndex}:${o3.sectionIndex}:${o3.side}`;
let l2 = i2.get(c3);
l2 || (l2 = { transitionRouteIndex: o3.routeIndex, transitionSectionIndex: o3.sectionIndex, side: o3.side, crossingDistances: [] }, i2.set(c3, l2)), l2.crossingDistances.push(o3.distanceFromSectionStart + r3);
}
}
return [...i2.values()].sort((e34, t3) => e34.transitionRouteIndex !== t3.transitionRouteIndex ? e34.transitionRouteIndex - t3.transitionRouteIndex : e34.transitionSectionIndex !== t3.transitionSectionIndex ? e34.transitionSectionIndex - t3.transitionSectionIndex : e34.side === t3.side ? 0 : e34.side === "start" ? -1 : 1);
}
tryCreateCandidate({ detourRouteIndex: e33, detourSection: t2, targetZ: n2, transitionRouteIndex: o2, transitionSection: i2, transitionSections: r2, transitionSectionIndex: s2, side: a2, crossingDistances: c2, baseClearanceIndexes: l2 }) {
if (!XB({ sections: r2, sectionIndex: s2, targetZ: t2.z, side: a2 }))
return null;
const h2 = this.reducedHdRoutes[e33], d2 = this.reducedHdRoutes[o2];
if (c2.length === 0)
return null;
const u2 = d2.viaDiameter / 2 + h2.traceThickness / 2 + this.traceMargin + RB, p2 = a2 === "start" ? Math.max(...c2) + u2 : Math.min(...c2) - u2, m2 = this.relocateTransitionVia({ route: d2, section: i2, targetZ: t2.z, side: a2, newViaDistance: p2 });
if (!m2)
return null;
const g2 = this.collapseDetourSection({ route: h2, section: t2, targetZ: n2 });
if (h2.vias.length + d2.vias.length - g2.vias.length - m2.route.vias.length !== 2)
return null;
const f2 = { detourRouteIndex: e33, detourRoute: g2, transitionUpdates: [{ routeIndex: o2, route: m2.route, relocatedVias: [m2.relocatedVia] }] };
return this.candidateIsClear(f2, l2) ? f2 : null;
}
tryCreateMultiCrossingCandidate({ detourRouteIndex: e33, detourSection: t2, targetZ: n2, crossingGroups: o2, sectionsByRoute: i2, baseClearanceIndexes: r2 }) {
if (o2.length < 2)
return null;
const s2 = this.reducedHdRoutes[e33], a2 = [], c2 = new Map;
for (const e34 of o2) {
const t3 = c2.get(e34.transitionRouteIndex) ?? [];
t3.push(e34), c2.set(e34.transitionRouteIndex, t3);
}
for (const [e34, n3] of c2) {
const o3 = this.reducedHdRoutes[e34], r3 = this.relocateTransitionVias({ route: o3, sections: i2[e34], crossingGroups: n3, detourZ: t2.z, detourTraceThickness: s2.traceThickness });
if (!r3)
return null;
a2.push({ routeIndex: e34, route: r3.route, relocatedVias: r3.relocatedVias });
}
const l2 = this.collapseDetourSection({ route: s2, section: t2, targetZ: n2 });
if (s2.vias.length + [...c2.keys()].reduce((e34, t3) => e34 + this.reducedHdRoutes[t3].vias.length, 0) - (l2.vias.length + a2.reduce((e34, { route: t3 }) => e34 + t3.vias.length, 0)) !== 2)
return null;
this.stats.multiCrossingCandidates = (this.stats.multiCrossingCandidates ?? 0) + 1;
const h2 = { detourRouteIndex: e33, detourRoute: l2, transitionUpdates: a2 };
return this.candidateIsClear(h2, r2) ? this.candidateRoutesHaveNoExternalCopperConflicts(h2, r2) ? (this.stats.multiCrossingReductions = (this.stats.multiCrossingReductions ?? 0) + 1, this.stats.transitionRoutesMovedByMultiCrossingReductions = (this.stats.transitionRoutesMovedByMultiCrossingReductions ?? 0) + a2.length, h2) : (this.stats.multiCrossingPreexistingConflictRejections = (this.stats.multiCrossingPreexistingConflictRejections ?? 0) + 1, null) : null;
}
findCrossingReduction() {
const e33 = this.reducedHdRoutes.map((e34) => sB(e34)), t2 = [], n2 = new Set;
for (let o3 = 0;o3 < this.reducedHdRoutes.length; o3++) {
if (this.reducedHdRoutes[o3].jumpers?.length)
continue;
const i3 = e33[o3];
for (let e34 = 1;e34 < i3.length - 1; e34++) {
const r2 = i3[e34 - 1], s2 = i3[e34], a2 = i3[e34 + 1];
r2.z !== a2.z || r2.z === s2.z || $B(s2) || (t2.push({ routeIndex: o3, section: s2, targetZ: r2.z }), n2.add(`${r2.z}:${s2.z}`));
}
}
if (t2.length === 0)
return null;
const o2 = this.buildTransitionSegmentIndex(e33, n2);
if (!o2)
return null;
let i2 = null;
for (const n3 of t2) {
const { routeIndex: t3, section: r2 } = n3, s2 = this.reducedHdRoutes[t3], a2 = this.getIndexedCrossingGroups({ detourRouteIndex: t3, detourSection: r2, targetZ: n3.targetZ, transitionSegmentIndex: o2 }).filter(({ transitionRouteIndex: e34 }) => {
const t4 = this.reducedHdRoutes[e34];
return !t4.jumpers?.length && !LB(s2, t4, this.input.connMap);
}), c2 = new Map;
for (const e34 of a2) {
const t4 = `${e34.transitionRouteIndex}:${e34.transitionSectionIndex}`, n4 = c2.get(t4) ?? [];
n4.push(e34), c2.set(t4, n4);
}
if (c2.size > 1) {
i2 ??= { mutableRoutes: new Uz(this.reducedHdRoutes), immutableRoutes: this.input.otherHdRoutes?.length ? new Uz([...this.input.otherHdRoutes]) : null };
let o3 = [{ groups: [], movement: 0 }];
const a3 = (t4) => {
const n4 = this.reducedHdRoutes[t4.transitionRouteIndex], o4 = e33[t4.transitionRouteIndex][t4.transitionSectionIndex], i3 = n4.viaDiameter / 2 + s2.traceThickness / 2 + this.traceMargin + RB, r3 = t4.side === "start" ? Math.max(...t4.crossingDistances) + i3 : Math.min(...t4.crossingDistances) - i3;
return t4.side === "start" ? r3 : BB(o4.points) - r3;
};
for (const e34 of c2.values()) {
const t4 = e34.map((e35) => ({ group: e35, movement: a3(e35) })).sort((e35, t5) => e35.movement - t5.movement);
o3 = o3.flatMap((e35) => t4.map((t5) => ({ groups: [...e35.groups, t5.group], movement: e35.movement + t5.movement }))).sort((e35, t5) => e35.movement - t5.movement).slice(0, 4);
}
for (const s3 of o3) {
const o4 = this.tryCreateMultiCrossingCandidate({ detourRouteIndex: t3, detourSection: r2, targetZ: n3.targetZ, crossingGroups: s3.groups, sectionsByRoute: e33, baseClearanceIndexes: i2 });
if (o4)
return o4;
}
continue;
}
const l2 = c2.values().next().value ?? [];
for (const o3 of l2) {
const s3 = o3.transitionRouteIndex, a3 = e33[s3], c3 = a3[o3.transitionSectionIndex];
i2 ??= { mutableRoutes: new Uz(this.reducedHdRoutes), immutableRoutes: this.input.otherHdRoutes?.length ? new Uz([...this.input.otherHdRoutes]) : null };
const l3 = this.tryCreateCandidate({ detourRouteIndex: t3, detourSection: r2, targetZ: n3.targetZ, transitionRouteIndex: s3, transitionSection: c3, transitionSections: a3, transitionSectionIndex: o3.transitionSectionIndex, side: o3.side, crossingDistances: o3.crossingDistances, baseClearanceIndexes: i2 });
if (l3)
return l3;
}
}
return null;
}
_step() {
const e33 = this.findCrossingReduction();
if (e33) {
this.reducedHdRoutes[e33.detourRouteIndex] = e33.detourRoute;
for (const t2 of e33.transitionUpdates)
this.reducedHdRoutes[t2.routeIndex] = t2.route;
this.stats.crossingViaReductions = (this.stats.crossingViaReductions ?? 0) + 1, this.stats.viasRemovedByCrossingReductions = (this.stats.viasRemovedByCrossingReductions ?? 0) + 2;
} else
this.solved = true;
}
getReducedHdRoutes() {
return this.reducedHdRoutes;
}
visualize() {
const e33 = { lines: [], circles: [], rects: [], coordinateSystem: "cartesian", title: "Crossing Via Reduction Solver" };
for (const t2 of this.input.obstacles)
e33.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: "rgba(128, 128, 128, 0.2)" });
for (const t2 of this.reducedHdRoutes) {
for (let n2 = 1;n2 < t2.route.length; n2++) {
const o2 = t2.route[n2 - 1], i2 = t2.route[n2];
o2.z === i2.z && e33.lines.push({ points: [o2, i2], strokeColor: o2.z === 0 ? "#d32f2f" : "#3367a8", strokeWidth: t2.traceThickness, label: `${t2.connectionName} (z=${o2.z})` });
}
for (const n2 of t2.vias)
e33.circles.push({ center: n2, radius: t2.viaDiameter / 2, fill: "#ff20d6", label: `${t2.connectionName} via` });
}
return e33;
}
};
var HB = 0.000001;
var GB = (e33, t2) => Math.abs(e33.x - t2.center.x) <= t2.width / 2 + HB && Math.abs(e33.y - t2.center.y) <= t2.height / 2 + HB;
var UB = (e33) => (e33.__zLayers?.length ?? e33.layers?.length ?? 0) > 1;
var ZB = class extends Fz {
constructor(e33) {
if (super(), this.simplificationConfig = e33, this.simplificationConfig = { ...e33, obstacles: fB(e33.obstacles, e33.layerCount) }, this.hdRoutes = this.markThroughObstacleSegments(e33.hdRoutes), e33.preserveRouteEndpoints) {
const t2 = new Map;
for (const n2 of e33.hdRoutes) {
const e34 = n2.route[0], o2 = n2.route.at(-1);
if (!e34 || !o2)
throw new Error(`TraceSimplificationSolver cannot preserve endpoints for empty route "${n2.connectionName}"`);
if (t2.has(n2.connectionName))
throw new Error(`TraceSimplificationSolver cannot preserve endpoints for duplicate route "${n2.connectionName}"`);
t2.set(n2.connectionName, { start: { ...e34 }, end: { ...o2 } });
}
this.preservedRouteEndpoints = t2;
}
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(e33) {
if (!this.preservedRouteEndpoints)
return;
if (e33.length !== this.preservedRouteEndpoints.size)
throw new Error(`TraceSimplificationSolver changed the preserved route set (expected ${this.preservedRouteEndpoints.size}, got ${e33.length})`);
const t2 = new Set, n2 = (e34, t3) => Math.abs(e34.x - t3.x) <= HB && Math.abs(e34.y - t3.y) <= HB && e34.z === t3.z;
for (const o2 of e33) {
if (t2.has(o2.connectionName))
throw new Error(`TraceSimplificationSolver produced duplicate preserved route "${o2.connectionName}"`);
t2.add(o2.connectionName);
const e34 = this.preservedRouteEndpoints.get(o2.connectionName), i2 = o2.route[0], r2 = o2.route.at(-1);
if (!(e34 && i2 && r2 && n2(i2, e34.start) && n2(r2, e34.end)))
throw new Error(`TraceSimplificationSolver changed a preserved endpoint for route "${o2.connectionName}"`);
}
}
isSameNetObstacle(e33, t2) {
return t2.connectedTo.some((t3) => t3 === e33.connectionName || t3 === e33.rootConnectionName || this.simplificationConfig.connMap.areIdsConnected(e33.connectionName, t3) || e33.rootConnectionName !== undefined && this.simplificationConfig.connMap.areIdsConnected(e33.rootConnectionName, t3));
}
getSameNetObstacleForSegment(e33, t2, n2) {
return this.simplificationConfig.obstacles.find((o2) => UB(o2) && this.isSameNetObstacle(e33, o2) && GB(t2, o2) && GB(n2, o2));
}
isViaInsideSameNetObstacle(e33, t2) {
return this.simplificationConfig.obstacles.some((n2) => UB(n2) && this.isSameNetObstacle(e33, n2) && GB(t2, n2));
}
markThroughObstacleSegments(e33) {
return e33.map((e34) => ({ ...e34, route: e34.route.map((t2, n2, o2) => {
const i2 = o2[n2 + 1], r2 = i2 && t2.z !== i2.z && this.getSameNetObstacleForSegment(e34, t2, i2);
if (r2)
return { ...t2, toNextSegmentType: "through_obstacle", ...r2.circuitJsonMetadata ? { toNextSegmentCircuitJsonMetadata: r2.circuitJsonMetadata } : {} };
const s2 = { ...t2 };
return delete s2.toNextSegmentType, delete s2.toNextSegmentCircuitJsonMetadata, s2;
}), vias: e34.vias.filter((t2) => !this.isViaInsideSameNetObstacle(e34, t2)) }));
}
_step() {
if (this.simplificationPipelineLoops >= this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)
this.solved = true;
else {
if (this.activeSubSolver) {
if (this.activeSubSolver.step(), !this.activeSubSolver.failed && !this.activeSubSolver.solved)
return;
if (this.activeSubSolver.solved) {
if (this.extractResult) {
const e33 = this.extractResult(this.activeSubSolver);
this.validatePreservedRouteEndpoints(e33), this.hdRoutes = this.markThroughObstacleSegments(e33);
}
if (this.activeSubSolver = null, this.extractResult = null, this.currentPhase === "via_removal" ? this.currentPhase = this.simplificationConfig.enableCrossingViaReduction ? "crossing_via_reduction" : "via_merging" : this.currentPhase === "crossing_via_reduction" ? this.currentPhase = "via_merging" : this.currentPhase === "via_merging" ? this.currentPhase = "path_simplification" : (this.currentPhase = "via_removal", this.simplificationPipelineLoops++), this.simplificationPipelineLoops >= this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)
return void (this.solved = true);
} else if (this.activeSubSolver.failed)
return this.failed = true, 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 _B({ 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] : undefined, geometryShortcutTraceMargin: 0.1, geometryShortcutObstacleMargin: this.simplificationConfig.minTraceToPadEdgeClearance ?? 0.15, enableGeometryShortcuts: this.simplificationPipelineLoops > 0, enableObstacleDetourShortcuts: this.simplificationConfig.enableCrossingViaReduction === true && this.simplificationPipelineLoops > 0, preserveRouteEndpoints: this.simplificationConfig.preserveRouteEndpoints, terminalLayerIndicesByPcbPortId: this.simplificationConfig.terminalLayerIndicesByPcbPortId }), this.extractResult = (e33) => e33.getOptimizedHdRoutes() ?? [];
break;
case "crossing_via_reduction":
this.activeSubSolver = new VB({ 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] : undefined, traceMargin: 0.1, obstacleMargin: this.simplificationConfig.minTraceToPadEdgeClearance ?? 0.15 }), this.extractResult = (e33) => e33.getReducedHdRoutes();
break;
case "via_merging":
this.activeSubSolver = new NB({ 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] : undefined, preserveRouteEndpoints: this.simplificationConfig.preserveRouteEndpoints }), this.extractResult = (e33) => e33.getMergedViaHdRoutes() ?? [];
break;
case "path_simplification":
this.activeSubSolver = new SB({ 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] : undefined, minBoardEdgeClearance: this.simplificationConfig.minBoardEdgeClearance, defaultViaDiameter: this.simplificationConfig.defaultViaDiameter, useTraceWidthAwareClearance: this.simplificationConfig.useTraceWidthAwareClearance, enableVertexShortcuts: this.simplificationConfig.enableVertexShortcuts }), this.extractResult = (e33) => e33.simplifiedHdRoutes;
break;
default:
this.failed = true, this.error = `Unknown phase: ${this.currentPhase}`;
}
}
}
visualize() {
if (this.activeSubSolver)
return this.activeSubSolver.visualize();
const e33 = { lines: [], points: [], rects: [], circles: [], coordinateSystem: "cartesian", title: "Trace Simplification Solver" };
for (const t2 of this.simplificationConfig.obstacles) {
let n2 = "rgba(128, 128, 128, 0.2)";
const o2 = t2.__zLayers?.includes(0), i2 = t2.__zLayers?.includes(1);
o2 && i2 ? n2 = "rgba(128, 0, 128, 0.2)" : o2 ? n2 = "rgba(255, 0, 0, 0.2)" : i2 && (n2 = "rgba(0, 0, 255, 0.2)"), e33.rects.push({ center: t2.center, width: t2.width, height: t2.height, fill: n2, label: `Obstacle (Z: ${t2.__zLayers?.join(", ")})` });
}
for (const t2 of this.simplificationConfig.otherHdRoutes ?? []) {
for (let n2 = 0;n2 < t2.route.length - 1; n2++) {
const o2 = t2.route[n2], i2 = t2.route[n2 + 1];
o2.z === i2.z && e33.lines.push({ points: [{ x: o2.x, y: o2.y }, { x: i2.x, y: i2.y }], strokeColor: o2.z === 0 ? "rgba(160, 32, 32, 0.55)" : "rgba(32, 32, 160, 0.55)", strokeWidth: t2.traceThickness, strokeDash: [0.08, 0.08], label: `${t2.connectionName} immutable (z=${o2.z})` });
}
for (const n2 of t2.vias)
e33.circles.push({ center: { x: n2.x, y: n2.y }, radius: t2.viaDiameter / 2, fill: "rgba(96, 96, 96, 0.45)", label: `${t2.connectionName} immutable via` });
}
for (const t2 of this.hdRoutes)
if (t2.route.length !== 0) {
for (let n2 = 0;n2 < t2.route.length - 1; n2++) {
const o2 = t2.route[n2], i2 = t2.route[n2 + 1];
o2.z === i2.z && e33.lines.push({ points: [{ x: o2.x, y: o2.y }, { x: i2.x, y: i2.y }], strokeColor: o2.z === 0 ? "red" : "blue", strokeWidth: t2.traceThickness, label: `${t2.connectionName} (z=${o2.z})` });
}
for (const n2 of t2.vias)
e33.circles.push({ center: { x: n2.x, y: n2.y }, radius: t2.viaDiameter / 2, fill: "rgba(255, 0, 255, 0.5)", label: `${t2.connectionName} via` });
if (t2.jumpers && t2.jumpers.length > 0) {
const n2 = pB(t2.jumpers, { color: "orange", label: t2.connectionName });
e33.rects.push(...n2.rects ?? []), e33.lines.push(...n2.lines ?? []);
}
}
return e33;
}
};
var qB = class {
tree;
constructor(e33 = 9) {
this.tree = new tt(e33);
}
insert(e33, t2, n2, o2, i2) {
this.tree.insert({ minX: t2, minY: n2, maxX: o2, maxY: i2, data: e33 });
}
bulkLoad(e33) {
const t2 = e33.map(({ item: e34, minX: t3, minY: n2, maxX: o2, maxY: i2 }) => ({ minX: t3, minY: n2, maxX: o2, maxY: i2, data: e34 }));
this.tree.load(t2);
}
search(e33, t2, n2, o2) {
return this.tree.search({ minX: e33, minY: t2, maxX: n2, maxY: o2 }).map((e34) => e34.data);
}
clear() {
this.tree.clear();
}
};
var JB = class {
index;
items = [];
currentIndex = 0;
capacity;
constructor(e33) {
this.capacity = Math.max(1, e33), this.index = new je(this.capacity);
}
insert(e33, t2, n2, o2, i2) {
if (this.currentIndex >= this.index.numItems)
throw new Error("Exceeded initial capacity");
this.items[this.currentIndex] = e33, this.index.add(t2, n2, o2, i2), this.currentIndex++;
}
finish() {
this.index.finish();
}
search(e33, t2, n2, o2) {
return this.index.search(e33, t2, n2, o2).map((e34) => this.items[e34] || null).filter(Boolean);
}
clear() {
this.items = [], this.currentIndex = 0, this.index = new je(this.capacity);
}
};
var QB = class {
idx;
storage = [];
constructor(e33 = "native", t2 = []) {
e33 === "flatbush" ? t2.length === 0 ? (this.idx = new qB, e33 = "rbush") : this.idx = new JB(t2.length) : this.idx = e33 === "rbush" ? new qB : new class {
shi = new KB(t2);
insert(e34) {}
search(e34, t3, n2, o2) {
const i2 = (e34 + n2) / 2, r2 = (t3 + o2) / 2, s2 = n2 - e34, a2 = o2 - t3;
return this.shi.getNodesInArea(i2, r2, s2, a2);
}
clear() {}
}, t2.forEach((e34) => this.insert(e34)), e33 === "flatbush" && t2.length > 0 && this.idx.finish?.();
}
insert(e33) {
this.storage.push(e33), this.idx.insert(e33, e33.center.x - e33.width / 2, e33.center.y - e33.height / 2, e33.center.x + e33.width / 2, e33.center.y + e33.height / 2);
}
search(e33) {
return this.idx.search(e33.minX, e33.minY, e33.maxX, e33.maxY);
}
searchArea(e33, t2, n2, o2) {
return this.search({ minX: e33 - n2 / 2, minY: t2 - o2 / 2, maxX: e33 + n2 / 2, maxY: t2 + o2 / 2 });
}
};
var KB = class {
constructor(e33) {
this.obstacles = e33, this.buckets = new Map;
for (let t2 = 0;t2 < e33.length; t2++) {
const n2 = e33[t2], o2 = n2.center.x - n2.width / 2, i2 = n2.center.y - n2.height / 2, r2 = n2.center.x + n2.width / 2, s2 = n2.center.y + n2.height / 2;
for (let e34 = o2;e34 <= r2; e34 += this.CELL_SIZE)
for (let o3 = i2;o3 <= s2; o3 += this.CELL_SIZE) {
const i3 = this.getBucketKey(e34, o3), r3 = this.buckets.get(i3);
r3 ? r3.push([n2, t2]) : this.buckets.set(i3, [[n2, t2]]);
}
}
}
obstacles;
buckets;
CELL_SIZE = 0.4;
getBucketKey(e33, t2) {
return `${Math.floor(e33 / this.CELL_SIZE)}x${Math.floor(t2 / this.CELL_SIZE)}`;
}
getNodesInArea(e33, t2, n2, o2) {
const i2 = [], r2 = new Set, s2 = t2 - o2 / 2, a2 = e33 + n2 / 2, c2 = t2 + o2 / 2;
for (let t3 = e33 - n2 / 2;t3 <= a2; t3 += this.CELL_SIZE)
for (let e34 = s2;e34 <= c2; e34 += this.CELL_SIZE) {
const n3 = this.getBucketKey(t3, e34), o3 = this.buckets.get(n3) || [];
for (const e35 of o3)
r2.has(e35[1]) || (r2.add(e35[1]), i2.push(e35[0]));
}
return i2;
}
};
var eF = 0.000000001;
var tF = class extends ai {
getSolverName() {
return "TraceWidthSolver";
}
hdRoutes;
hdRoutesWithWidths = [];
nominalTraceWidth;
minTraceWidth;
obstacleMargin;
minTraceToHoleEdgeClearance;
TRACE_WIDTH_SCHEDULE;
connectionNominalTraceWidthMap;
unprocessedRoutes = [];
processedRoutes = [];
currentTrace = null;
cursorPosition = null;
currentTraceSegmentIndex = 0;
currentTraceSegmentT = 0;
currentScheduleIndex = 0;
currentTargetWidth = 0;
hasInsufficientClearance = false;
lastCollidingObstacles = [];
lastCollidingRoutes = [];
lastClearance = 1 / 0;
obstacles = [];
obstacleSHI;
hdRouteSHI;
connMap;
colorMap;
constructor(e33) {
super(), this.MAX_ITERATIONS = 1e6, this.hdRoutes = [...e33.hdRoutes], this.minTraceWidth = e33.minTraceWidth, this.obstacleMargin = e33.obstacleMargin ?? 0.15, this.minTraceToHoleEdgeClearance = e33.minTraceToHoleEdgeClearance, this.nominalTraceWidth = 0, this.TRACE_WIDTH_SCHEDULE = [], this.unprocessedRoutes = [...this.hdRoutes], this.connMap = e33.connMap, this.colorMap = e33.colorMap;
const t2 = e33.layerCount;
this.obstacles = Ns(e33.obstacles ?? [], t2), this.connectionNominalTraceWidthMap = new Map;
for (const t3 of e33.connection)
t3.nominalTraceWidth !== undefined && this.connectionNominalTraceWidthMap.set(t3.name, t3.nominalTraceWidth);
this.obstacles.length > 0 && (this.obstacleSHI = new QB("flatbush", this.obstacles)), this.hdRouteSHI = new dr(this.hdRoutes);
}
getNominalTraceWidthForRoute(e33) {
const t2 = this.connectionNominalTraceWidthMap.get(e33.connectionName);
return t2 !== undefined ? t2 : e33.rootConnectionName ? this.connectionNominalTraceWidthMap.get(e33.rootConnectionName) : undefined;
}
_step() {
if (!this.currentTrace) {
const e34 = this.unprocessedRoutes.shift();
if (!e34)
return this.hdRoutesWithWidths = this.processedRoutes, void (this.solved = true);
const t2 = this.getNominalTraceWidthForRoute(e34);
if (t2 === undefined) {
const t3 = e34.traceThickness ?? this.minTraceWidth;
return this.processedRoutes.push(this.createRouteWithWidth(e34, t3)), void (this.currentTrace = null);
}
this.currentTrace = e34, this.nominalTraceWidth = t2;
const n2 = (this.nominalTraceWidth + this.minTraceWidth) / 2;
return this.TRACE_WIDTH_SCHEDULE = [this.nominalTraceWidth, n2], 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());
}
const e33 = this.stepCursorForward();
(e33 ? this.getClearanceForSegment(this.cursorPosition, this.cursorPosition) : this.getMinimumRouteClearance()) < this.currentTargetWidth / 2 + this.obstacleMargin ? (this.hasInsufficientClearance = true, this.currentScheduleIndex++, this.currentScheduleIndex < this.TRACE_WIDTH_SCHEDULE.length ? (this.currentTargetWidth = this.TRACE_WIDTH_SCHEDULE[this.currentScheduleIndex], this.initializeCursor()) : this.finalizeCurrentTrace(this.minTraceWidth)) : e33 || this.finalizeCurrentTrace(this.currentTargetWidth);
}
initializeCursor() {
if (!this.currentTrace)
return;
const e33 = this.currentTrace.route[0];
this.cursorPosition = { ...e33 }, this.currentTraceSegmentIndex = 0, this.currentTraceSegmentT = 0, this.hasInsufficientClearance = false;
}
stepCursorForward() {
if (!this.currentTrace || !this.cursorPosition)
return false;
const e33 = this.currentTrace.route;
let t2 = 0.1;
for (;t2 > 0; ) {
if (this.currentTraceSegmentIndex >= e33.length - 1)
return false;
const n2 = e33[this.currentTraceSegmentIndex], o2 = e33[this.currentTraceSegmentIndex + 1];
if (n2.insideJumperPad && o2.insideJumperPad) {
this.currentTraceSegmentIndex++, this.currentTraceSegmentT = 0;
continue;
}
const i2 = o2.x - n2.x, r2 = o2.y - n2.y, s2 = Math.sqrt(i2 * i2 + r2 * r2);
if (s2 === 0) {
this.currentTraceSegmentIndex++, this.currentTraceSegmentT = 0;
continue;
}
const a2 = this.currentTraceSegmentT * s2, c2 = s2 - a2;
if (t2 <= c2) {
const e34 = a2 + t2;
return this.currentTraceSegmentT = e34 / s2, this.cursorPosition = { x: n2.x + i2 * this.currentTraceSegmentT, y: n2.y + r2 * this.currentTraceSegmentT, z: n2.z }, true;
}
if (t2 -= c2, this.currentTraceSegmentIndex++, this.currentTraceSegmentT = 0, this.currentTraceSegmentIndex >= e33.length - 1) {
const t3 = e33[e33.length - 1];
return this.cursorPosition = { ...t3 }, false;
}
}
return true;
}
isObstacleOwnJumperPad(e33) {
if (!this.currentTrace?.jumpers)
return false;
for (const t2 of this.currentTrace.jumpers) {
const n2 = Math.sqrt((e33.center.x - t2.start.x) ** 2 + (e33.center.y - t2.start.y) ** 2), o2 = Math.sqrt((e33.center.x - t2.end.x) ** 2 + (e33.center.y - t2.end.y) ** 2), i2 = Math.max(e33.width, e33.height) / 2 + 0.01;
if (n2 < i2 || o2 < i2)
return true;
}
return false;
}
getMinimumRouteClearance() {
if (!this.currentTrace)
return 1 / 0;
let e33 = 1 / 0;
const t2 = this.currentTrace.route;
for (let n2 = 0;n2 < t2.length - 1; n2++) {
const o2 = t2[n2], i2 = t2[n2 + 1];
o2.z === i2.z && (o2.insideJumperPad && i2.insideJumperPad || o2.toNextSegmentType !== "through_obstacle" && (e33 = Math.min(e33, this.getClearanceForSegment(o2, i2))));
}
return e33;
}
getClearanceForSegment(e33, t2) {
if (!this.currentTrace)
return 1 / 0;
const n2 = this.currentTrace.rootConnectionName ?? this.currentTrace.connectionName, o2 = this.currentTargetWidth / 2 + this.obstacleMargin;
let i2 = 1 / 0;
this.lastCollidingObstacles = [], this.lastCollidingRoutes = [];
const r2 = this.currentTargetWidth / 2 + Math.max(this.obstacleMargin, this.minTraceToHoleEdgeClearance ?? 0), s2 = new Set(this.obstacleSHI?.search({ minX: Math.min(e33.x, t2.x) - r2, minY: Math.min(e33.y, t2.y) - r2, maxX: Math.max(e33.x, t2.x) + r2, maxY: Math.max(e33.y, t2.y) + r2 }));
for (const e34 of this.obstacles)
e34.ccwRotationDegrees && s2.add(e34);
for (const r3 of s2) {
if (!this.isObstacleOnPointLayer(r3, e33))
continue;
if (vo(r3, this.currentTrace, this.connMap))
continue;
if (r3.obstacleId && this.connMap?.areIdsConnected(n2, r3.obstacleId))
continue;
if (this.isObstacleOwnJumperPad(r3))
continue;
const s3 = -(r3.ccwRotationDegrees ?? 0) * Math.PI / 180, a3 = Math.cos(s3), c2 = Math.sin(s3), l2 = { x: (e33.x - r3.center.x) * a3 - (e33.y - r3.center.y) * c2, y: (e33.x - r3.center.x) * c2 + (e33.y - r3.center.y) * a3 }, h2 = { x: (t2.x - r3.center.x) * a3 - (t2.y - r3.center.y) * c2, y: (t2.x - r3.center.x) * c2 + (t2.y - r3.center.y) * a3 }, d2 = (r3.isNonPlatedHole && r3.shape === "circle" ? zt(e33, t2, { ...r3.center, radius: r3.width / 2 }) : Lt(l2, h2, { center: { x: 0, y: 0 }, width: r3.width, height: r3.height })) - ((r3.isNonPlatedHole ? this.minTraceToHoleEdgeClearance ?? this.obstacleMargin : this.obstacleMargin) - this.obstacleMargin);
i2 = Math.min(i2, d2), d2 < o2 && this.lastCollidingObstacles.push(r3);
}
const a2 = this.hdRouteSHI.getConflictingRoutesForSegment(e33, t2, o2);
for (const { conflictingRoute: r3 } of a2) {
const s3 = r3, a3 = s3.rootConnectionName ?? s3.connectionName;
if (a3 === n2)
continue;
if (this.connMap?.areIdsConnected(n2, a3))
continue;
let c2 = 1 / 0;
for (let n3 = 0;n3 < s3.route.length - 1; n3++) {
const o3 = s3.route[n3], i3 = s3.route[n3 + 1];
o3.z === i3.z && o3.z === e33.z && (o3.insideJumperPad && i3.insideJumperPad || o3.toNextSegmentType !== "through_obstacle" && (c2 = Math.min(c2, kt(e33, t2, o3, i3) - (o3.traceThickness ?? s3.traceThickness) / 2)));
}
for (const n3 of s3.vias)
c2 = Math.min(c2, zt(e33, t2, { ...n3, radius: s3.viaDiameter / 2 }));
i2 = Math.min(i2, c2), c2 < o2 && this.lastCollidingRoutes.push(s3);
}
return this.lastClearance = i2, i2;
}
isObstacleOnPointLayer(e33, t2) {
return !e33.__zLayers || e33.__zLayers.includes(t2.z);
}
getAdjacentNonCoincidentRoutePoint(e33, t2) {
const n2 = e33.route[t2];
if (!n2)
return;
const o2 = t2 === 0 ? 1 : -1;
for (let i2 = t2 + o2;i2 >= 0 && i2 < e33.route.length; i2 += o2) {
const t3 = e33.route[i2];
if (vt(t3, n2) > eF)
return t3;
}
}
getObstacleWidthAlongVector(e33, t2) {
const n2 = (e33.ccwRotationDegrees ?? 0) * Math.PI / 180, o2 = Math.cos(n2), i2 = Math.sin(n2), r2 = o2, s2 = i2, a2 = -i2, c2 = o2;
return Math.abs(t2.x * r2 + t2.y * s2) * e33.width + Math.abs(t2.x * a2 + t2.y * c2) * e33.height;
}
getTerminalPadWidthLimit(e33, t2, n2) {
const o2 = e33.route[t2];
if (!o2)
return;
const i2 = this.getAdjacentNonCoincidentRoutePoint(e33, t2);
if (!i2)
return;
const r2 = t2 === 0 ? Ft(o2, i2) : Ft(i2, o2);
if (vt(r2, { x: 0, y: 0 }) <= eF)
return;
const s2 = { x: -r2.y, y: r2.x };
let a2;
for (const t3 of this.obstacles) {
if (!this.isObstacleOnPointLayer(t3, o2))
continue;
if (!vo(t3, e33, this.connMap))
continue;
if (jt(o2, t3) > eF)
continue;
const n3 = this.getObstacleWidthAlongVector(t3, s2);
if (n3 <= eF)
continue;
const i3 = this.getObstacleWidthAlongVector(t3, r2) / 2;
(!a2 || n3 < a2.width || Math.abs(n3 - a2.width) <= eF && i3 > a2.neckDistance) && (a2 = { width: n3, neckDistance: i3 });
}
return !a2 || a2.width >= n2 - eF ? undefined : a2;
}
getRouteDistanceInfo(e33) {
const t2 = [0];
let n2 = 0;
for (let o2 = 1;o2 < e33.length; o2++) {
const i2 = e33[o2 - 1];
n2 += vt(e33[o2], i2), t2.push(n2);
}
return { distances: t2, totalDistance: n2 };
}
interpolateRoutePointAtDistance(e33, t2, n2) {
for (let o2 = 1;o2 < e33.length; o2++) {
const i2 = t2[o2 - 1], r2 = t2[o2], s2 = r2 - i2;
if (n2 > r2 + eF)
continue;
const a2 = e33[o2 - 1], c2 = e33[o2];
if (s2 <= eF)
return { ...c2 };
const l2 = Math.max(0, Math.min(1, (n2 - i2) / s2));
return { x: a2.x + (c2.x - a2.x) * l2, y: a2.y + (c2.y - a2.y) * l2, z: a2.z };
}
return { ...e33[e33.length - 1] };
}
getTaperWidthAtDistance({ distanceFromStart: e33, totalDistance: t2, startLimit: n2, endLimit: o2, taperDistance: i2, traceWidth: r2 }) {
let s2 = r2;
if (n2 !== undefined && e33 <= i2) {
const t3 = Math.min(n2.neckDistance, i2);
if (e33 <= t3)
s2 = Math.min(s2, n2.width);
else {
const o3 = (e33 - t3) / Math.max(i2 - t3, eF);
s2 = Math.min(s2, n2.width + (r2 - n2.width) * o3);
}
}
if (o2 !== undefined) {
const n3 = t2 - e33;
if (n3 <= i2) {
const e34 = Math.min(o2.neckDistance, i2);
if (n3 <= e34)
s2 = Math.min(s2, o2.width);
else {
const t3 = (n3 - e34) / Math.max(i2 - e34, eF);
s2 = Math.min(s2, o2.width + (r2 - o2.width) * t3);
}
}
}
return s2;
}
createTerminalTaperedRoute(e33, t2) {
if (e33.route.length < 2)
return e33.route.map((e34) => ({ ...e34, traceThickness: e34.traceThickness ?? t2 }));
const n2 = this.getTerminalPadWidthLimit(e33, 0, t2), o2 = this.getTerminalPadWidthLimit(e33, e33.route.length - 1, t2), { distances: i2, totalDistance: r2 } = this.getRouteDistanceInfo(e33.route);
if (r2 <= eF) {
const i3 = Math.min(n2?.width ?? t2, o2?.width ?? t2);
return e33.route.map((e34) => ({ ...e34, traceThickness: i3 }));
}
const s2 = Math.min(Math.max(2 * t2, 0.75), r2 / 2), a2 = i2.map((e34, t3) => ({ distanceFromStart: e34, originalPointIndex: t3 })), c2 = [];
if (n2 !== undefined) {
c2.push(n2.neckDistance);
for (let e34 = 0;e34 <= 8; e34++)
c2.push(s2 * e34 / 8);
}
if (o2 !== undefined) {
c2.push(r2 - o2.neckDistance);
for (let e34 = 0;e34 <= 8; e34++)
c2.push(r2 - s2 + s2 * e34 / 8);
}
for (const e34 of c2) {
const t3 = Math.max(0, Math.min(r2, e34));
a2.some((e35) => Math.abs(e35.distanceFromStart - t3) <= eF) || a2.push({ distanceFromStart: t3 });
}
return a2.sort((e34, t3) => {
const n3 = e34.distanceFromStart - t3.distanceFromStart;
return Math.abs(n3) > eF ? n3 : (e34.originalPointIndex ?? 1 / 0) - (t3.originalPointIndex ?? 1 / 0);
}), a2.map((a3) => {
const { distanceFromStart: c3 } = a3, l2 = a3.originalPointIndex !== undefined ? { ...e33.route[a3.originalPointIndex] } : this.interpolateRoutePointAtDistance(e33.route, i2, c3);
return l2.traceThickness = this.getTaperWidthAtDistance({ distanceFromStart: c3, totalDistance: r2, startLimit: n2, endLimit: o2, taperDistance: s2, traceWidth: t2 }), l2;
});
}
createRouteWithWidth(e33, t2) {
return { connectionName: e33.connectionName, rootConnectionName: e33.rootConnectionName, traceThickness: t2, viaDiameter: e33.viaDiameter, route: this.createTerminalTaperedRoute(e33, t2), vias: [...e33.vias], jumpers: e33.jumpers };
}
finalizeCurrentTrace(e33) {
if (!this.currentTrace)
return;
const t2 = this.createRouteWithWidth(this.currentTrace, e33);
this.processedRoutes.push(t2), this.hdRouteSHI.removeRoute(t2.connectionName), this.hdRouteSHI.addRoute(t2), this.currentTrace = null, this.cursorPosition = null, this.hasInsufficientClearance = false;
}
visualize() {
const e33 = { lines: [], points: [], circles: [], rects: [], coordinateSystem: "cartesian", title: `Trace Width Solver (schedule: [${this.TRACE_WIDTH_SCHEDULE.map((e34) => e34.toFixed(2)).join(", ")}]mm, fallback: ${this.minTraceWidth.toFixed(2)}mm, margin: ${this.obstacleMargin.toFixed(2)}mm)` }, t2 = new Set(this.lastCollidingObstacles.map((e34) => e34.obstacleId)), n2 = new Set(this.lastCollidingRoutes.map((e34) => e34.connectionName));
for (const n3 of this.obstacles) {
const o2 = t2.has(n3.obstacleId), i2 = n3.__zLayers?.includes(0), r2 = n3.__zLayers?.includes(1);
let s2;
s2 = o2 ? "rgba(255, 0, 0, 0.6)" : i2 && r2 ? "rgba(128, 0, 128, 0.15)" : i2 ? "rgba(255, 0, 0, 0.15)" : r2 ? "rgba(0, 0, 255, 0.15)" : "rgba(128, 128, 128, 0.15)", e33.rects.push({ center: n3.center, width: n3.width, height: n3.height, fill: s2, stroke: o2 ? "red" : undefined, label: o2 ? `COLLIDING: ${n3.obstacleId ?? "obstacle"}` : `${n3.obstacleId ?? "obstacle"} (Z: ${n3.__zLayers?.join(", ")})` });
}
for (const t3 of this.processedRoutes) {
if (t3.route.length === 0)
continue;
const n3 = t3.traceThickness === this.nominalTraceWidth, o2 = t3.traceThickness === this.TRACE_WIDTH_SCHEDULE[1], i2 = n3 ? "green" : o2 ? "yellow" : "orange";
for (let n4 = 0;n4 < t3.route.length - 1; n4++) {
const o3 = t3.route[n4], r2 = t3.route[n4 + 1];
o3.insideJumperPad && r2.insideJumperPad || o3.z === r2.z && e33.lines.push({ points: [{ x: o3.x, y: o3.y }, { x: r2.x, y: r2.y }], strokeColor: i2, strokeWidth: o3.traceThickness ?? t3.traceThickness, label: `${t3.connectionName} (w=${(o3.traceThickness ?? t3.traceThickness).toFixed(2)})` });
}
for (const n4 of t3.vias)
e33.circles.push({ center: { x: n4.x, y: n4.y }, radius: t3.viaDiameter / 2, fill: "rgba(255, 0, 255, 0.5)", label: `${t3.connectionName} via` });
if (t3.jumpers && t3.jumpers.length > 0) {
const n4 = Az(t3.jumpers, { color: i2, label: t3.connectionName });
e33.rects.push(...n4.rects ?? []), e33.lines.push(...n4.lines ?? []);
}
}
if (this.currentTrace) {
for (let t3 = 0;t3 < this.currentTrace.route.length - 1; t3++) {
const n3 = this.currentTrace.route[t3], o2 = this.currentTrace.route[t3 + 1];
n3.insideJumperPad && o2.insideJumperPad || n3.z === o2.z && e33.lines.push({ points: [{ x: n3.x, y: n3.y }, { x: o2.x, y: o2.y }], strokeColor: "cyan", strokeWidth: this.currentTrace.traceThickness ?? this.minTraceWidth, label: `Processing: ${this.currentTrace.connectionName}` });
}
this.cursorPosition && (e33.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)` }), e33.points.push({ x: this.cursorPosition.x, y: this.cursorPosition.y, color: "orange", label: "Cursor" }));
}
for (const t3 of this.unprocessedRoutes) {
if (t3.route.length === 0)
continue;
const o2 = n2.has(t3.connectionName);
for (let n3 = 0;n3 < t3.route.length - 1; n3++) {
const i2 = t3.route[n3], r2 = t3.route[n3 + 1];
i2.z === r2.z && e33.lines.push({ points: [{ x: i2.x, y: i2.y }, { x: r2.x, y: r2.y }], strokeColor: o2 ? "rgba(255, 0, 0, 0.8)" : "rgba(128, 128, 128, 0.3)", strokeWidth: t3.traceThickness ?? this.minTraceWidth, label: o2 ? `COLLIDING: ${t3.connectionName}` : t3.connectionName });
}
}
return e33;
}
getHdRoutesWithWidths() {
return this.hdRoutesWithWidths;
}
};
var mF = (e33, t2 = {}) => {
const n2 = Math.min(...e33.availableZ);
return { center: !t2.rectMargin || t2.zOffset ? { x: e33.center.x + n2 * e33.width * (t2.zOffset ?? 0.05), y: e33.center.y - n2 * e33.width * (t2.zOffset ?? 0.05) } : e33.center, width: t2.rectMargin ? e33.width - 2 * t2.rectMargin : Math.max(e33.width - 0.5, 0.8 * e33.width), height: t2.rectMargin ? e33.height - 2 * t2.rectMargin : Math.max(e33.height - 0.5, 0.8 * e33.height), fill: e33._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)" }[e33.availableZ.join(",")] ?? "rgba(0,200,200,0.1)", layer: `z${e33.availableZ.join(",")}`, label: [e33.capacityMeshNodeId, `availableZ: ${e33.availableZ.join(",")}`, "" + (e33._containsTarget ? "containsTarget" : ""), "" + (e33._containsObstacle ? "containsObstacle" : "")].filter(Boolean).join(`
`) };
};
ro();
function nj(e33) {
const t2 = e33.width / 2, n2 = e33.height / 2, o2 = e33.center.x, i2 = e33.center.y, r2 = { x: o2 - t2, y: i2 + n2 }, s2 = { x: o2 + t2, y: i2 + n2 }, a2 = { x: o2 - t2, y: i2 - n2 }, c2 = { x: o2 + t2, y: i2 - n2 };
return [{ start: r2, end: s2 }, { start: s2, end: c2 }, { start: c2, end: a2 }, { start: a2, end: r2 }];
}
var Pj = Object.create;
var Mj = Object.defineProperty;
var wj = Object.getOwnPropertyDescriptor;
var Nj = Object.getOwnPropertyNames;
var Tj = Object.getPrototypeOf;
var Rj = Object.prototype.hasOwnProperty;
var Ej = (e33, t2) => function() {
return t2 || (0, e33[Nj(e33)[0]])((t2 = { exports: {} }).exports, t2), t2.exports;
};
var Aj = (e33, t2, n2) => (n2 = e33 != null ? Pj(Tj(e33)) : {}, ((e34, t3, n3, o2) => {
if (t3 && typeof t3 == "object" || typeof t3 == "function")
for (let i2 of Nj(t3))
Rj.call(e34, i2) || i2 === n3 || Mj(e34, i2, { get: () => t3[i2], enumerable: !(o2 = wj(t3, i2)) || o2.enumerable });
return e34;
})(e33 && e33.__esModule ? n2 : Mj(n2, "default", { value: e33, enumerable: true }), e33));
var Oj = Ej({ "node_modules/is-buffer/index.js"(e33, t2) {
function n2(e34) {
return !!e34.constructor && typeof e34.constructor.isBuffer == "function" && e34.constructor.isBuffer(e34);
}
t2.exports = function(e34) {
return e34 != null && (n2(e34) || function(e35) {
return typeof e35.readFloatLE == "function" && typeof e35.slice == "function" && n2(e35.slice(0, 0));
}(e34) || !!e34._isBuffer);
};
} });
var kj = Ej({ "node_modules/kind-of/index.js"(e33, t2) {
var n2 = Oj(), o2 = Object.prototype.toString;
t2.exports = function(e34) {
if (e34 === undefined)
return "undefined";
if (e34 === null)
return "null";
if (e34 === true || e34 === false || e34 instanceof Boolean)
return "boolean";
if (typeof e34 == "string" || e34 instanceof String)
return "string";
if (typeof e34 == "number" || e34 instanceof Number)
return "number";
if (typeof e34 == "function" || e34 instanceof Function)
return "function";
if (Array.isArray !== undefined && Array.isArray(e34))
return "array";
if (e34 instanceof RegExp)
return "regexp";
if (e34 instanceof Date)
return "date";
var t3 = o2.call(e34);
return t3 === "[object RegExp]" ? "regexp" : t3 === "[object Date]" ? "date" : t3 === "[object Arguments]" ? "arguments" : t3 === "[object Error]" ? "error" : n2(e34) ? "buffer" : t3 === "[object Set]" ? "set" : t3 === "[object WeakSet]" ? "weakset" : t3 === "[object Map]" ? "map" : t3 === "[object WeakMap]" ? "weakmap" : t3 === "[object Symbol]" ? "symbol" : t3 === "[object Int8Array]" ? "int8array" : t3 === "[object Uint8Array]" ? "uint8array" : t3 === "[object Uint8ClampedArray]" ? "uint8clampedarray" : t3 === "[object Int16Array]" ? "int16array" : t3 === "[object Uint16Array]" ? "uint16array" : t3 === "[object Int32Array]" ? "int32array" : t3 === "[object Uint32Array]" ? "uint32array" : t3 === "[object Float32Array]" ? "float32array" : t3 === "[object Float64Array]" ? "float64array" : "object";
};
} });
var Dj = Ej({ "node_modules/rename-keys/index.js"(e33, t2) {
(function() {
function e34(e35, t3) {
if (typeof t3 != "function")
return e35;
var n2 = {};
for (var o2 in e35)
Object.prototype.hasOwnProperty.call(e35, o2) && (n2[t3(o2, e35[o2]) || o2] = e35[o2]);
return n2;
}
t2 !== undefined && t2.exports ? t2.exports = e34 : typeof define == "function" && define.amd ? define([], function() {
return e34;
}) : window.rename = e34;
})();
} });
var Lj = Ej({ "node_modules/deep-rename-keys/index.js"(e33, t2) {
var n2 = kj(), o2 = Dj();
t2.exports = function e34(t3, i2) {
var r2 = n2(t3);
if (r2 !== "object" && r2 !== "array")
throw new Error("expected an object");
var s2 = [];
for (var a2 in r2 === "object" && (t3 = o2(t3, i2), s2 = {}), t3)
if (t3.hasOwnProperty(a2)) {
var c2 = t3[a2];
n2(c2) === "object" || n2(c2) === "array" ? s2[a2] = e34(c2, i2) : s2[a2] = c2;
}
return s2;
};
} });
var zj = Ej({ "node_modules/eventemitter3/index.js"(e33, t2) {
var n2 = Object.prototype.hasOwnProperty, o2 = "~";
function i2() {}
function r2(e34, t3, n3) {
this.fn = e34, this.context = t3, this.once = n3 || false;
}
function s2() {
this._events = new i2, this._eventsCount = 0;
}
Object.create && (i2.prototype = Object.create(null), new i2().__proto__ || (o2 = false)), s2.prototype.eventNames = function() {
var e34, t3, i3 = [];
if (this._eventsCount === 0)
return i3;
for (t3 in e34 = this._events)
n2.call(e34, t3) && i3.push(o2 ? t3.slice(1) : t3);
return Object.getOwnPropertySymbols ? i3.concat(Object.getOwnPropertySymbols(e34)) : i3;
}, s2.prototype.listeners = function(e34, t3) {
var n3 = o2 ? o2 + e34 : e34, i3 = this._events[n3];
if (t3)
return !!i3;
if (!i3)
return [];
if (i3.fn)
return [i3.fn];
for (var r3 = 0, s3 = i3.length, a2 = new Array(s3);r3 < s3; r3++)
a2[r3] = i3[r3].fn;
return a2;
}, s2.prototype.emit = function(e34, t3, n3, i3, r3, s3) {
var a2 = o2 ? o2 + e34 : e34;
if (!this._events[a2])
return false;
var c2, l2, h2 = this._events[a2], d2 = arguments.length;
if (h2.fn) {
switch (h2.once && this.removeListener(e34, h2.fn, undefined, true), d2) {
case 1:
return h2.fn.call(h2.context), true;
case 2:
return h2.fn.call(h2.context, t3), true;
case 3:
return h2.fn.call(h2.context, t3, n3), true;
case 4:
return h2.fn.call(h2.context, t3, n3, i3), true;
case 5:
return h2.fn.call(h2.context, t3, n3, i3, r3), true;
case 6:
return h2.fn.call(h2.context, t3, n3, i3, r3, s3), true;
}
for (l2 = 1, c2 = new Array(d2 - 1);l2 < d2; l2++)
c2[l2 - 1] = arguments[l2];
h2.fn.apply(h2.context, c2);
} else {
var u2, p2 = h2.length;
for (l2 = 0;l2 < p2; l2++)
switch (h2[l2].once && this.removeListener(e34, h2[l2].fn, undefined, true), d2) {
case 1:
h2[l2].fn.call(h2[l2].context);
break;
case 2:
h2[l2].fn.call(h2[l2].context, t3);
break;
case 3:
h2[l2].fn.call(h2[l2].context, t3, n3);
break;
case 4:
h2[l2].fn.call(h2[l2].context, t3, n3, i3);
break;
default:
if (!c2)
for (u2 = 1, c2 = new Array(d2 - 1);u2 < d2; u2++)
c2[u2 - 1] = arguments[u2];
h2[l2].fn.apply(h2[l2].context, c2);
}
}
return true;
}, s2.prototype.on = function(e34, t3, n3) {
var i3 = new r2(t3, n3 || this), s3 = o2 ? o2 + e34 : e34;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.once = function(e34, t3, n3) {
var i3 = new r2(t3, n3 || this, true), s3 = o2 ? o2 + e34 : e34;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.removeListener = function(e34, t3, n3, r3) {
var s3 = o2 ? o2 + e34 : e34;
if (!this._events[s3])
return this;
if (!t3)
return --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3], this;
var a2 = this._events[s3];
if (a2.fn)
a2.fn !== t3 || r3 && !a2.once || n3 && a2.context !== n3 || (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3]);
else {
for (var c2 = 0, l2 = [], h2 = a2.length;c2 < h2; c2++)
(a2[c2].fn !== t3 || r3 && !a2[c2].once || n3 && a2[c2].context !== n3) && l2.push(a2[c2]);
l2.length ? this._events[s3] = l2.length === 1 ? l2[0] : l2 : --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3];
}
return this;
}, s2.prototype.removeAllListeners = function(e34) {
var t3;
return e34 ? (t3 = o2 ? o2 + e34 : e34, this._events[t3] && (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[t3])) : (this._events = new i2, this._eventsCount = 0), this;
}, s2.prototype.off = s2.prototype.removeListener, s2.prototype.addListener = s2.prototype.on, s2.prototype.setMaxListeners = function() {
return this;
}, s2.prefixed = o2, s2.EventEmitter = s2, t2 !== undefined && (t2.exports = s2);
} });
var Bj = Ej({ "node_modules/xml-lexer/dist/lexer.js"(e33, t2) {
function n2(e34, t3, n3) {
return t3 in e34 ? Object.defineProperty(e34, t3, { value: n3, enumerable: true, configurable: true, writable: true }) : e34[t3] = n3, e34;
}
var o2 = zj(), i2 = function() {}, r2 = { 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" }, s2 = { lt: "action-lt", gt: "action-gt", space: "action-space", equal: "action-equal", quote: "action-quote", slash: "action-slash", char: "action-char", error: "action-error" }, a2 = { text: "text", openTag: "open-tag", closeTag: "close-tag", attributeName: "attribute-name", attributeValue: "attribute-value" }, c2 = { " ": s2.space, "\t": s2.space, "\n": s2.space, "\r": s2.space, "<": s2.lt, ">": s2.gt, '"': s2.quote, "'": s2.quote, "=": s2.equal, "/": s2.slash };
t2.exports = { State: r2, Action: s2, Type: a2, create: function(e34) {
var t3, l2, h2, d2, u2, p2, m2, g2, f2, _2;
e34 = Object.assign({ debug: false }, e34);
var y2 = new o2, b2 = r2.data, x2 = "", v2 = "", I2 = "", S2 = "", C2 = "", P2 = "", M2 = function(t4, n3) {
if (v2[0] !== "?" && v2[0] !== "!") {
var o3 = { type: t4, value: n3 };
e34.debug && console.log("emit:", o3), y2.emit("data", o3);
}
};
y2.stateMachine = (n2(_2 = {}, r2.data, (n2(t3 = {}, s2.lt, function() {
x2.trim() && M2(a2.text, x2), v2 = "", C2 = false, b2 = r2.tagBegin;
}), n2(t3, s2.char, function(e35) {
x2 += e35;
}), t3)), n2(_2, r2.cdata, n2({}, s2.char, function(e35) {
(x2 += e35).substr(-3) === "]]>" && (M2(a2.text, x2.slice(0, -3)), x2 = "", b2 = r2.data);
})), n2(_2, r2.tagBegin, (n2(l2 = {}, s2.space, i2), n2(l2, s2.char, function(e35) {
v2 = e35, b2 = r2.tagName;
}), n2(l2, s2.slash, function() {
v2 = "", C2 = true;
}), l2)), n2(_2, r2.tagName, (n2(h2 = {}, s2.space, function() {
C2 ? b2 = r2.tagEnd : (b2 = r2.attributeNameStart, M2(a2.openTag, v2));
}), n2(h2, s2.gt, function() {
M2(C2 ? a2.closeTag : a2.openTag, v2), x2 = "", b2 = r2.data;
}), n2(h2, s2.slash, function() {
b2 = r2.tagEnd, M2(a2.openTag, v2);
}), n2(h2, s2.char, function(e35) {
(v2 += e35) === "![CDATA[" && (b2 = r2.cdata, x2 = "", v2 = "");
}), h2)), n2(_2, r2.tagEnd, (n2(d2 = {}, s2.gt, function() {
M2(a2.closeTag, v2), x2 = "", b2 = r2.data;
}), n2(d2, s2.char, i2), d2)), n2(_2, r2.attributeNameStart, (n2(u2 = {}, s2.char, function(e35) {
I2 = e35, b2 = r2.attributeName;
}), n2(u2, s2.gt, function() {
x2 = "", b2 = r2.data;
}), n2(u2, s2.space, i2), n2(u2, s2.slash, function() {
C2 = true, b2 = r2.tagEnd;
}), u2)), n2(_2, r2.attributeName, (n2(p2 = {}, s2.space, function() {
b2 = r2.attributeNameEnd;
}), n2(p2, s2.equal, function() {
M2(a2.attributeName, I2), b2 = r2.attributeValueBegin;
}), n2(p2, s2.gt, function() {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), x2 = "", b2 = r2.data;
}), n2(p2, s2.slash, function() {
C2 = true, S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), b2 = r2.tagEnd;
}), n2(p2, s2.char, function(e35) {
I2 += e35;
}), p2)), n2(_2, r2.attributeNameEnd, (n2(m2 = {}, s2.space, i2), n2(m2, s2.equal, function() {
M2(a2.attributeName, I2), b2 = r2.attributeValueBegin;
}), n2(m2, s2.gt, function() {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), x2 = "", b2 = r2.data;
}), n2(m2, s2.char, function(e35) {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), I2 = e35, b2 = r2.attributeName;
}), m2)), n2(_2, r2.attributeValueBegin, (n2(g2 = {}, s2.space, i2), n2(g2, s2.quote, function(e35) {
P2 = e35, S2 = "", b2 = r2.attributeValue;
}), n2(g2, s2.gt, function() {
M2(a2.attributeValue, S2 = ""), x2 = "", b2 = r2.data;
}), n2(g2, s2.char, function(e35) {
P2 = "", S2 = e35, b2 = r2.attributeValue;
}), g2)), n2(_2, r2.attributeValue, (n2(f2 = {}, s2.space, function(e35) {
P2 ? S2 += e35 : (M2(a2.attributeValue, S2), b2 = r2.attributeNameStart);
}), n2(f2, s2.quote, function(e35) {
P2 === e35 ? (M2(a2.attributeValue, S2), b2 = r2.attributeNameStart) : S2 += e35;
}), n2(f2, s2.gt, function(e35) {
P2 ? S2 += e35 : (M2(a2.attributeValue, S2), x2 = "", b2 = r2.data);
}), n2(f2, s2.slash, function(e35) {
P2 ? S2 += e35 : (M2(a2.attributeValue, S2), C2 = true, b2 = r2.tagEnd);
}), n2(f2, s2.char, function(e35) {
S2 += e35;
}), f2)), _2);
var w2 = function(t4) {
e34.debug && console.log(b2, t4);
var n3 = y2.stateMachine[b2], o3 = n3[function(e35) {
return c2[e35] || s2.char;
}(t4)] || n3[s2.error] || n3[s2.char];
o3(t4);
};
return y2.write = function(e35) {
for (var t4 = e35.length, n3 = 0;n3 < t4; n3++)
w2(e35[n3]);
}, y2;
} };
} });
var Fj = Ej({ "node_modules/xml-reader/dist/reader.js"(e33, t2) {
var n2 = zj(), o2 = Bj(), i2 = o2.Type, r2 = { element: "element", text: "text" }, s2 = function(e34) {
return Object.assign({ name: "", type: r2.element, value: "", parent: null, attributes: {}, children: [] }, e34);
}, a2 = function(e34) {
e34 = Object.assign({ stream: false, parentNodes: true, doneEvent: "done", tagPrefix: "tag:", emitTopLevelOnly: false, debug: false }, e34);
var t3 = undefined, a3 = undefined, c2 = undefined, l2 = undefined, h2 = new n2, d2 = function(n3) {
switch (n3.type) {
case i2.openTag:
if (c2 === null)
(c2 = a3).name = n3.value;
else {
var o3 = s2({ name: n3.value, parent: c2 });
c2.children.push(o3), c2 = o3;
}
break;
case i2.closeTag:
var d3 = c2.parent;
if (e34.parentNodes || (c2.parent = null), c2.name !== n3.value)
break;
e34.stream && d3 === a3 && (a3.children = [], c2.parent = null), e34.emitTopLevelOnly && d3 !== a3 || (h2.emit(e34.tagPrefix + c2.name, c2), h2.emit("tag", c2.name, c2)), c2 === a3 && (t3.removeAllListeners("data"), h2.emit(e34.doneEvent, c2), a3 = null), c2 = d3;
break;
case i2.text:
c2 && c2.children.push(s2({ type: r2.text, value: n3.value, parent: e34.parentNodes ? c2 : null }));
break;
case i2.attributeName:
l2 = n3.value, c2.attributes[l2] = "";
break;
case i2.attributeValue:
c2.attributes[l2] = n3.value;
}
};
return h2.reset = function() {
(t3 = o2.create({ debug: e34.debug })).on("data", d2), a3 = s2(), c2 = null, l2 = "", h2.parse = t3.write;
}, h2.reset(), h2;
};
t2.exports = { parseSync: function(e34, t3) {
t3 = Object.assign({}, t3, { stream: false, tagPrefix: ":" });
var n3 = a2(t3), o3 = undefined;
return n3.on("done", function(e35) {
o3 = e35;
}), n3.parse(e34), o3;
}, create: a2, NodeType: r2 };
} });
(Aj(Lj()), Aj(Fj()), class {
MAX_ITERATIONS = 1e5;
solved = false;
failed = false;
iterations = 0;
progress = 0;
error = null;
activeSubSolver;
failedSubSolvers;
timeToSolve;
stats = {};
_setupDone = false;
setup() {
this._setupDone || (this._setup(), this._setupDone = true);
}
_setup() {}
step() {
if (this._setupDone || this.setup(), !this.solved && !this.failed) {
this.iterations++;
try {
this._step();
} catch (e33) {
throw this.error = `${this.constructor.name} error: ${e33}`, this.failed = true, e33;
}
!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 = true), "computeProgress" in this && (this.progress = this.computeProgress());
}
}
_step() {}
getConstructorParams() {
throw new Error("getConstructorParams not implemented");
}
getOutput() {
return null;
}
solve() {
const e33 = Date.now();
for (;!this.solved && !this.failed; )
this.step();
const t2 = Date.now();
this.timeToSolve = t2 - e33;
}
visualize() {
return { lines: [], points: [], rects: [], circles: [] };
}
tryFinalAcceptance() {}
preview() {
return { lines: [], points: [], rects: [], circles: [] };
}
});
var i$ = Object.create;
var r$ = Object.defineProperty;
var s$ = Object.getOwnPropertyDescriptor;
var a$ = Object.getOwnPropertyNames;
var c$ = Object.getPrototypeOf;
var l$ = Object.prototype.hasOwnProperty;
var h$ = (e33, t2) => function() {
return t2 || (0, e33[a$(e33)[0]])((t2 = { exports: {} }).exports, t2), t2.exports;
};
var d$ = h$({ "node_modules/binary-search-bounds/search-bounds.js"(e33, t2) {
function n2(e34, t3, n3, o3, i3) {
for (var r3 = i3 + 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e34[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) >= 0 ? (r3 = s3, i3 = s3 - 1) : o3 = s3 + 1;
}
return r3;
}
function o2(e34, t3, n3, o3, i3) {
for (var r3 = i3 + 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e34[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) > 0 ? (r3 = s3, i3 = s3 - 1) : o3 = s3 + 1;
}
return r3;
}
function i2(e34, t3, n3, o3, i3) {
for (var r3 = o3 - 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e34[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) < 0 ? (r3 = s3, o3 = s3 + 1) : i3 = s3 - 1;
}
return r3;
}
function r2(e34, t3, n3, o3, i3) {
for (var r3 = o3 - 1;o3 <= i3; ) {
var s3 = o3 + i3 >>> 1, a3 = e34[s3];
(n3 !== undefined ? n3(a3, t3) : a3 - t3) <= 0 ? (r3 = s3, o3 = s3 + 1) : i3 = s3 - 1;
}
return r3;
}
function s2(e34, t3, n3, o3, i3) {
for (;o3 <= i3; ) {
var r3 = o3 + i3 >>> 1, s3 = e34[r3], a3 = n3 !== undefined ? n3(s3, t3) : s3 - t3;
if (a3 === 0)
return r3;
a3 <= 0 ? o3 = r3 + 1 : i3 = r3 - 1;
}
return -1;
}
function a2(e34, t3, n3, o3, i3, r3) {
return typeof n3 == "function" ? r3(e34, t3, n3, o3 === undefined ? 0 : 0 | o3, i3 === undefined ? e34.length - 1 : 0 | i3) : r3(e34, t3, undefined, n3 === undefined ? 0 : 0 | n3, o3 === undefined ? e34.length - 1 : 0 | o3);
}
t2.exports = { ge: function(e34, t3, o3, i3, r3) {
return a2(e34, t3, o3, i3, r3, n2);
}, gt: function(e34, t3, n3, i3, r3) {
return a2(e34, t3, n3, i3, r3, o2);
}, lt: function(e34, t3, n3, o3, r3) {
return a2(e34, t3, n3, o3, r3, i2);
}, le: function(e34, t3, n3, o3, i3) {
return a2(e34, t3, n3, o3, i3, r2);
}, eq: function(e34, t3, n3, o3, i3) {
return a2(e34, t3, n3, o3, i3, s2);
} };
} });
var u$ = h$({ "node_modules/two-product/two-product.js"(e33, t2) {
t2.exports = function(e34, t3, o2) {
var i2 = e34 * t3, r2 = n2 * e34, s2 = r2 - (r2 - e34), a2 = e34 - s2, c2 = n2 * t3, l2 = c2 - (c2 - t3), h2 = t3 - l2, d2 = a2 * h2 - (i2 - s2 * l2 - a2 * l2 - s2 * h2);
if (o2)
return o2[0] = d2, o2[1] = i2, o2;
return [d2, i2];
};
var n2 = +(Math.pow(2, 27) + 1);
} });
var p$ = h$({ "node_modules/robust-sum/robust-sum.js"(e33, t2) {
t2.exports = function(e34, t3) {
var n2 = 0 | e34.length, o2 = 0 | t3.length;
if (n2 === 1 && o2 === 1)
return function(e35, t4) {
var n3 = e35 + t4, o3 = n3 - e35, i3 = n3 - o3, r3 = t4 - o3, s3 = e35 - i3, a3 = s3 + r3;
if (a3)
return [a3, n3];
return [n3];
}(e34[0], t3[0]);
var i2, r2, s2 = new Array(n2 + o2), a2 = 0, c2 = 0, l2 = 0, h2 = Math.abs, d2 = e34[c2], u2 = h2(d2), p2 = t3[l2], m2 = h2(p2);
u2 < m2 ? (r2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e34[c2]))) : (r2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = t3[l2])));
c2 < n2 && u2 < m2 || l2 >= o2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e34[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = t3[l2])));
var g2, f2, _2 = i2 + r2, y2 = _2 - i2, b2 = r2 - y2, x2 = b2, v2 = _2;
for (;c2 < n2 && l2 < o2; )
u2 < m2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e34[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = t3[l2]))), (b2 = (r2 = x2) - (y2 = (_2 = i2 + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2;
for (;c2 < n2; )
(b2 = (r2 = x2) - (y2 = (_2 = (i2 = d2) + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2, (c2 += 1) < n2 && (d2 = e34[c2]);
for (;l2 < o2; )
(b2 = (r2 = x2) - (y2 = (_2 = (i2 = p2) + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2, (l2 += 1) < o2 && (p2 = t3[l2]);
x2 && (s2[a2++] = x2);
v2 && (s2[a2++] = v2);
a2 || (s2[a2++] = 0);
return s2.length = a2, s2;
};
} });
var m$ = h$({ "node_modules/two-sum/two-sum.js"(e33, t2) {
t2.exports = function(e34, t3, n2) {
var o2 = e34 + t3, i2 = o2 - e34, r2 = t3 - i2, s2 = e34 - (o2 - i2);
if (n2)
return n2[0] = s2 + r2, n2[1] = o2, n2;
return [s2 + r2, o2];
};
} });
var g$ = h$({ "node_modules/robust-scale/robust-scale.js"(e33, t2) {
var n2 = u$(), o2 = m$();
t2.exports = function(e34, t3) {
var i2 = e34.length;
if (i2 === 1) {
var r2 = n2(e34[0], t3);
return r2[0] ? r2 : [r2[1]];
}
var s2 = new Array(2 * i2), a2 = [0.1, 0.1], c2 = [0.1, 0.1], l2 = 0;
n2(e34[0], t3, a2), a2[0] && (s2[l2++] = a2[0]);
for (var h2 = 1;h2 < i2; ++h2) {
n2(e34[h2], t3, c2);
var d2 = a2[1];
o2(d2, c2[0], a2), a2[0] && (s2[l2++] = a2[0]);
var u2 = c2[1], p2 = a2[1], m2 = u2 + p2, g2 = p2 - (m2 - u2);
a2[1] = m2, g2 && (s2[l2++] = g2);
}
a2[1] && (s2[l2++] = a2[1]);
l2 === 0 && (s2[l2++] = 0);
return s2.length = l2, s2;
};
} });
var f$ = h$({ "node_modules/robust-subtract/robust-diff.js"(e33, t2) {
t2.exports = function(e34, t3) {
var n2 = 0 | e34.length, o2 = 0 | t3.length;
if (n2 === 1 && o2 === 1)
return function(e35, t4) {
var n3 = e35 + t4, o3 = n3 - e35, i3 = n3 - o3, r3 = t4 - o3, s3 = e35 - i3, a3 = s3 + r3;
if (a3)
return [a3, n3];
return [n3];
}(e34[0], -t3[0]);
var i2, r2, s2 = new Array(n2 + o2), a2 = 0, c2 = 0, l2 = 0, h2 = Math.abs, d2 = e34[c2], u2 = h2(d2), p2 = -t3[l2], m2 = h2(p2);
u2 < m2 ? (r2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e34[c2]))) : (r2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = -t3[l2])));
c2 < n2 && u2 < m2 || l2 >= o2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e34[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = -t3[l2])));
var g2, f2, _2 = i2 + r2, y2 = _2 - i2, b2 = r2 - y2, x2 = b2, v2 = _2;
for (;c2 < n2 && l2 < o2; )
u2 < m2 ? (i2 = d2, (c2 += 1) < n2 && (u2 = h2(d2 = e34[c2]))) : (i2 = p2, (l2 += 1) < o2 && (m2 = h2(p2 = -t3[l2]))), (b2 = (r2 = x2) - (y2 = (_2 = i2 + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2;
for (;c2 < n2; )
(b2 = (r2 = x2) - (y2 = (_2 = (i2 = d2) + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2, (c2 += 1) < n2 && (d2 = e34[c2]);
for (;l2 < o2; )
(b2 = (r2 = x2) - (y2 = (_2 = (i2 = p2) + r2) - i2)) && (s2[a2++] = b2), x2 = v2 - ((g2 = v2 + _2) - (f2 = g2 - v2)) + (_2 - f2), v2 = g2, (l2 += 1) < o2 && (p2 = -t3[l2]);
x2 && (s2[a2++] = x2);
v2 && (s2[a2++] = v2);
a2 || (s2[a2++] = 0);
return s2.length = a2, s2;
};
} });
var _$ = h$({ "node_modules/robust-orientation/orientation.js"(e33, t2) {
var n2 = u$(), o2 = p$(), i2 = g$(), r2 = f$();
function s2(e34, t3, n3, o3) {
return function(n4, i3, r3) {
var s3 = e34(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), e34(t3(n4[1], i3[0]), t3(-i3[1], n4[0]))), a3 = e34(t3(n4[1], r3[0]), t3(-r3[1], n4[0])), c3 = o3(s3, a3);
return c3[c3.length - 1];
};
}
function a2(e34, t3, n3, o3) {
return function(i3, r3, s3, a3) {
var c3 = e34(e34(n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), r3[2]), e34(n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), -s3[2]), n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), a3[2]))), e34(n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), a3[2])))), l3 = e34(e34(n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), i3[2]), e34(n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -s3[2]), n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), a3[2]))), e34(n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), s3[2])))), h3 = o3(c3, l3);
return h3[h3.length - 1];
};
}
function c2(e34, t3, n3, o3) {
return function(i3, r3, s3, a3, c3) {
var l3 = e34(e34(e34(n3(e34(n3(e34(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), s3[2]), e34(n3(e34(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), -a3[2]), n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), c3[2]))), r3[3]), e34(n3(e34(n3(e34(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), r3[2]), e34(n3(e34(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -a3[2]), n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), c3[2]))), -s3[3]), n3(e34(n3(e34(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), r3[2]), e34(n3(e34(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -s3[2]), n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), c3[2]))), a3[3]))), e34(n3(e34(n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), r3[2]), e34(n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), -s3[2]), n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), a3[2]))), -c3[3]), e34(n3(e34(n3(e34(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), r3[2]), e34(n3(e34(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -a3[2]), n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), c3[2]))), i3[3]), n3(e34(n3(e34(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), i3[2]), e34(n3(e34(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -a3[2]), n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), c3[2]))), -r3[3])))), e34(e34(n3(e34(n3(e34(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), c3[2]))), a3[3]), e34(n3(e34(n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), a3[2]))), -c3[3]), n3(e34(n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), r3[2]), e34(n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), -s3[2]), n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), a3[2]))), i3[3]))), e34(n3(e34(n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), i3[2]), e34(n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -s3[2]), n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), a3[2]))), -r3[3]), e34(n3(e34(n3(e34(t3(r3[1], a3[0]), t3(-a3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), a3[2]))), s3[3]), n3(e34(n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), s3[2]))), -a3[3]))))), h3 = e34(e34(e34(n3(e34(n3(e34(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), s3[2]), e34(n3(e34(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), -a3[2]), n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), c3[2]))), i3[3]), n3(e34(n3(e34(t3(a3[1], c3[0]), t3(-c3[1], a3[0])), i3[2]), e34(n3(e34(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -a3[2]), n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), c3[2]))), -s3[3])), e34(n3(e34(n3(e34(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), i3[2]), e34(n3(e34(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -s3[2]), n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), c3[2]))), a3[3]), n3(e34(n3(e34(t3(s3[1], a3[0]), t3(-a3[1], s3[0])), i3[2]), e34(n3(e34(t3(i3[1], a3[0]), t3(-a3[1], i3[0])), -s3[2]), n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), a3[2]))), -c3[3]))), e34(e34(n3(e34(n3(e34(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), r3[2]), e34(n3(e34(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), -s3[2]), n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), c3[2]))), i3[3]), n3(e34(n3(e34(t3(s3[1], c3[0]), t3(-c3[1], s3[0])), i3[2]), e34(n3(e34(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -s3[2]), n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), c3[2]))), -r3[3])), e34(n3(e34(n3(e34(t3(r3[1], c3[0]), t3(-c3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], c3[0]), t3(-c3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), c3[2]))), s3[3]), n3(e34(n3(e34(t3(r3[1], s3[0]), t3(-s3[1], r3[0])), i3[2]), e34(n3(e34(t3(i3[1], s3[0]), t3(-s3[1], i3[0])), -r3[2]), n3(e34(t3(i3[1], r3[0]), t3(-r3[1], i3[0])), s3[2]))), -c3[3])))), d3 = o3(l3, h3);
return d3[d3.length - 1];
};
}
function l2(e34) {
return (e34 === 3 ? s2 : e34 === 4 ? a2 : c2)(o2, n2, i2, r2);
}
var h2 = l2(3), d2 = l2(4), u2 = [function() {
return 0;
}, function() {
return 0;
}, function(e34, t3) {
return t3[0] - e34[0];
}, function(e34, t3, n3) {
var o3, i3 = (e34[1] - n3[1]) * (t3[0] - n3[0]), r3 = (e34[0] - n3[0]) * (t3[1] - n3[1]), s3 = i3 - r3;
if (i3 > 0) {
if (r3 <= 0)
return s3;
o3 = i3 + r3;
} else {
if (!(i3 < 0))
return s3;
if (r3 >= 0)
return s3;
o3 = -(i3 + r3);
}
var a3 = 0.00000000000000033306690738754716 * o3;
return s3 >= a3 || s3 <= -a3 ? s3 : h2(e34, t3, n3);
}, function(e34, t3, n3, o3) {
var i3 = e34[0] - o3[0], r3 = t3[0] - o3[0], s3 = n3[0] - o3[0], a3 = e34[1] - o3[1], c3 = t3[1] - o3[1], l3 = n3[1] - o3[1], h3 = e34[2] - o3[2], u3 = t3[2] - o3[2], p3 = n3[2] - o3[2], m3 = r3 * l3, g2 = s3 * c3, f2 = s3 * a3, _2 = i3 * l3, y2 = i3 * c3, b2 = r3 * a3, x2 = h3 * (m3 - g2) + u3 * (f2 - _2) + p3 * (y2 - b2), v2 = 0.0000000000000007771561172376103 * ((Math.abs(m3) + Math.abs(g2)) * Math.abs(h3) + (Math.abs(f2) + Math.abs(_2)) * Math.abs(u3) + (Math.abs(y2) + Math.abs(b2)) * Math.abs(p3));
return x2 > v2 || -x2 > v2 ? x2 : d2(e34, t3, n3, o3);
}];
function p2(e34) {
var t3 = u2[e34.length];
return t3 || (t3 = u2[e34.length] = l2(e34.length)), t3.apply(undefined, e34);
}
function m2(e34, t3, n3, o3, i3, r3, s3) {
return function(t4, n4, a3, c3, l3) {
switch (arguments.length) {
case 0:
case 1:
return 0;
case 2:
return o3(t4, n4);
case 3:
return i3(t4, n4, a3);
case 4:
return r3(t4, n4, a3, c3);
case 5:
return s3(t4, n4, a3, c3, l3);
}
for (var h3 = new Array(arguments.length), d3 = 0;d3 < arguments.length; ++d3)
h3[d3] = arguments[d3];
return e34(h3);
};
}
(function() {
for (;u2.length <= 5; )
u2.push(l2(u2.length));
t2.exports = m2.apply(undefined, [p2].concat(u2));
for (var e34 = 0;e34 <= 5; ++e34)
t2.exports[e34] = u2[e34];
})();
} });
var y$ = h$({ "node_modules/cdt2d/lib/monotone.js"(e33, t2) {
var n2 = d$(), o2 = _$()[3];
function i2(e34, t3, n3, o3, i3) {
this.a = e34, this.b = t3, this.idx = n3, this.lowerIds = o3, this.upperIds = i3;
}
function r2(e34, t3, n3, o3) {
this.a = e34, this.b = t3, this.type = n3, this.idx = o3;
}
function s2(e34, t3) {
var n3 = e34.a[0] - t3.a[0] || e34.a[1] - t3.a[1] || e34.type - t3.type;
return n3 || (e34.type !== 0 && (n3 = o2(e34.a, e34.b, t3.b)) ? n3 : e34.idx - t3.idx);
}
function a2(e34, t3) {
return o2(e34.a, e34.b, t3);
}
function c2(e34, t3, i3, r3, s3) {
for (var c3 = n2.lt(t3, r3, a2), l3 = n2.gt(t3, r3, a2), h3 = c3;h3 < l3; ++h3) {
for (var d3 = t3[h3], u2 = d3.lowerIds, p2 = u2.length;p2 > 1 && o2(i3[u2[p2 - 2]], i3[u2[p2 - 1]], r3) > 0; )
e34.push([u2[p2 - 1], u2[p2 - 2], s3]), p2 -= 1;
u2.length = p2, u2.push(s3);
var m2 = d3.upperIds;
for (p2 = m2.length;p2 > 1 && o2(i3[m2[p2 - 2]], i3[m2[p2 - 1]], r3) < 0; )
e34.push([m2[p2 - 2], m2[p2 - 1], s3]), p2 -= 1;
m2.length = p2, m2.push(s3);
}
}
function l2(e34, t3) {
var n3;
return (n3 = e34.a[0] < t3.a[0] ? o2(e34.a, e34.b, t3.a) : o2(t3.b, t3.a, e34.a)) ? n3 : (n3 = t3.b[0] < e34.b[0] ? o2(e34.a, e34.b, t3.b) : o2(t3.b, t3.a, e34.b)) || e34.idx - t3.idx;
}
function h2(e34, t3, o3) {
var r3 = n2.le(e34, o3, l2), s3 = e34[r3], a3 = s3.upperIds, c3 = a3[a3.length - 1];
s3.upperIds = [c3], e34.splice(r3 + 1, 0, new i2(o3.a, o3.b, o3.idx, [c3], a3));
}
function d2(e34, t3, o3) {
var i3 = o3.a;
o3.a = o3.b, o3.b = i3;
var r3 = n2.eq(e34, o3, l2), s3 = e34[r3];
e34[r3 - 1].upperIds = s3.upperIds, e34.splice(r3, 1);
}
t2.exports = function(e34, t3) {
for (var n3 = e34.length, o3 = t3.length, a3 = [], l3 = 0;l3 < n3; ++l3)
a3.push(new r2(e34[l3], null, 0, l3));
for (l3 = 0;l3 < o3; ++l3) {
var u2 = t3[l3], p2 = e34[u2[0]], m2 = e34[u2[1]];
p2[0] < m2[0] ? a3.push(new r2(p2, m2, 2, l3), new r2(m2, p2, 1, l3)) : p2[0] > m2[0] && a3.push(new r2(m2, p2, 2, l3), new r2(p2, m2, 1, l3));
}
a3.sort(s2);
for (var g2 = a3[0].a[0] - (1 + Math.abs(a3[0].a[0])) * Math.pow(2, -52), f2 = [new i2([g2, 1], [g2, 0], -1, [], [])], _2 = [], y2 = (l3 = 0, a3.length);l3 < y2; ++l3) {
var b2 = a3[l3], x2 = b2.type;
x2 === 0 ? c2(_2, f2, e34, b2.a, b2.idx) : x2 === 2 ? h2(f2, e34, b2) : d2(f2, e34, b2);
}
return _2;
};
} });
var b$ = h$({ "node_modules/cdt2d/lib/triangulation.js"(e33, t2) {
var n2 = d$();
function o2(e34, t3) {
this.stars = e34, this.edges = t3;
}
t2.exports = function(e34, t3) {
for (var n3 = new Array(e34), i3 = 0;i3 < e34; ++i3)
n3[i3] = [];
return new o2(n3, t3);
};
var i2 = o2.prototype;
function r2(e34, t3, n3) {
for (var o3 = 1, i3 = e34.length;o3 < i3; o3 += 2)
if (e34[o3 - 1] === t3 && e34[o3] === n3)
return e34[o3 - 1] = e34[i3 - 2], e34[o3] = e34[i3 - 1], void (e34.length = i3 - 2);
}
i2.isConstraint = function() {
var e34 = [0, 0];
function t3(e35, t4) {
return e35[0] - t4[0] || e35[1] - t4[1];
}
return function(o3, i3) {
return e34[0] = Math.min(o3, i3), e34[1] = Math.max(o3, i3), n2.eq(this.edges, e34, t3) >= 0;
};
}(), i2.removeTriangle = function(e34, t3, n3) {
var o3 = this.stars;
r2(o3[e34], t3, n3), r2(o3[t3], n3, e34), r2(o3[n3], e34, t3);
}, i2.addTriangle = function(e34, t3, n3) {
var o3 = this.stars;
o3[e34].push(t3, n3), o3[t3].push(n3, e34), o3[n3].push(e34, t3);
}, i2.opposite = function(e34, t3) {
for (var n3 = this.stars[t3], o3 = 1, i3 = n3.length;o3 < i3; o3 += 2)
if (n3[o3] === e34)
return n3[o3 - 1];
return -1;
}, i2.flip = function(e34, t3) {
var n3 = this.opposite(e34, t3), o3 = this.opposite(t3, e34);
this.removeTriangle(e34, t3, n3), this.removeTriangle(t3, e34, o3), this.addTriangle(e34, o3, n3), this.addTriangle(t3, n3, o3);
}, i2.edges = function() {
for (var e34 = this.stars, t3 = [], n3 = 0, o3 = e34.length;n3 < o3; ++n3)
for (var i3 = e34[n3], r3 = 0, s2 = i3.length;r3 < s2; r3 += 2)
t3.push([i3[r3], i3[r3 + 1]]);
return t3;
}, i2.cells = function() {
for (var e34 = this.stars, t3 = [], n3 = 0, o3 = e34.length;n3 < o3; ++n3)
for (var i3 = e34[n3], r3 = 0, s2 = i3.length;r3 < s2; r3 += 2) {
var a2 = i3[r3], c2 = i3[r3 + 1];
n3 < Math.min(a2, c2) && t3.push([n3, a2, c2]);
}
return t3;
};
} });
var x$ = h$({ "node_modules/robust-in-sphere/in-sphere.js"(e33, t2) {
var n2 = u$(), o2 = p$(), i2 = f$(), r2 = g$();
function s2(e34) {
return (e34 === 3 ? a2 : e34 === 4 ? c2 : e34 === 5 ? l2 : h2)(o2, i2, n2, r2);
}
function a2(e34, t3, n3, o3) {
return function(i3, r3, s3) {
var a3 = n3(i3[0], i3[0]), c3 = o3(a3, r3[0]), l3 = o3(a3, s3[0]), h3 = n3(r3[0], r3[0]), d3 = o3(h3, i3[0]), u3 = o3(h3, s3[0]), p3 = n3(s3[0], s3[0]), m2 = o3(p3, i3[0]), g2 = o3(p3, r3[0]), f2 = e34(t3(g2, u3), t3(d3, c3)), _2 = t3(m2, l3), y2 = t3(f2, _2);
return y2[y2.length - 1];
};
}
function c2(e34, t3, n3, o3) {
return function(i3, r3, s3, a3) {
var c3 = e34(n3(i3[0], i3[0]), n3(i3[1], i3[1])), l3 = o3(c3, r3[0]), h3 = o3(c3, s3[0]), d3 = o3(c3, a3[0]), u3 = e34(n3(r3[0], r3[0]), n3(r3[1], r3[1])), p3 = o3(u3, i3[0]), m2 = o3(u3, s3[0]), g2 = o3(u3, a3[0]), f2 = e34(n3(s3[0], s3[0]), n3(s3[1], s3[1])), _2 = o3(f2, i3[0]), y2 = o3(f2, r3[0]), b2 = o3(f2, a3[0]), x2 = e34(n3(a3[0], a3[0]), n3(a3[1], a3[1])), v2 = o3(x2, i3[0]), I2 = o3(x2, r3[0]), S2 = o3(x2, s3[0]), C2 = e34(e34(o3(t3(S2, b2), r3[1]), e34(o3(t3(I2, g2), -s3[1]), o3(t3(y2, m2), a3[1]))), e34(o3(t3(I2, g2), i3[1]), e34(o3(t3(v2, d3), -r3[1]), o3(t3(p3, l3), a3[1])))), P2 = e34(e34(o3(t3(S2, b2), i3[1]), e34(o3(t3(v2, d3), -s3[1]), o3(t3(_2, h3), a3[1]))), e34(o3(t3(y2, m2), i3[1]), e34(o3(t3(_2, h3), -r3[1]), o3(t3(p3, l3), s3[1])))), M2 = t3(C2, P2);
return M2[M2.length - 1];
};
}
function l2(e34, t3, n3, o3) {
return function(i3, r3, s3, a3, c3) {
var l3 = e34(n3(i3[0], i3[0]), e34(n3(i3[1], i3[1]), n3(i3[2], i3[2]))), h3 = o3(l3, r3[0]), d3 = o3(l3, s3[0]), u3 = o3(l3, a3[0]), p3 = o3(l3, c3[0]), m2 = e34(n3(r3[0], r3[0]), e34(n3(r3[1], r3[1]), n3(r3[2], r3[2]))), g2 = o3(m2, i3[0]), f2 = o3(m2, s3[0]), _2 = o3(m2, a3[0]), y2 = o3(m2, c3[0]), b2 = e34(n3(s3[0], s3[0]), e34(n3(s3[1], s3[1]), n3(s3[2], s3[2]))), x2 = o3(b2, i3[0]), v2 = o3(b2, r3[0]), I2 = o3(b2, a3[0]), S2 = o3(b2, c3[0]), C2 = e34(n3(a3[0], a3[0]), e34(n3(a3[1], a3[1]), n3(a3[2], a3[2]))), P2 = o3(C2, i3[0]), M2 = o3(C2, r3[0]), w2 = o3(C2, s3[0]), N2 = o3(C2, c3[0]), T2 = e34(n3(c3[0], c3[0]), e34(n3(c3[1], c3[1]), n3(c3[2], c3[2]))), R2 = o3(T2, i3[0]), E2 = o3(T2, r3[0]), A2 = o3(T2, s3[0]), O2 = o3(T2, a3[0]), k2 = e34(e34(e34(o3(e34(o3(t3(O2, N2), s3[1]), e34(o3(t3(A2, S2), -a3[1]), o3(t3(w2, I2), c3[1]))), r3[2]), e34(o3(e34(o3(t3(O2, N2), r3[1]), e34(o3(t3(E2, y2), -a3[1]), o3(t3(M2, _2), c3[1]))), -s3[2]), o3(e34(o3(t3(A2, S2), r3[1]), e34(o3(t3(E2, y2), -s3[1]), o3(t3(v2, f2), c3[1]))), a3[2]))), e34(o3(e34(o3(t3(w2, I2), r3[1]), e34(o3(t3(M2, _2), -s3[1]), o3(t3(v2, f2), a3[1]))), -c3[2]), e34(o3(e34(o3(t3(O2, N2), r3[1]), e34(o3(t3(E2, y2), -a3[1]), o3(t3(M2, _2), c3[1]))), i3[2]), o3(e34(o3(t3(O2, N2), i3[1]), e34(o3(t3(R2, p3), -a3[1]), o3(t3(P2, u3), c3[1]))), -r3[2])))), e34(e34(o3(e34(o3(t3(E2, y2), i3[1]), e34(o3(t3(R2, p3), -r3[1]), o3(t3(g2, h3), c3[1]))), a3[2]), e34(o3(e34(o3(t3(M2, _2), i3[1]), e34(o3(t3(P2, u3), -r3[1]), o3(t3(g2, h3), a3[1]))), -c3[2]), o3(e34(o3(t3(w2, I2), r3[1]), e34(o3(t3(M2, _2), -s3[1]), o3(t3(v2, f2), a3[1]))), i3[2]))), e34(o3(e34(o3(t3(w2, I2), i3[1]), e34(o3(t3(P2, u3), -s3[1]), o3(t3(x2, d3), a3[1]))), -r3[2]), e34(o3(e34(o3(t3(M2, _2), i3[1]), e34(o3(t3(P2, u3), -r3[1]), o3(t3(g2, h3), a3[1]))), s3[2]), o3(e34(o3(t3(v2, f2), i3[1]), e34(o3(t3(x2, d3), -r3[1]), o3(t3(g2, h3), s3[1]))), -a3[2]))))), D2 = e34(e34(e34(o3(e34(o3(t3(O2, N2), s3[1]), e34(o3(t3(A2, S2), -a3[1]), o3(t3(w2, I2), c3[1]))), i3[2]), o3(e34(o3(t3(O2, N2), i3[1]), e34(o3(t3(R2, p3), -a3[1]), o3(t3(P2, u3), c3[1]))), -s3[2])), e34(o3(e34(o3(t3(A2, S2), i3[1]), e34(o3(t3(R2, p3), -s3[1]), o3(t3(x2, d3), c3[1]))), a3[2]), o3(e34(o3(t3(w2, I2), i3[1]), e34(o3(t3(P2, u3), -s3[1]), o3(t3(x2, d3), a3[1]))), -c3[2]))), e34(e34(o3(e34(o3(t3(A2, S2), r3[1]), e34(o3(t3(E2, y2), -s3[1]), o3(t3(v2, f2), c3[1]))), i3[2]), o3(e34(o3(t3(A2, S2), i3[1]), e34(o3(t3(R2, p3), -s3[1]), o3(t3(x2, d3), c3[1]))), -r3[2])), e34(o3(e34(o3(t3(E2, y2), i3[1]), e34(o3(t3(R2, p3), -r3[1]), o3(t3(g2, h3), c3[1]))), s3[2]), o3(e34(o3(t3(v2, f2), i3[1]), e34(o3(t3(x2, d3), -r3[1]), o3(t3(g2, h3), s3[1]))), -c3[2])))), L2 = t3(k2, D2);
return L2[L2.length - 1];
};
}
function h2(e34, t3, n3, o3) {
return function(i3, r3, s3, a3, c3, l3) {
var h3 = e34(e34(n3(i3[0], i3[0]), n3(i3[1], i3[1])), e34(n3(i3[2], i3[2]), n3(i3[3], i3[3]))), d3 = o3(h3, r3[0]), u3 = o3(h3, s3[0]), p3 = o3(h3, a3[0]), m2 = o3(h3, c3[0]), g2 = o3(h3, l3[0]), f2 = e34(e34(n3(r3[0], r3[0]), n3(r3[1], r3[1])), e34(n3(r3[2], r3[2]), n3(r3[3], r3[3]))), _2 = o3(f2, i3[0]), y2 = o3(f2, s3[0]), b2 = o3(f2, a3[0]), x2 = o3(f2, c3[0]), v2 = o3(f2, l3[0]), I2 = e34(e34(n3(s3[0], s3[0]), n3(s3[1], s3[1])), e34(n3(s3[2], s3[2]), n3(s3[3], s3[3]))), S2 = o3(I2, i3[0]), C2 = o3(I2, r3[0]), P2 = o3(I2, a3[0]), M2 = o3(I2, c3[0]), w2 = o3(I2, l3[0]), N2 = e34(e34(n3(a3[0], a3[0]), n3(a3[1], a3[1])), e34(n3(a3[2], a3[2]), n3(a3[3], a3[3]))), T2 = o3(N2, i3[0]), R2 = o3(N2, r3[0]), E2 = o3(N2, s3[0]), A2 = o3(N2, c3[0]), O2 = o3(N2, l3[0]), k2 = e34(e34(n3(c3[0], c3[0]), n3(c3[1], c3[1])), e34(n3(c3[2], c3[2]), n3(c3[3], c3[3]))), D2 = o3(k2, i3[0]), L2 = o3(k2, r3[0]), z2 = o3(k2, s3[0]), B2 = o3(k2, a3[0]), F2 = o3(k2, l3[0]), j2 = e34(e34(n3(l3[0], l3[0]), n3(l3[1], l3[1])), e34(n3(l3[2], l3[2]), n3(l3[3], l3[3]))), $2 = o3(j2, i3[0]), Y = o3(j2, r3[0]), X2 = o3(j2, s3[0]), W2 = o3(j2, a3[0]), V2 = o3(j2, c3[0]), H2 = e34(e34(e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), a3[1]), e34(o3(t3(W2, O2), -c3[1]), o3(t3(B2, A2), l3[1]))), s3[2]), o3(e34(o3(t3(V2, F2), s3[1]), e34(o3(t3(X2, w2), -c3[1]), o3(t3(z2, M2), l3[1]))), -a3[2])), e34(o3(e34(o3(t3(W2, O2), s3[1]), e34(o3(t3(X2, w2), -a3[1]), o3(t3(E2, P2), l3[1]))), c3[2]), o3(e34(o3(t3(B2, A2), s3[1]), e34(o3(t3(z2, M2), -a3[1]), o3(t3(E2, P2), c3[1]))), -l3[2]))), r3[3]), e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), a3[1]), e34(o3(t3(W2, O2), -c3[1]), o3(t3(B2, A2), l3[1]))), r3[2]), o3(e34(o3(t3(V2, F2), r3[1]), e34(o3(t3(Y, v2), -c3[1]), o3(t3(L2, x2), l3[1]))), -a3[2])), e34(o3(e34(o3(t3(W2, O2), r3[1]), e34(o3(t3(Y, v2), -a3[1]), o3(t3(R2, b2), l3[1]))), c3[2]), o3(e34(o3(t3(B2, A2), r3[1]), e34(o3(t3(L2, x2), -a3[1]), o3(t3(R2, b2), c3[1]))), -l3[2]))), -s3[3]), o3(e34(e34(o3(e34(o3(t3(V2, F2), s3[1]), e34(o3(t3(X2, w2), -c3[1]), o3(t3(z2, M2), l3[1]))), r3[2]), o3(e34(o3(t3(V2, F2), r3[1]), e34(o3(t3(Y, v2), -c3[1]), o3(t3(L2, x2), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), r3[1]), e34(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), c3[2]), o3(e34(o3(t3(z2, M2), r3[1]), e34(o3(t3(L2, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), -l3[2]))), a3[3]))), e34(e34(o3(e34(e34(o3(e34(o3(t3(W2, O2), s3[1]), e34(o3(t3(X2, w2), -a3[1]), o3(t3(E2, P2), l3[1]))), r3[2]), o3(e34(o3(t3(W2, O2), r3[1]), e34(o3(t3(Y, v2), -a3[1]), o3(t3(R2, b2), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), r3[1]), e34(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), r3[1]), e34(o3(t3(R2, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -l3[2]))), -c3[3]), o3(e34(e34(o3(e34(o3(t3(B2, A2), s3[1]), e34(o3(t3(z2, M2), -a3[1]), o3(t3(E2, P2), c3[1]))), r3[2]), o3(e34(o3(t3(B2, A2), r3[1]), e34(o3(t3(L2, x2), -a3[1]), o3(t3(R2, b2), c3[1]))), -s3[2])), e34(o3(e34(o3(t3(z2, M2), r3[1]), e34(o3(t3(L2, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), r3[1]), e34(o3(t3(R2, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -c3[2]))), l3[3])), e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), a3[1]), e34(o3(t3(W2, O2), -c3[1]), o3(t3(B2, A2), l3[1]))), r3[2]), o3(e34(o3(t3(V2, F2), r3[1]), e34(o3(t3(Y, v2), -c3[1]), o3(t3(L2, x2), l3[1]))), -a3[2])), e34(o3(e34(o3(t3(W2, O2), r3[1]), e34(o3(t3(Y, v2), -a3[1]), o3(t3(R2, b2), l3[1]))), c3[2]), o3(e34(o3(t3(B2, A2), r3[1]), e34(o3(t3(L2, x2), -a3[1]), o3(t3(R2, b2), c3[1]))), -l3[2]))), i3[3]), o3(e34(e34(o3(e34(o3(t3(V2, F2), a3[1]), e34(o3(t3(W2, O2), -c3[1]), o3(t3(B2, A2), l3[1]))), i3[2]), o3(e34(o3(t3(V2, F2), i3[1]), e34(o3(t3($2, g2), -c3[1]), o3(t3(D2, m2), l3[1]))), -a3[2])), e34(o3(e34(o3(t3(W2, O2), i3[1]), e34(o3(t3($2, g2), -a3[1]), o3(t3(T2, p3), l3[1]))), c3[2]), o3(e34(o3(t3(B2, A2), i3[1]), e34(o3(t3(D2, m2), -a3[1]), o3(t3(T2, p3), c3[1]))), -l3[2]))), -r3[3])))), e34(e34(e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), r3[1]), e34(o3(t3(Y, v2), -c3[1]), o3(t3(L2, x2), l3[1]))), i3[2]), o3(e34(o3(t3(V2, F2), i3[1]), e34(o3(t3($2, g2), -c3[1]), o3(t3(D2, m2), l3[1]))), -r3[2])), e34(o3(e34(o3(t3(Y, v2), i3[1]), e34(o3(t3($2, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), c3[2]), o3(e34(o3(t3(L2, x2), i3[1]), e34(o3(t3(D2, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), -l3[2]))), a3[3]), o3(e34(e34(o3(e34(o3(t3(W2, O2), r3[1]), e34(o3(t3(Y, v2), -a3[1]), o3(t3(R2, b2), l3[1]))), i3[2]), o3(e34(o3(t3(W2, O2), i3[1]), e34(o3(t3($2, g2), -a3[1]), o3(t3(T2, p3), l3[1]))), -r3[2])), e34(o3(e34(o3(t3(Y, v2), i3[1]), e34(o3(t3($2, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), a3[2]), o3(e34(o3(t3(R2, b2), i3[1]), e34(o3(t3(T2, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -l3[2]))), -c3[3])), e34(o3(e34(e34(o3(e34(o3(t3(B2, A2), r3[1]), e34(o3(t3(L2, x2), -a3[1]), o3(t3(R2, b2), c3[1]))), i3[2]), o3(e34(o3(t3(B2, A2), i3[1]), e34(o3(t3(D2, m2), -a3[1]), o3(t3(T2, p3), c3[1]))), -r3[2])), e34(o3(e34(o3(t3(L2, x2), i3[1]), e34(o3(t3(D2, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), a3[2]), o3(e34(o3(t3(R2, b2), i3[1]), e34(o3(t3(T2, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -c3[2]))), l3[3]), o3(e34(e34(o3(e34(o3(t3(W2, O2), s3[1]), e34(o3(t3(X2, w2), -a3[1]), o3(t3(E2, P2), l3[1]))), r3[2]), o3(e34(o3(t3(W2, O2), r3[1]), e34(o3(t3(Y, v2), -a3[1]), o3(t3(R2, b2), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), r3[1]), e34(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), r3[1]), e34(o3(t3(R2, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -l3[2]))), i3[3]))), e34(e34(o3(e34(e34(o3(e34(o3(t3(W2, O2), s3[1]), e34(o3(t3(X2, w2), -a3[1]), o3(t3(E2, P2), l3[1]))), i3[2]), o3(e34(o3(t3(W2, O2), i3[1]), e34(o3(t3($2, g2), -a3[1]), o3(t3(T2, p3), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), i3[1]), e34(o3(t3($2, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), i3[1]), e34(o3(t3(T2, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -l3[2]))), -r3[3]), o3(e34(e34(o3(e34(o3(t3(W2, O2), r3[1]), e34(o3(t3(Y, v2), -a3[1]), o3(t3(R2, b2), l3[1]))), i3[2]), o3(e34(o3(t3(W2, O2), i3[1]), e34(o3(t3($2, g2), -a3[1]), o3(t3(T2, p3), l3[1]))), -r3[2])), e34(o3(e34(o3(t3(Y, v2), i3[1]), e34(o3(t3($2, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), a3[2]), o3(e34(o3(t3(R2, b2), i3[1]), e34(o3(t3(T2, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -l3[2]))), s3[3])), e34(o3(e34(e34(o3(e34(o3(t3(X2, w2), r3[1]), e34(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), i3[2]), o3(e34(o3(t3(X2, w2), i3[1]), e34(o3(t3($2, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), -r3[2])), e34(o3(e34(o3(t3(Y, v2), i3[1]), e34(o3(t3($2, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), s3[2]), o3(e34(o3(t3(C2, y2), i3[1]), e34(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -l3[2]))), -a3[3]), o3(e34(e34(o3(e34(o3(t3(E2, P2), r3[1]), e34(o3(t3(R2, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), i3[2]), o3(e34(o3(t3(E2, P2), i3[1]), e34(o3(t3(T2, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -r3[2])), e34(o3(e34(o3(t3(R2, b2), i3[1]), e34(o3(t3(T2, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), s3[2]), o3(e34(o3(t3(C2, y2), i3[1]), e34(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -a3[2]))), l3[3]))))), G2 = e34(e34(e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), a3[1]), e34(o3(t3(W2, O2), -c3[1]), o3(t3(B2, A2), l3[1]))), s3[2]), o3(e34(o3(t3(V2, F2), s3[1]), e34(o3(t3(X2, w2), -c3[1]), o3(t3(z2, M2), l3[1]))), -a3[2])), e34(o3(e34(o3(t3(W2, O2), s3[1]), e34(o3(t3(X2, w2), -a3[1]), o3(t3(E2, P2), l3[1]))), c3[2]), o3(e34(o3(t3(B2, A2), s3[1]), e34(o3(t3(z2, M2), -a3[1]), o3(t3(E2, P2), c3[1]))), -l3[2]))), i3[3]), e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), a3[1]), e34(o3(t3(W2, O2), -c3[1]), o3(t3(B2, A2), l3[1]))), i3[2]), o3(e34(o3(t3(V2, F2), i3[1]), e34(o3(t3($2, g2), -c3[1]), o3(t3(D2, m2), l3[1]))), -a3[2])), e34(o3(e34(o3(t3(W2, O2), i3[1]), e34(o3(t3($2, g2), -a3[1]), o3(t3(T2, p3), l3[1]))), c3[2]), o3(e34(o3(t3(B2, A2), i3[1]), e34(o3(t3(D2, m2), -a3[1]), o3(t3(T2, p3), c3[1]))), -l3[2]))), -s3[3]), o3(e34(e34(o3(e34(o3(t3(V2, F2), s3[1]), e34(o3(t3(X2, w2), -c3[1]), o3(t3(z2, M2), l3[1]))), i3[2]), o3(e34(o3(t3(V2, F2), i3[1]), e34(o3(t3($2, g2), -c3[1]), o3(t3(D2, m2), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), i3[1]), e34(o3(t3($2, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), c3[2]), o3(e34(o3(t3(z2, M2), i3[1]), e34(o3(t3(D2, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -l3[2]))), a3[3]))), e34(e34(o3(e34(e34(o3(e34(o3(t3(W2, O2), s3[1]), e34(o3(t3(X2, w2), -a3[1]), o3(t3(E2, P2), l3[1]))), i3[2]), o3(e34(o3(t3(W2, O2), i3[1]), e34(o3(t3($2, g2), -a3[1]), o3(t3(T2, p3), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), i3[1]), e34(o3(t3($2, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), i3[1]), e34(o3(t3(T2, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -l3[2]))), -c3[3]), o3(e34(e34(o3(e34(o3(t3(B2, A2), s3[1]), e34(o3(t3(z2, M2), -a3[1]), o3(t3(E2, P2), c3[1]))), i3[2]), o3(e34(o3(t3(B2, A2), i3[1]), e34(o3(t3(D2, m2), -a3[1]), o3(t3(T2, p3), c3[1]))), -s3[2])), e34(o3(e34(o3(t3(z2, M2), i3[1]), e34(o3(t3(D2, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), i3[1]), e34(o3(t3(T2, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -c3[2]))), l3[3])), e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), s3[1]), e34(o3(t3(X2, w2), -c3[1]), o3(t3(z2, M2), l3[1]))), r3[2]), o3(e34(o3(t3(V2, F2), r3[1]), e34(o3(t3(Y, v2), -c3[1]), o3(t3(L2, x2), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), r3[1]), e34(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), c3[2]), o3(e34(o3(t3(z2, M2), r3[1]), e34(o3(t3(L2, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), -l3[2]))), i3[3]), o3(e34(e34(o3(e34(o3(t3(V2, F2), s3[1]), e34(o3(t3(X2, w2), -c3[1]), o3(t3(z2, M2), l3[1]))), i3[2]), o3(e34(o3(t3(V2, F2), i3[1]), e34(o3(t3($2, g2), -c3[1]), o3(t3(D2, m2), l3[1]))), -s3[2])), e34(o3(e34(o3(t3(X2, w2), i3[1]), e34(o3(t3($2, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), c3[2]), o3(e34(o3(t3(z2, M2), i3[1]), e34(o3(t3(D2, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -l3[2]))), -r3[3])))), e34(e34(e34(o3(e34(e34(o3(e34(o3(t3(V2, F2), r3[1]), e34(o3(t3(Y, v2), -c3[1]), o3(t3(L2, x2), l3[1]))), i3[2]), o3(e34(o3(t3(V2, F2), i3[1]), e34(o3(t3($2, g2), -c3[1]), o3(t3(D2, m2), l3[1]))), -r3[2])), e34(o3(e34(o3(t3(Y, v2), i3[1]), e34(o3(t3($2, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), c3[2]), o3(e34(o3(t3(L2, x2), i3[1]), e34(o3(t3(D2, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), -l3[2]))), s3[3]), o3(e34(e34(o3(e34(o3(t3(X2, w2), r3[1]), e34(o3(t3(Y, v2), -s3[1]), o3(t3(C2, y2), l3[1]))), i3[2]), o3(e34(o3(t3(X2, w2), i3[1]), e34(o3(t3($2, g2), -s3[1]), o3(t3(S2, u3), l3[1]))), -r3[2])), e34(o3(e34(o3(t3(Y, v2), i3[1]), e34(o3(t3($2, g2), -r3[1]), o3(t3(_2, d3), l3[1]))), s3[2]), o3(e34(o3(t3(C2, y2), i3[1]), e34(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -l3[2]))), -c3[3])), e34(o3(e34(e34(o3(e34(o3(t3(z2, M2), r3[1]), e34(o3(t3(L2, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), i3[2]), o3(e34(o3(t3(z2, M2), i3[1]), e34(o3(t3(D2, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -r3[2])), e34(o3(e34(o3(t3(L2, x2), i3[1]), e34(o3(t3(D2, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), s3[2]), o3(e34(o3(t3(C2, y2), i3[1]), e34(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -c3[2]))), l3[3]), o3(e34(e34(o3(e34(o3(t3(B2, A2), s3[1]), e34(o3(t3(z2, M2), -a3[1]), o3(t3(E2, P2), c3[1]))), r3[2]), o3(e34(o3(t3(B2, A2), r3[1]), e34(o3(t3(L2, x2), -a3[1]), o3(t3(R2, b2), c3[1]))), -s3[2])), e34(o3(e34(o3(t3(z2, M2), r3[1]), e34(o3(t3(L2, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), r3[1]), e34(o3(t3(R2, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), -c3[2]))), i3[3]))), e34(e34(o3(e34(e34(o3(e34(o3(t3(B2, A2), s3[1]), e34(o3(t3(z2, M2), -a3[1]), o3(t3(E2, P2), c3[1]))), i3[2]), o3(e34(o3(t3(B2, A2), i3[1]), e34(o3(t3(D2, m2), -a3[1]), o3(t3(T2, p3), c3[1]))), -s3[2])), e34(o3(e34(o3(t3(z2, M2), i3[1]), e34(o3(t3(D2, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), a3[2]), o3(e34(o3(t3(E2, P2), i3[1]), e34(o3(t3(T2, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -c3[2]))), -r3[3]), o3(e34(e34(o3(e34(o3(t3(B2, A2), r3[1]), e34(o3(t3(L2, x2), -a3[1]), o3(t3(R2, b2), c3[1]))), i3[2]), o3(e34(o3(t3(B2, A2), i3[1]), e34(o3(t3(D2, m2), -a3[1]), o3(t3(T2, p3), c3[1]))), -r3[2])), e34(o3(e34(o3(t3(L2, x2), i3[1]), e34(o3(t3(D2, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), a3[2]), o3(e34(o3(t3(R2, b2), i3[1]), e34(o3(t3(T2, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), -c3[2]))), s3[3])), e34(o3(e34(e34(o3(e34(o3(t3(z2, M2), r3[1]), e34(o3(t3(L2, x2), -s3[1]), o3(t3(C2, y2), c3[1]))), i3[2]), o3(e34(o3(t3(z2, M2), i3[1]), e34(o3(t3(D2, m2), -s3[1]), o3(t3(S2, u3), c3[1]))), -r3[2])), e34(o3(e34(o3(t3(L2, x2), i3[1]), e34(o3(t3(D2, m2), -r3[1]), o3(t3(_2, d3), c3[1]))), s3[2]), o3(e34(o3(t3(C2, y2), i3[1]), e34(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -c3[2]))), -a3[3]), o3(e34(e34(o3(e34(o3(t3(E2, P2), r3[1]), e34(o3(t3(R2, b2), -s3[1]), o3(t3(C2, y2), a3[1]))), i3[2]), o3(e34(o3(t3(E2, P2), i3[1]), e34(o3(t3(T2, p3), -s3[1]), o3(t3(S2, u3), a3[1]))), -r3[2])), e34(o3(e34(o3(t3(R2, b2), i3[1]), e34(o3(t3(T2, p3), -r3[1]), o3(t3(_2, d3), a3[1]))), s3[2]), o3(e34(o3(t3(C2, y2), i3[1]), e34(o3(t3(S2, u3), -r3[1]), o3(t3(_2, d3), s3[1]))), -a3[2]))), c3[3]))))), U2 = t3(H2, G2);
return U2[U2.length - 1];
};
}
var d2 = [function() {
return 0;
}, function() {
return 0;
}, function() {
return 0;
}];
function u2(e34) {
var t3 = d2[e34.length];
return t3 || (t3 = d2[e34.length] = s2(e34.length)), t3.apply(undefined, e34);
}
function p2(e34, t3, n3, o3, i3, r3, s3, a3) {
return function(t4, n4, c3, l3, h3, d3) {
switch (arguments.length) {
case 0:
case 1:
return 0;
case 2:
return o3(t4, n4);
case 3:
return i3(t4, n4, c3);
case 4:
return r3(t4, n4, c3, l3);
case 5:
return s3(t4, n4, c3, l3, h3);
case 6:
return a3(t4, n4, c3, l3, h3, d3);
}
for (var u3 = new Array(arguments.length), p3 = 0;p3 < arguments.length; ++p3)
u3[p3] = arguments[p3];
return e34(u3);
};
}
(function() {
for (;d2.length <= 6; )
d2.push(s2(d2.length));
t2.exports = p2.apply(undefined, [u2].concat(d2));
for (var e34 = 0;e34 <= 6; ++e34)
t2.exports[e34] = d2[e34];
})();
} });
var v$ = h$({ "node_modules/cdt2d/lib/delaunay.js"(e33, t2) {
var n2 = x$()[4];
d$();
function o2(e34, t3, o3, i2, r2, s2) {
var a2 = t3.opposite(i2, r2);
if (!(a2 < 0)) {
if (r2 < i2) {
var c2 = i2;
i2 = r2, r2 = c2, c2 = s2, s2 = a2, a2 = c2;
}
t3.isConstraint(i2, r2) || n2(e34[i2], e34[r2], e34[s2], e34[a2]) < 0 && o3.push(i2, r2);
}
}
t2.exports = function(e34, t3) {
for (var i2 = [], r2 = e34.length, s2 = t3.stars, a2 = 0;a2 < r2; ++a2)
for (var c2 = s2[a2], l2 = 1;l2 < c2.length; l2 += 2) {
if (!((p2 = c2[l2]) < a2) && !t3.isConstraint(a2, p2)) {
for (var h2 = c2[l2 - 1], d2 = -1, u2 = 1;u2 < c2.length; u2 += 2)
if (c2[u2 - 1] === p2) {
d2 = c2[u2];
break;
}
d2 < 0 || n2(e34[a2], e34[p2], e34[h2], e34[d2]) < 0 && i2.push(a2, p2);
}
}
for (;i2.length > 0; ) {
for (var p2 = i2.pop(), m2 = (h2 = -1, d2 = -1, c2 = s2[a2 = i2.pop()], 1);m2 < c2.length; m2 += 2) {
var g2 = c2[m2 - 1], f2 = c2[m2];
g2 === p2 ? d2 = f2 : f2 === p2 && (h2 = g2);
}
h2 < 0 || d2 < 0 || (n2(e34[a2], e34[p2], e34[h2], e34[d2]) >= 0 || (t3.flip(a2, p2), o2(e34, t3, i2, h2, a2, d2), o2(e34, t3, i2, a2, d2, h2), o2(e34, t3, i2, d2, p2, h2), o2(e34, t3, i2, p2, h2, d2)));
}
};
} });
var I$ = h$({ "node_modules/cdt2d/lib/filter.js"(e33, t2) {
var n2 = d$();
function o2(e34, t3, n3, o3, i3, r2, s2) {
this.cells = e34, this.neighbor = t3, this.flags = o3, this.constraint = n3, this.active = i3, this.next = r2, this.boundary = s2;
}
function i2(e34, t3) {
return e34[0] - t3[0] || e34[1] - t3[1] || e34[2] - t3[2];
}
t2.exports = function(e34, t3, n3) {
var r2 = function(e35, t4) {
for (var n4 = e35.cells(), r3 = n4.length, s3 = 0;s3 < r3; ++s3) {
var a3 = (_3 = n4[s3])[0], c3 = _3[1], l3 = _3[2];
c3 < l3 ? c3 < a3 && (_3[0] = c3, _3[1] = l3, _3[2] = a3) : l3 < a3 && (_3[0] = l3, _3[1] = a3, _3[2] = c3);
}
n4.sort(i2);
var h3 = new Array(r3);
for (s3 = 0;s3 < h3.length; ++s3)
h3[s3] = 0;
var d3 = [], u3 = [], p3 = new Array(3 * r3), m3 = new Array(3 * r3), g3 = null;
t4 && (g3 = []);
var f3 = new o2(n4, p3, m3, h3, d3, u3, g3);
for (s3 = 0;s3 < r3; ++s3)
for (var _3 = n4[s3], y2 = 0;y2 < 3; ++y2) {
a3 = _3[y2], c3 = _3[(y2 + 1) % 3];
var b2 = p3[3 * s3 + y2] = f3.locate(c3, a3, e35.opposite(c3, a3)), x2 = m3[3 * s3 + y2] = e35.isConstraint(a3, c3);
b2 < 0 && (x2 ? u3.push(s3) : (d3.push(s3), h3[s3] = 1), t4 && g3.push([c3, a3, -1]));
}
return f3;
}(e34, n3);
if (t3 === 0)
return n3 ? r2.cells.concat(r2.boundary) : r2.cells;
var s2 = 1, a2 = r2.active, c2 = r2.next, l2 = r2.flags, h2 = r2.cells, d2 = r2.constraint, u2 = r2.neighbor;
for (;a2.length > 0 || c2.length > 0; ) {
for (;a2.length > 0; ) {
var p2 = a2.pop();
if (l2[p2] !== -s2) {
l2[p2] = s2;
h2[p2];
for (var m2 = 0;m2 < 3; ++m2) {
var g2 = u2[3 * p2 + m2];
g2 >= 0 && l2[g2] === 0 && (d2[3 * p2 + m2] ? c2.push(g2) : (a2.push(g2), l2[g2] = s2));
}
}
}
var f2 = c2;
c2 = a2, a2 = f2, c2.length = 0, s2 = -s2;
}
var _2 = function(e35, t4, n4) {
for (var o3 = 0, i3 = 0;i3 < e35.length; ++i3)
t4[i3] === n4 && (e35[o3++] = e35[i3]);
return e35.length = o3, e35;
}(h2, l2, t3);
if (n3)
return _2.concat(r2.boundary);
return _2;
}, o2.prototype.locate = function() {
var e34 = [0, 0, 0];
return function(t3, o3, r2) {
var s2 = t3, a2 = o3, c2 = r2;
return o3 < r2 ? o3 < t3 && (s2 = o3, a2 = r2, c2 = t3) : r2 < t3 && (s2 = r2, a2 = t3, c2 = o3), s2 < 0 ? -1 : (e34[0] = s2, e34[1] = a2, e34[2] = c2, n2.eq(this.cells, e34, i2));
};
}();
} });
var S$ = h$({ "node_modules/cdt2d/cdt2d.js"(e33, t2) {
var n2 = y$(), o2 = b$(), i2 = v$(), r2 = I$();
function s2(e34) {
return [Math.min(e34[0], e34[1]), Math.max(e34[0], e34[1])];
}
function a2(e34, t3) {
return e34[0] - t3[0] || e34[1] - t3[1];
}
function c2(e34, t3, n3) {
return t3 in e34 ? e34[t3] : n3;
}
t2.exports = function(e34, t3, l2) {
Array.isArray(t3) ? (l2 = l2 || {}, t3 = t3 || []) : (l2 = t3 || {}, t3 = []);
var h2 = !!c2(l2, "delaunay", true), d2 = !!c2(l2, "interior", true), u2 = !!c2(l2, "exterior", true), p2 = !!c2(l2, "infinity", false);
if (!d2 && !u2 || e34.length === 0)
return [];
var m2 = n2(e34, t3);
if (h2 || d2 !== u2 || p2) {
for (var g2 = o2(e34.length, function(e35) {
return e35.map(s2).sort(a2);
}(t3)), f2 = 0;f2 < m2.length; ++f2) {
var _2 = m2[f2];
g2.addTriangle(_2[0], _2[1], _2[2]);
}
return h2 && i2(e34, g2), u2 ? d2 ? p2 ? r2(g2, 0, p2) : g2.cells() : r2(g2, 1, p2) : r2(g2, -1);
}
return m2;
};
} });
var SY = true;
var CY = { CCW: -1, CW: 1, NOT_ORIENTABLE: 0 };
var PY = 2 * Math.PI;
var MY = Object.freeze({ __proto__: null, BOUNDARY: 2, CCW: SY, CONTAINS: 3, CW: false, END_VERTEX: 2, INSIDE: 1, INTERLACE: 4, NOT_VERTEX: 0, ORIENTATION: CY, OUTSIDE: 0, OVERLAP_OPPOSITE: 2, OVERLAP_SAME: 1, PIx2: PY, START_VERTEX: 1 });
var wY = 0.000001;
function NY(e33) {
wY = e33;
}
function TY() {
return wY;
}
function RY(e33) {
return e33 < wY && e33 > -wY;
}
function EY(e33, t2) {
return e33 - t2 < wY && e33 - t2 > -wY;
}
function AY(e33, t2) {
return e33 - t2 > wY;
}
function OY(e33, t2) {
return e33 - t2 < -wY;
}
var kY = { Utils: Object.freeze({ __proto__: null, DECIMALS: 3, EQ: EY, EQ_0: RY, GE: function(e33, t2) {
return e33 - t2 > -wY;
}, GT: AY, LE: function(e33, t2) {
return e33 - t2 < wY;
}, LT: OY, getTolerance: TY, setTolerance: NY }), Errors: undefined, Matrix: undefined, Planar_set: undefined, Point: undefined, Vector: undefined, Line: undefined, Circle: undefined, Segment: undefined, Arc: undefined, Box: undefined, Edge: undefined, Face: undefined, Ray: undefined, Ray_shooting: undefined, Multiline: undefined, Polygon: undefined, Distance: undefined, Inversion: undefined };
for (let e33 in MY)
kY[e33] = MY[e33];
Object.defineProperty(kY, "DP_TOL", { get: function() {
return TY();
}, set: function(e33) {
NY(e33);
} });
var DY = 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");
}
};
kY.Errors = DY;
var LY = class {
constructor(e33, t2) {
this.first = e33, this.last = t2 || this.first;
}
[Symbol.iterator]() {
let e33;
return { next: () => (e33 = e33 ? e33.next : this.first, { value: e33, done: e33 === undefined }) };
}
get size() {
let e33 = 0;
for (let t2 of this)
e33++;
return e33;
}
toArray(e33 = undefined, t2 = undefined) {
let n2 = [], o2 = e33 || this.first, i2 = t2 || this.last, r2 = o2;
if (r2 === undefined)
return n2;
do {
n2.push(r2), r2 = r2.next;
} while (r2 !== i2.next);
return n2;
}
append(e33) {
return this.isEmpty() ? this.first = e33 : (e33.prev = this.last, this.last.next = e33), this.last = e33, this.last.next = undefined, this.first.prev = undefined, this;
}
insert(e33, t2) {
if (this.isEmpty())
this.first = e33, this.last = e33;
else if (t2 == null)
e33.next = this.first, this.first.prev = e33, this.first = e33;
else {
let n2 = t2.next;
t2.next = e33, n2 && (n2.prev = e33), e33.prev = t2, e33.next = n2, this.last === t2 && (this.last = e33);
}
return this.last.next = undefined, this.first.prev = undefined, this;
}
remove(e33) {
return e33 === this.first && e33 === this.last ? (this.first = undefined, this.last = undefined) : (e33.prev && (e33.prev.next = e33.next), e33.next && (e33.next.prev = e33.prev), e33 === this.first && (this.first = e33.next), e33 === this.last && (this.last = e33.prev)), this;
}
isEmpty() {
return this.first === undefined;
}
static testInfiniteLoop(e33) {
let t2 = e33, n2 = e33;
do {
if (t2 != e33 && t2 === n2)
throw DY.INFINITE_LOOP;
t2 = t2.next, n2 = n2.next.next;
} while (t2 != e33);
}
};
var zY = { stroke: "black" };
var BY = class {
constructor(e33 = zY) {
for (const t2 in e33)
this[t2] = e33[t2];
this.stroke = e33.stroke ?? zY.stroke;
}
toAttributesString() {
return Object.keys(this).reduce((e33, t2) => e33 + (this[t2] !== undefined ? this.toAttrString(t2, this[t2]) : ""), "");
}
toAttrString(e33, t2) {
const n2 = e33 === "className" ? "class" : this.convertCamelToKebabCase(e33);
return t2 === null ? `${n2} ` : `${n2}="${t2.toString()}" `;
}
convertCamelToKebabCase(e33) {
return e33.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 FY(e33) {
return new BY(e33).toAttributesString();
}
function jY(e33, t2) {
let n2 = [], [o2, i2, r2] = e33.standard, [s2, a2, c2] = t2.standard, l2 = o2 * a2 - i2 * s2, h2 = r2 * a2 - i2 * c2, d2 = o2 * c2 - r2 * s2;
if (!kY.Utils.EQ_0(l2)) {
let e34, t3;
i2 === 0 ? (e34 = r2 / o2, t3 = d2 / l2) : a2 === 0 ? (e34 = c2 / s2, t3 = d2 / l2) : o2 === 0 ? (e34 = h2 / l2, t3 = r2 / i2) : s2 === 0 ? (e34 = h2 / l2, t3 = c2 / a2) : (e34 = h2 / l2, t3 = d2 / l2), n2.push(new kY.Point(e34, t3));
}
return n2;
}
function $Y(e33, t2) {
let n2 = [], o2 = t2.pc.projectionOn(e33), i2 = t2.pc.distanceTo(o2)[0];
if (kY.Utils.EQ(i2, t2.r))
n2.push(o2);
else if (kY.Utils.LT(i2, t2.r)) {
let r2, s2, a2 = Math.sqrt(t2.r * t2.r - i2 * i2);
r2 = e33.norm.rotate90CCW().multiply(a2), s2 = o2.translate(r2), n2.push(s2), r2 = e33.norm.rotate90CW().multiply(a2), s2 = o2.translate(r2), n2.push(s2);
}
return n2;
}
function YY(e33, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = WY(o2, e33);
for (let e34 of t3)
cX(e34, n2) || n2.push(e34);
}
return n2;
}
function XY(e33, t2) {
let n2 = [];
if (YY(e33, t2.box).length === 0)
return n2;
let o2 = $Y(e33, new kY.Circle(t2.pc, t2.r));
for (let e34 of o2)
e34.on(t2) && n2.push(e34);
return n2;
}
function WY(e33, t2) {
let n2 = [];
return e33.ps.on(t2) && n2.push(e33.ps), e33.pe.on(t2) && !e33.isZeroLength() && n2.push(e33.pe), n2.length > 0 || e33.isZeroLength() || e33.ps.leftTo(t2) && e33.pe.leftTo(t2) || !e33.ps.leftTo(t2) && !e33.pe.leftTo(t2) ? n2 : jY(new kY.Line(e33.ps, e33.pe), t2);
}
function VY(e33, t2) {
let n2 = [];
if (e33.isZeroLength())
return e33.ps.on(t2) && n2.push(e33.ps), n2;
if (t2.isZeroLength())
return t2.ps.on(e33) && n2.push(t2.ps), n2;
let o2 = new kY.Line(e33.ps, e33.pe), i2 = new kY.Line(t2.ps, t2.pe);
if (o2.incidentTo(i2))
e33.ps.on(t2) && n2.push(e33.ps), e33.pe.on(t2) && n2.push(e33.pe), !t2.ps.on(e33) || t2.ps.equalTo(e33.ps) || t2.ps.equalTo(e33.pe) || n2.push(t2.ps), !t2.pe.on(e33) || t2.pe.equalTo(e33.ps) || t2.pe.equalTo(e33.pe) || n2.push(t2.pe);
else {
let r2 = jY(o2, i2);
r2.length > 0 && HY(r2[0], e33) && HY(r2[0], t2) && n2.push(r2[0]);
}
return n2;
}
function HY(e33, t2) {
const n2 = t2.box;
return kY.Utils.LE(e33.x, n2.xmax) && kY.Utils.GE(e33.x, n2.xmin) && kY.Utils.LE(e33.y, n2.ymax) && kY.Utils.GE(e33.y, n2.ymin);
}
function GY(e33, t2) {
let n2 = [];
if (e33.isZeroLength()) {
let [o3, i2] = e33.ps.distanceTo(t2.pc);
return kY.Utils.EQ(o3, t2.r) && n2.push(e33.ps), n2;
}
let o2 = $Y(new kY.Line(e33.ps, e33.pe), t2);
for (let t3 of o2)
t3.on(e33) && n2.push(t3);
return n2;
}
function UY(e33, t2) {
let n2 = [];
if (e33.isZeroLength())
return e33.ps.on(t2) && n2.push(e33.ps), n2;
let o2 = $Y(new kY.Line(e33.ps, e33.pe), new kY.Circle(t2.pc, t2.r));
for (let i2 of o2)
i2.on(e33) && i2.on(t2) && n2.push(i2);
return n2;
}
function ZY(e33, t2) {
let n2 = [], o2 = new kY.Vector(e33.pc, t2.pc), i2 = e33.r, r2 = t2.r;
if (kY.Utils.EQ_0(i2) || kY.Utils.EQ_0(r2))
return n2;
if (kY.Utils.EQ_0(o2.x) && kY.Utils.EQ_0(o2.y) && kY.Utils.EQ(i2, r2))
return n2.push(e33.pc.translate(-i2, 0)), n2;
let s2, a2 = e33.pc.distanceTo(t2.pc)[0];
if (kY.Utils.GT(a2, i2 + r2))
return n2;
if (kY.Utils.LT(a2, Math.abs(i2 - r2)))
return n2;
if (o2.x /= a2, o2.y /= a2, kY.Utils.EQ(a2, i2 + r2) || kY.Utils.EQ(a2, Math.abs(i2 - r2)))
return s2 = e33.pc.translate(i2 * o2.x, i2 * o2.y), n2.push(s2), n2;
let c2 = i2 * i2 / (2 * a2) - r2 * r2 / (2 * a2) + a2 / 2, l2 = e33.pc.translate(c2 * o2.x, c2 * o2.y), h2 = Math.sqrt(i2 * i2 - c2 * c2);
return s2 = l2.translate(o2.rotate90CCW().multiply(h2)), n2.push(s2), s2 = l2.translate(o2.rotate90CW().multiply(h2)), n2.push(s2), n2;
}
function qY(e33, t2) {
let n2 = [];
if (e33.pc.equalTo(t2.pc) && kY.Utils.EQ(e33.r, t2.r)) {
let o3;
return o3 = e33.start, o3.on(t2) && n2.push(o3), o3 = e33.end, o3.on(t2) && n2.push(o3), o3 = t2.start, o3.on(e33) && n2.push(o3), o3 = t2.end, o3.on(e33) && n2.push(o3), n2;
}
let o2 = new kY.Circle(e33.pc, e33.r), i2 = new kY.Circle(t2.pc, t2.r), r2 = o2.intersect(i2);
for (let o3 of r2)
o3.on(e33) && o3.on(t2) && n2.push(o3);
return n2;
}
function JY(e33, t2) {
let n2 = [];
if (t2.pc.equalTo(e33.pc) && kY.Utils.EQ(t2.r, e33.r))
return n2.push(e33.start), n2.push(e33.end), n2;
let o2 = ZY(t2, new kY.Circle(e33.pc, e33.r));
for (let t3 of o2)
t3.on(e33) && n2.push(t3);
return n2;
}
function QY(e33, t2) {
return e33.isSegment ? VY(e33.shape, t2) : UY(t2, e33.shape);
}
function KY(e33, t2) {
return e33.isSegment ? UY(e33.shape, t2) : qY(e33.shape, t2);
}
function eX(e33, t2) {
return e33.isSegment ? WY(e33.shape, t2) : XY(t2, e33.shape);
}
function tX(e33, t2) {
return e33.isSegment ? GY(e33.shape, t2) : JY(e33.shape, t2);
}
function nX(e33, t2) {
let n2 = [];
for (let o2 of t2.edges)
for (let t3 of QY(o2, e33))
n2.push(t3);
return n2;
}
function oX(e33, t2) {
let n2 = [];
for (let o2 of t2.edges)
for (let t3 of KY(o2, e33))
n2.push(t3);
return n2;
}
function iX(e33, t2) {
let n2 = [];
if (t2.isEmpty())
return n2;
for (let o2 of t2.edges)
for (let t3 of eX(o2, e33))
cX(t3, n2) || n2.push(t3);
return e33.sortPoints(n2);
}
function rX(e33, t2) {
let n2 = [];
if (t2.isEmpty())
return n2;
for (let o2 of t2.edges)
for (let t3 of tX(o2, e33))
n2.push(t3);
return n2;
}
function sX(e33, t2) {
return e33.isSegment ? QY(t2, e33.shape) : e33.isArc ? KY(t2, e33.shape) : e33.isLine ? eX(t2, e33.shape) : e33.isRay ? (n2 = t2, o2 = e33.shape, n2.isSegment ? hX(o2, n2.shape) : dX(o2, n2.shape)) : [];
var n2, o2;
}
function aX(e33, t2) {
let n2 = [];
if (t2.isEmpty() || e33.shape.box.not_intersect(t2.box))
return n2;
let o2 = t2.edges.search(e33.shape.box);
for (let t3 of o2)
n2 = [...n2, ...sX(e33, t3)];
return n2;
}
function cX(e33, t2) {
return t2.some((t3) => t3.equalTo(e33));
}
function lX(e33) {
return new kY.Line(e33.start, e33.norm);
}
function hX(e33, t2) {
return WY(t2, lX(e33)).filter((t3) => e33.contains(t3));
}
function dX(e33, t2) {
return XY(lX(e33), t2).filter((t3) => e33.contains(t3));
}
function uX(e33, t2) {
return $Y(lX(e33), t2).filter((t3) => e33.contains(t3));
}
function pX(e33, t2) {
return jY(lX(e33), t2).filter((t3) => e33.contains(t3));
}
function mX(e33, t2) {
return iX(lX(e33), t2).filter((t3) => e33.contains(t3));
}
function gX(e33, t2) {
if (e33.intersect && e33.intersect instanceof Function)
return e33.intersect(t2);
throw DY.UNSUPPORTED_SHAPE_TYPE;
}
function fX(e33, t2) {
let n2 = [];
for (let o2 of t2)
n2 = [...n2, ...gX(e33, o2.shape)];
return n2;
}
var _X = class e33 extends LY {
constructor(...e34) {
if (super(), this.isInfinite = false, e34.length === 1 && e34[0] instanceof Array && e34[0].length > 0) {
const t2 = e34[0], n2 = t2.length, o2 = (e35) => e35 instanceof kY.Segment || e35 instanceof kY.Arc || e35 instanceof kY.Ray, i2 = (e35) => e35 instanceof kY.Segment || e35 instanceof kY.Arc;
if (!(n2 === 1 && ((e35) => e35 instanceof kY.Segment || e35 instanceof kY.Arc || e35 instanceof kY.Ray || e35 instanceof kY.Line)(t2[0]) || n2 > 1 && o2(t2[0]) && o2(t2[n2 - 1]) && t2.slice(1, n2 - 1).every(i2)))
throw kY.Errors.ILLEGAL_PARAMETERS;
this.isInfinite = t2.some((e35) => e35 instanceof kY.Ray || e35 instanceof kY.Line);
for (let e35 of t2) {
let t3 = new kY.Edge(e35);
this.append(t3);
}
this.setArcLength();
}
}
get edges() {
return [...this];
}
get box() {
return this.edges.reduce((e34, t2) => e34.merge(t2.box), new kY.Box);
}
get vertices() {
let e34 = this.edges.map((e35) => e35.start);
return e34.push(this.last.end), e34;
}
get length() {
if (this.isEmpty())
return 0;
if (this.isInfinite)
return Number.POSITIVE_INFINITY;
let e34 = 0;
for (let t2 of this)
e34 += t2.length;
return e34;
}
clone() {
return new e33(this.toShapes());
}
setArcLength() {
for (let e34 of this)
this.setOneEdgeArcLength(e34);
}
setOneEdgeArcLength(e34) {
e34 === this.first ? e34.arc_length = 0 : e34.arc_length = e34.prev.arc_length + e34.prev.length;
}
pointAtLength(e34) {
if (e34 > this.length || e34 < 0)
return null;
if (this.isInfinite)
return null;
let t2 = null;
for (let n2 of this)
if (e34 >= n2.arc_length && (n2 === this.last || e34 < n2.next.arc_length)) {
t2 = n2.pointAtLength(e34 - n2.arc_length);
break;
}
return t2;
}
addVertex(e34, t2) {
let n2 = t2.shape.split(e34);
if (n2[0] === null)
return t2.prev;
if (n2[1] === null)
return t2;
let o2 = new kY.Edge(n2[0]), i2 = t2.prev;
return this.insert(o2, i2), t2.shape = n2[1], o2;
}
getChain(e34, t2) {
let n2 = [];
for (let o2 = e34;o2 !== t2.next; o2 = o2.next)
n2.push(o2);
return n2;
}
split(e34) {
for (let t2 of e34) {
let e35 = this.findEdgeByPoint(t2);
this.addVertex(t2, e35);
}
return this;
}
findEdgeByPoint(e34) {
let t2;
for (let n2 of this)
if (n2.shape.contains(e34)) {
t2 = n2;
break;
}
return t2;
}
distanceTo(e34) {
if (e34 instanceof Point) {
const [t2, n2] = kY.Distance.shape2multiline(e34, this);
return [t2, n2.reverse()];
}
if (e34 instanceof kY.Line) {
const [t2, n2] = kY.Distance.shape2multiline(e34, this);
return [t2, n2.reverse()];
}
if (e34 instanceof kY.Circle) {
const [t2, n2] = kY.Distance.shape2multiline(e34, this);
return [t2, n2.reverse()];
}
if (e34 instanceof kY.Segment) {
const [t2, n2] = kY.Distance.shape2multiline(e34, this);
return [t2, n2.reverse()];
}
if (e34 instanceof kY.Arc) {
const [t2, n2] = kY.Distance.shape2multiline(e34, this);
return [t2, n2.reverse()];
}
if (e34 instanceof kY.Multiline)
return kY.Distance.multiline2multiline(this, e34);
throw kY.Errors.UNSUPPORTED_SHAPE_TYPE;
}
intersect(e34) {
return e34 instanceof kY.Multiline ? function(e35, t2) {
let n2 = [];
for (let o2 of e35)
for (let e36 of t2)
n2 = [...n2, ...gX(o2.shape, e36.shape)];
return n2;
}(this, e34) : fX(e34, this);
}
contains(e34) {
if (e34 instanceof kY.Point)
return this.edges.some((t2) => t2.shape.contains(e34));
throw kY.Errors.UNSUPPORTED_SHAPE_TYPE;
}
translate(t2) {
return new e33(this.edges.map((e34) => e34.shape.translate(t2)));
}
rotate(t2 = 0, n2 = new kY.Point) {
return new e33(this.edges.map((e34) => e34.shape.rotate(t2, n2)));
}
transform(t2 = new kY.Matrix) {
return new e33(this.edges.map((e34) => e34.shape.transform(t2)));
}
toShapes() {
return this.edges.map((e34) => e34.shape.clone());
}
toJSON() {
return this.edges.map((e34) => e34.toJSON());
}
svgPoints() {
return this.vertices.map((e34) => `${e34.x},${e34.y}`).join(" ");
}
dpath() {
let e34 = `M${this.first.start.x},${this.first.start.y}`;
for (let t2 of this)
e34 += t2.svg();
return e34;
}
svg(e34 = {}) {
let t2 = `
<path ${FY({ fill: "none", ...e34 })} d="`;
t2 += `
M${this.first.start.x},${this.first.start.y}`;
for (let e35 of this)
t2 += e35.svg();
return t2 += `" >
</path>`, t2;
}
};
kY.Multiline = _X;
function yX(e34, t2, n2) {
let o2 = n2.length, i2 = e34.shape.split(t2);
if (i2.length === 0)
return;
let r2 = 0;
r2 = i2[0] === null ? 0 : i2[1] === null ? e34.shape.length : i2[0].length;
let s2, a2 = 0;
EY(r2, 0) && (a2 |= 1), EY(r2, e34.shape.length) && (a2 |= 2), s2 = r2 === 1 / 0 ? i2[0].coord(t2) : 2 & a2 && e34.next && e34.next.arc_length === 0 ? 0 : e34.arc_length + r2, n2.push({ id: o2, pt: t2, arc_length: s2, edge_before: e34, edge_after: undefined, face: e34.face, is_vertex: a2 });
}
function bX(e34) {
e34.int_points1_sorted = xX(e34.int_points1), e34.int_points2_sorted = xX(e34.int_points2);
}
function xX(e34) {
let t2 = new Map, n2 = 0;
for (let o2 of e34)
t2.has(o2.face) || (t2.set(o2.face, n2), n2++);
for (let n3 of e34)
n3.faceId = t2.get(n3.face);
return e34.slice().sort(vX);
}
function vX(e34, t2) {
return e34.faceId < t2.faceId ? -1 : e34.faceId > t2.faceId ? 1 : e34.arc_length < t2.arc_length ? -1 : e34.arc_length > t2.arc_length ? 1 : 0;
}
function IX(e34) {
if (e34.int_points1.length < 2)
return;
let t2, n2, o2, i2, r2 = false;
for (let s2 = 0;s2 < e34.int_points1_sorted.length; s2++)
if (e34.int_points1_sorted[s2].id !== -1) {
t2 = e34.int_points1_sorted[s2], n2 = e34.int_points2[t2.id];
for (let a2 = s2 + 1;a2 < e34.int_points1_sorted.length && (o2 = e34.int_points1_sorted[a2], EY(o2.arc_length, t2.arc_length)); a2++)
o2.id !== -1 && (i2 = e34.int_points2[o2.id], i2.id !== -1 && o2.edge_before === t2.edge_before && o2.edge_after === t2.edge_after && i2.edge_before === n2.edge_before && i2.edge_after === n2.edge_after && (o2.id = -1, i2.id = -1, r2 = true));
}
n2 = e34.int_points2_sorted[0], t2 = e34.int_points1[n2.id];
for (let o3 = 1;o3 < e34.int_points2_sorted.length; o3++) {
let i3 = e34.int_points2_sorted[o3];
if (i3.id === -1)
continue;
if (n2.id === -1 || !EY(i3.arc_length, n2.arc_length)) {
n2 = i3, t2 = e34.int_points1[n2.id];
continue;
}
let s2 = e34.int_points1[i3.id];
s2.edge_before === t2.edge_before && s2.edge_after === t2.edge_after && i3.edge_before === n2.edge_before && i3.edge_after === n2.edge_after && (s2.id = -1, i3.id = -1, r2 = true);
}
r2 && (e34.int_points1 = e34.int_points1.filter((e35) => e35.id >= 0), e34.int_points2 = e34.int_points2.filter((e35) => e35.id >= 0), e34.int_points1.forEach((e35, t3) => e35.id = t3), e34.int_points2.forEach((e35, t3) => e35.id = t3));
}
function SX(e34) {
for (let t2 of e34)
t2.edge_before && (t2.edge_before.bvStart = undefined, t2.edge_before.bvEnd = undefined, t2.edge_before.bv = undefined, t2.edge_before.overlap = undefined), t2.edge_after && (t2.edge_after.bvStart = undefined, t2.edge_after.bvEnd = undefined, t2.edge_after.bv = undefined, t2.edge_after.overlap = undefined);
for (let t2 of e34)
t2.edge_before && (t2.edge_before.bvEnd = 2), t2.edge_after && (t2.edge_after.bvStart = 2);
}
function CX(e34, t2) {
for (let n2 of e34)
n2.edge_before && n2.edge_before.setInclusion(t2), n2.edge_after && n2.edge_after.setInclusion(t2);
}
function PX(e34, t2, n2) {
let o2, i2, r2 = 1;
if (e34.length === 1)
return 1;
o2 = e34[t2];
for (let s2 = t2 + 1;s2 < e34.length && o2.face === n2 && (i2 = e34[s2], i2.pt.equalTo(o2.pt) && i2.edge_before === o2.edge_before && i2.edge_after === o2.edge_after); s2++)
r2++;
return r2;
}
function MX(e34, t2) {
if (t2) {
for (let n2 of t2) {
let t3 = n2.edge_before;
if (n2.is_vertex = 0, t3.shape.start && t3.shape.start.equalTo(n2.pt) && (n2.is_vertex |= 1), t3.shape.end && t3.shape.end.equalTo(n2.pt) && (n2.is_vertex |= 2), 1 & n2.is_vertex) {
n2.edge_before = t3.prev, t3.prev && (n2.is_vertex = 2);
continue;
}
if (2 & n2.is_vertex)
continue;
let o2 = e34.addVertex(n2.pt, t3);
n2.edge_before = o2;
}
for (let n2 of t2)
n2.edge_before ? n2.edge_after = n2.edge_before.next : e34 instanceof _X && 1 & n2.is_vertex && (n2.edge_after = e34.first);
}
}
function wX(e34, t2, n2) {
const o2 = e34.edge_before, i2 = t2.edge_after, r2 = n2.length;
o2.next = n2[0], n2[0].prev = o2, n2[r2 - 1].next = i2, i2.prev = n2[r2 - 1];
}
kY.multiline = (...e34) => new kY.Multiline(...e34);
var { INSIDE: NX, OUTSIDE: TX, BOUNDARY: RX, OVERLAP_SAME: EX, OVERLAP_OPPOSITE: AX } = MY;
var { NOT_VERTEX: OX, START_VERTEX: kX, END_VERTEX: DX } = MY;
function LX(e34, t2) {
let n2 = t2.clone().reverse(), [o2] = YX(e34, n2, 3, true);
return o2;
}
function zX(e34, t2) {
let [n2] = YX(e34, t2, 2, true);
return n2;
}
function BX(e34, t2) {
let [n2, o2] = YX(e34, t2, 2, false), i2 = [];
for (let e35 of n2.faces)
i2 = [...i2, ...[...e35.edges].map((e36) => e36.shape)];
let r2 = [];
for (let e35 of o2.faces)
r2 = [...r2, ...[...e35.edges].map((e36) => e36.shape)];
return [i2, r2];
}
function FX(e34, t2) {
let [n2] = YX(e34, t2, 3, false), i2 = [];
for (let e35 of n2.faces)
i2 = [...i2, ...[...e35.edges].map((e36) => e36.shape)];
return i2;
}
function jX(e34, t2) {
let n2 = e34.clone(), o2 = t2.clone(), i2 = XX(n2, o2);
return bX(i2), MX(n2, i2.int_points1_sorted), MX(o2, i2.int_points2_sorted), IX(i2), bX(i2), [i2.int_points1_sorted.map((e35) => e35.pt), i2.int_points2_sorted.map((e35) => e35.pt)];
}
function $X(e34, t2, n2, o2) {
let i2 = WX(e34, n2.int_points1), r2 = WX(t2, n2.int_points2);
for (VX(i2, t2), VX(r2, e34), SX(n2.int_points1), SX(n2.int_points2), CX(n2.int_points1, t2), CX(n2.int_points2, e34);HX(e34, t2, n2.int_points1, n2.int_points1_sorted, n2.int_points2, n2); )
;
((function(e35) {
let t3, n3, o3, i3 = e35.int_points1.length;
for (let r3 = 0;r3 < i3; r3++) {
let s2 = e35.int_points1_sorted[r3];
s2.face !== t3 && (n3 = r3, t3 = s2.face);
let a2, c2 = r3, l2 = PX(e35.int_points1_sorted, r3, t3);
a2 = c2 + l2 < i3 && e35.int_points1_sorted[c2 + l2].face === t3 ? c2 + l2 : n3;
let h2 = PX(e35.int_points1_sorted, a2, t3);
o3 = null;
for (let n4 = a2;n4 < a2 + h2; n4++) {
let i4 = e35.int_points1_sorted[n4];
if (i4.face === t3 && e35.int_points2[i4.id].face === e35.int_points2[s2.id].face) {
o3 = i4;
break;
}
}
if (o3 === null)
continue;
let d2 = s2.edge_after, u2 = o3.edge_before;
if (d2.bv !== 2 || u2.bv !== 2)
continue;
if (d2 !== u2)
continue;
let p2 = e35.int_points2[s2.id], m2 = e35.int_points2[o3.id], g2 = p2.edge_after, f2 = m2.edge_before;
g2.bv === 2 && f2.bv === 2 && g2 === f2 || (p2 = e35.int_points2[o3.id], m2 = e35.int_points2[s2.id], g2 = p2.edge_after, f2 = m2.edge_before), g2.bv === 2 && f2.bv === 2 && g2 === f2 && d2.setOverlap(g2);
}
}))(n2), GX(e34, o2, n2.int_points1_sorted, true), GX(t2, o2, n2.int_points2_sorted, false), qX(e34, i2, o2, true), qX(t2, r2, o2, false);
}
function YX(e34, t2, n2, o2) {
let i2 = e34.clone(), r2 = t2.clone(), s2 = XX(i2, r2);
return bX(s2), MX(i2, s2.int_points1_sorted), MX(r2, s2.int_points2_sorted), IX(s2), bX(s2), $X(i2, r2, s2, n2), o2 && function(e35, t3, n3) {
((function(e36, t4, n4, o3) {
for (let n5 of t4.faces) {
for (let t5 of n5)
e36.edges.add(t5);
o3.find((e37) => e37.face === n5) === undefined && e36.addFace(n5.first, n5.last);
}
}))(e35, t3, 0, n3.int_points2), function(e36, t4, n4) {
if (n4.int_points1.length !== 0)
for (let e37 = 0;e37 < n4.int_points1.length; e37++) {
let t5 = n4.int_points1[e37], o3 = n4.int_points2[e37];
if (t5.edge_before !== undefined && t5.edge_after === undefined && o3.edge_before === undefined && o3.edge_after !== undefined && (t5.edge_before.next = o3.edge_after, o3.edge_after.prev = t5.edge_before, t5.edge_after = o3.edge_after, o3.edge_before = t5.edge_before), o3.edge_before !== undefined && o3.edge_after === undefined && t5.edge_before === undefined && t5.edge_after !== undefined && (o3.edge_before.next = t5.edge_after, t5.edge_after.prev = o3.edge_before, o3.edge_after = t5.edge_after, t5.edge_before = o3.edge_before), t5.edge_before !== undefined && t5.edge_after === undefined)
for (let e38 of n4.int_points1_sorted)
e38 !== t5 && e38.edge_before === undefined && e38.edge_after !== undefined && e38.pt.equalTo(t5.pt) && (t5.edge_before.next = e38.edge_after, e38.edge_after.prev = t5.edge_before, t5.edge_after = e38.edge_after, e38.edge_before = t5.edge_before);
if (o3.edge_before !== undefined && o3.edge_after === undefined)
for (let e38 of n4.int_points2_sorted)
e38 !== o3 && e38.edge_before === undefined && e38.edge_after !== undefined && e38.pt.equalTo(o3.pt) && (o3.edge_before.next = e38.edge_after, e38.edge_after.prev = o3.edge_before, o3.edge_after = e38.edge_after, e38.edge_before = o3.edge_before);
}
}(0, 0, n3), UX(e35, n3.int_points1), UX(t3, n3.int_points2), ZX(e35, n3.int_points1, n3.int_points2), ZX(e35, n3.int_points2, n3.int_points1);
}(i2, r2, s2), [i2, r2];
}
function XX(e34, t2) {
let n2 = { int_points1: [], int_points2: [] };
for (let o2 of e34.edges) {
let e35 = t2.edges.search(o2.box);
for (let t3 of e35) {
let e36 = o2.shape.intersect(t3.shape);
for (let i2 of e36)
yX(o2, i2, n2.int_points1), yX(t3, i2, n2.int_points2);
}
}
return n2;
}
function WX(e34, t2) {
let n2 = [];
for (let o2 of e34.faces)
t2.find((e35) => e35.face === o2) || n2.push(o2);
return n2;
}
function VX(e34, t2) {
for (let n2 of e34)
n2.first.bv = n2.first.bvStart = n2.first.bvEnd = undefined, n2.first.setInclusion(t2);
}
function HX(e34, t2, n2, o2, i2, r2) {
let s2, a2, c2, l2 = o2.length, h2 = false;
for (let d2 = 0;d2 < l2; d2++) {
let u2 = o2[d2];
u2.face !== s2 && (a2 = d2, s2 = u2.face);
let p2, m2 = d2, g2 = PX(o2, d2, s2);
p2 = m2 + g2 < l2 && o2[m2 + g2].face === s2 ? m2 + g2 : a2;
let f2 = PX(o2, p2, s2);
c2 = null;
for (let e35 = p2;e35 < p2 + f2; e35++) {
let t3 = o2[e35];
if (t3.face === s2 && i2[t3.id].face === i2[u2.id].face) {
c2 = t3;
break;
}
}
if (c2 === null)
continue;
let _2 = u2.edge_after, y2 = c2.edge_before;
if (_2.bv !== RX || y2.bv == RX)
if (_2.bv == RX || y2.bv !== RX) {
if (_2.bv === RX && y2.bv === RX && _2 != y2 || _2.bv === NX && y2.bv === TX || _2.bv === TX && y2.bv === NX) {
let e35 = _2.next;
for (;e35 != y2; )
e35.bvStart = undefined, e35.bvEnd = undefined, e35.bv = undefined, e35.setInclusion(t2), e35 = e35.next;
}
if (_2.bv === RX && y2.bv === RX && _2 != y2) {
let e35, t3 = _2.next;
for (;t3 != y2; ) {
if (t3.bv != RX) {
if (e35 === undefined)
e35 = t3.bv;
else if (t3.bv != e35)
throw DY.UNRESOLVED_BOUNDARY_CONFLICT;
}
t3 = t3.next;
}
e35 != null && (_2.bv = e35, y2.bv = e35);
continue;
}
if (_2.bv === NX && y2.bv === TX || _2.bv === TX && y2.bv === NX) {
let o3 = _2;
for (;o3 != y2; ) {
if (o3.bvStart === _2.bv && o3.bvEnd === y2.bv) {
let [s3, a3] = o3.shape.distanceTo(t2);
if (s3 < 10 * kY.DP_TOL) {
yX(o3, a3.ps, n2);
let s4 = n2[n2.length - 1];
if (s4.is_vertex & kX)
s4.edge_after = o3, s4.edge_before = o3.prev, o3.bvStart = RX, o3.bv = undefined, o3.setInclusion(t2);
else if (s4.is_vertex & DX)
s4.edge_after = o3.next, o3.bvEnd = RX, o3.bv = undefined, o3.setInclusion(t2);
else {
let e35 = t2.addVertex(s4.pt, o3);
s4.edge_before = e35, s4.edge_after = e35.next, e35.setInclusion(t2), e35.next.bvStart = RX, e35.next.bvEnd = undefined, e35.next.bv = undefined, e35.next.setInclusion(t2);
}
let c3 = t2.findEdgeByPoint(a3.pe);
yX(c3, a3.pe, i2);
let l3 = i2[i2.length - 1];
if (l3.is_vertex & kX)
l3.edge_after = c3, l3.edge_before = c3.prev;
else if (l3.is_vertex & DX)
l3.edge_after = c3.next;
else {
let n3 = i2.find((e35) => e35.edge_after === c3), o4 = t2.addVertex(l3.pt, c3);
l3.edge_before = o4, l3.edge_after = o4.next, n3 && (n3.edge_after = o4), o4.bvStart = undefined, o4.bvEnd = RX, o4.bv = undefined, o4.setInclusion(e34), o4.next.bvStart = RX, o4.next.bvEnd = undefined, o4.next.bv = undefined, o4.next.setInclusion(e34);
}
bX(r2), h2 = true;
break;
}
}
o3 = o3.next;
}
if (h2)
break;
throw DY.UNRESOLVED_BOUNDARY_CONFLICT;
}
} else
y2.bv = _2.bv;
else
_2.bv = y2.bv;
}
return h2;
}
function GX(e34, t2, n2, o2) {
if (!n2)
return;
let i2, r2, s2, a2;
for (let c2 = 0;c2 < n2.length; c2++) {
if (s2 = n2[c2], s2.face !== i2 && (r2 = c2, i2 = s2.face), i2.isEmpty())
continue;
let l2, h2 = c2, d2 = PX(n2, c2, i2);
l2 = h2 + d2 < n2.length && n2[h2 + d2].face === s2.face ? h2 + d2 : r2, a2 = n2[l2];
let u2 = l2, p2 = PX(n2, u2, i2), m2 = s2.edge_after, g2 = a2.edge_before;
if (m2.bv === NX && g2.bv === NX && t2 === 1 || m2.bv === TX && g2.bv === TX && t2 === 2 || (m2.bv === TX || g2.bv === TX) && t2 === 3 && !o2 || (m2.bv === NX || g2.bv === NX) && t2 === 3 && o2 || m2.bv === RX && g2.bv === RX && m2.overlap & EX && o2 || m2.bv === RX && g2.bv === RX && m2.overlap & AX) {
e34.removeChain(i2, m2, g2);
for (let e35 = h2;e35 < h2 + d2; e35++)
n2[e35].edge_after = undefined;
for (let e35 = u2;e35 < u2 + p2; e35++)
n2[e35].edge_before = undefined;
}
c2 += d2 - 1;
}
}
function UX(e34, t2) {
for (let n2 of t2)
e34.faces.delete(n2.face), n2.face = undefined, n2.edge_before && (n2.edge_before.face = undefined), n2.edge_after && (n2.edge_after.face = undefined);
}
function ZX(e34, t2, n2) {
for (let o2 of t2) {
if (o2.edge_before === undefined || o2.edge_after === undefined)
continue;
if (o2.face)
continue;
if (o2.edge_after.face || o2.edge_before.face)
continue;
let { edge_after: i2, edge_before: r2 } = o2;
try {
LY.testInfiniteLoop(i2);
} catch (e35) {
throw DY.CANNOT_COMPLETE_BOOLEAN_OPERATION;
}
let s2 = e34.addFace(i2, r2);
for (let e35 of t2)
e35.edge_before && e35.edge_after && e35.edge_before.face === s2 && e35.edge_after.face === s2 && (e35.face = s2);
for (let e35 of n2)
e35.edge_before && e35.edge_after && e35.edge_before.face === s2 && e35.edge_after.face === s2 && (e35.face = s2);
}
}
function qX(e34, t2, n2, o2) {
for (let i2 of t2) {
let t3 = i2.first.bv;
(n2 === 1 && t3 === NX || n2 === 3 && t3 === NX && o2 || n2 === 3 && t3 === TX && !o2 || n2 === 2 && t3 === TX) && e34.deleteFace(i2);
}
}
var JX = Object.freeze({ __proto__: null, BOOLEAN_INTERSECT: 2, BOOLEAN_SUBTRACT: 3, BOOLEAN_UNION: 1, calculateIntersections: jX, innerClip: BX, intersect: zX, outerClip: FX, removeNotRelevantChains: GX, removeOldFaces: UX, restoreFaces: ZX, subtract: LX, unify: function(e34, t2) {
let [n2] = YX(e34, t2, 1, true);
return n2;
} });
var QX = RegExp("T.F..FFF.|T.F...F..");
var KX = RegExp("T........|.T.......|...T.....|....T....");
var eW = RegExp("FT.......|F..T.....|F...T....");
var tW = RegExp("T.F..F...");
var nW = RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF...");
var oW = class {
constructor() {
this.m = new Array(9).fill(undefined);
}
get I2I() {
return this.m[0];
}
set I2I(e34) {
this.m[0] = e34;
}
get I2B() {
return this.m[1];
}
set I2B(e34) {
this.m[1] = e34;
}
get I2E() {
return this.m[2];
}
set I2E(e34) {
this.m[2] = e34;
}
get B2I() {
return this.m[3];
}
set B2I(e34) {
this.m[3] = e34;
}
get B2B() {
return this.m[4];
}
set B2B(e34) {
this.m[4] = e34;
}
get B2E() {
return this.m[5];
}
set B2E(e34) {
this.m[5] = e34;
}
get E2I() {
return this.m[6];
}
set E2I(e34) {
this.m[6] = e34;
}
get E2B() {
return this.m[7];
}
set E2B(e34) {
this.m[7] = e34;
}
get E2E() {
return this.m[8];
}
set E2E(e34) {
this.m[8] = e34;
}
toString() {
return this.m.map((e34) => e34 instanceof Array && e34.length > 0 ? "T" : e34 instanceof Array && e34.length === 0 ? "F" : "*").join("");
}
equal() {
return QX.test(this.toString());
}
intersect() {
return KX.test(this.toString());
}
touch() {
return eW.test(this.toString());
}
inside() {
return tW.test(this.toString());
}
covered() {
return nW.test(this.toString());
}
};
function iW(e34, t2) {
let n2, o2 = new kY.Ray(t2), i2 = new kY.Line(o2.pt, o2.norm);
const r2 = new kY.Box(o2.box.xmin - kY.DP_TOL, o2.box.ymin - kY.DP_TOL, o2.box.xmax + kY.DP_TOL, o2.box.ymax + kY.DP_TOL);
if (e34.box.not_intersect(r2))
return kY.OUTSIDE;
let s2 = e34.edges.search(r2);
if (s2.length === 0)
return kY.OUTSIDE;
for (let e35 of s2)
if (e35.shape.contains(t2))
return kY.BOUNDARY;
let a2 = [...e34.faces], c2 = [];
for (let e35 of s2)
for (let n3 of o2.intersect(e35.shape)) {
if (n3.equalTo(t2))
return kY.BOUNDARY;
c2.push({ pt: n3, edge: e35, face_index: a2.indexOf(e35.face) });
}
c2.sort((e35, t3) => OY(e35.pt.x, t3.pt.x) ? -1 : AY(e35.pt.x, t3.pt.x) ? 1 : e35.face_index < t3.face_index ? -1 : e35.face_index > t3.face_index ? 1 : e35.edge.arc_length < t3.edge.arc_length ? -1 : e35.edge.arc_length > t3.edge.arc_length ? 1 : 0);
let l2 = 0;
for (let e35 = 0;e35 < c2.length; e35++) {
let t3 = c2[e35];
if (t3.pt.equalTo(t3.edge.shape.start)) {
if (e35 > 0 && t3.pt.equalTo(c2[e35 - 1].pt) && t3.face_index === c2[e35 - 1].face_index && t3.edge.prev === c2[e35 - 1].edge)
continue;
let n3 = t3.edge.prev;
for (;RY(n3.length); )
n3 = n3.prev;
let o3 = n3.shape.tangentInEnd(), r3 = t3.pt.translate(o3), s3 = t3.edge.shape.tangentInStart(), a3 = t3.pt.translate(s3), h2 = r3.leftTo(i2), d2 = a3.leftTo(i2);
(h2 && !d2 || !h2 && d2) && l2++;
} else if (t3.pt.equalTo(t3.edge.shape.end)) {
if (e35 > 0 && t3.pt.equalTo(c2[e35 - 1].pt) && t3.face_index === c2[e35 - 1].face_index && t3.edge.next === c2[e35 - 1].edge)
continue;
let n3 = t3.edge.next;
for (;RY(n3.length); )
n3 = n3.next;
let o3 = n3.shape.tangentInStart(), r3 = t3.pt.translate(o3), s3 = t3.edge.shape.tangentInEnd(), a3 = t3.pt.translate(s3), h2 = r3.leftTo(i2), d2 = a3.leftTo(i2);
(h2 && !d2 || !h2 && d2) && l2++;
} else if (t3.edge.shape instanceof kY.Segment)
l2++;
else {
let e36 = t3.edge.shape.box;
EY(t3.pt.y, e36.ymin) || EY(t3.pt.y, e36.ymax) || l2++;
}
}
return n2 = l2 % 2 == 1 ? 1 : 0, n2;
}
function rW(e34, t2) {
return lW(e34, t2).intersect();
}
function sW(e34, t2) {
return lW(e34, t2).inside();
}
function aW(e34, t2) {
return lW(e34, t2).covered();
}
function cW(e34, t2) {
return aW(t2, e34);
}
function lW(e34, t2) {
return e34 instanceof kY.Line && t2 instanceof kY.Line ? function(e35, t3) {
let n2 = new oW, o2 = jY(e35, t3);
o2.length === 0 ? e35.contains(t3.pt) && t3.contains(e35.pt) ? (n2.I2I = [e35], n2.I2E = [], n2.E2I = []) : (n2.I2I = [], n2.I2E = [e35], n2.E2I = [t3]) : (n2.I2I = o2, n2.I2E = e35.split(o2), n2.E2I = t3.split(o2));
return n2;
}(e34, t2) : e34 instanceof kY.Line && t2 instanceof kY.Circle ? function(e35, t3) {
let n2 = new oW, o2 = $Y(e35, t3);
if (o2.length === 0)
n2.I2I = [], n2.I2B = [], n2.I2E = [e35], n2.E2I = [t3];
else if (o2.length === 1)
n2.I2I = [], n2.I2B = o2, n2.I2E = e35.split(o2), n2.E2I = [t3];
else {
let i2 = new _X([e35]), r2 = e35.sortPoints(o2);
i2.split(r2);
let s2 = i2.toShapes();
n2.I2I = [s2[1]], n2.I2B = r2, n2.I2E = [s2[0], s2[2]], n2.E2I = new kY.Polygon([t3.toArc()]).cutWithLine(e35);
}
return n2;
}(e34, t2) : e34 instanceof kY.Line && t2 instanceof kY.Box ? function(e35, t3) {
let n2 = new oW, o2 = YY(e35, t3);
if (o2.length === 0)
n2.I2I = [], n2.I2B = [], n2.I2E = [e35], n2.E2I = [t3];
else if (o2.length === 1)
n2.I2I = [], n2.I2B = o2, n2.I2E = e35.split(o2), n2.E2I = [t3];
else {
let i2 = new _X([e35]), r2 = e35.sortPoints(o2);
i2.split(r2);
let s2 = i2.toShapes();
t3.toSegments().some((e36) => e36.contains(o2[0]) && e36.contains(o2[1])) ? (n2.I2I = [], n2.I2B = [s2[1]], n2.I2E = [s2[0], s2[2]], n2.E2I = [t3]) : (n2.I2I = [s2[1]], n2.I2B = r2, n2.I2E = [s2[0], s2[2]], n2.E2I = new kY.Polygon(t3.toSegments()).cutWithLine(e35));
}
return n2;
}(e34, t2) : e34 instanceof kY.Line && t2 instanceof kY.Polygon ? function(e35, t3) {
let n2 = new oW, o2 = iX(e35, t3), i2 = new _X([e35]), r2 = o2.length > 0 ? o2.slice() : e35.sortPoints(o2);
return i2.split(r2), [...i2].forEach((e36) => e36.setInclusion(t3)), n2.I2I = [...i2].filter((e36) => e36.bv === kY.INSIDE).map((e36) => e36.shape), n2.I2B = [...i2].slice(1).map((e36) => e36.bv === kY.BOUNDARY ? e36.shape : e36.shape.start), n2.I2E = [...i2].filter((e36) => e36.bv === kY.OUTSIDE).map((e36) => e36.shape), n2.E2I = t3.cutWithLine(e35), n2;
}(e34, t2) : (e34 instanceof kY.Segment || e34 instanceof kY.Arc) && t2 instanceof kY.Polygon ? hW(e34, t2) : (e34 instanceof kY.Segment || e34 instanceof kY.Arc) && (t2 instanceof kY.Circle || t2 instanceof kY.Box) ? hW(e34, new kY.Polygon(t2)) : e34 instanceof kY.Polygon && t2 instanceof kY.Polygon ? dW(e34, t2) : (e34 instanceof kY.Circle || e34 instanceof kY.Box) && (t2 instanceof kY.Circle || t2 instanceof kY.Box) ? dW(new kY.Polygon(e34), new kY.Polygon(t2)) : (e34 instanceof kY.Circle || e34 instanceof kY.Box) && t2 instanceof kY.Polygon ? dW(new kY.Polygon(e34), t2) : e34 instanceof kY.Polygon && (t2 instanceof kY.Circle || t2 instanceof kY.Box) ? dW(e34, new kY.Polygon(t2)) : undefined;
}
function hW(e34, t2) {
let n2 = new oW, o2 = function(e35, t3) {
return e35 instanceof kY.Line ? iX(e35, t3) : e35 instanceof kY.Segment ? nX(e35, t3) : e35 instanceof kY.Arc ? oX(e35, t3) : [];
}(e34, t2), i2 = o2.length > 0 ? o2.slice() : e34.sortPoints(o2), r2 = new _X([e34]);
r2.split(i2), [...r2].forEach((e35) => e35.setInclusion(t2)), n2.I2I = [...r2].filter((e35) => e35.bv === kY.INSIDE).map((e35) => e35.shape), n2.I2B = [...r2].slice(1).map((e35) => e35.bv === kY.BOUNDARY ? e35.shape : e35.shape.start), n2.I2E = [...r2].filter((e35) => e35.bv === kY.OUTSIDE).map((e35) => e35.shape), n2.B2I = [], n2.B2B = [], n2.B2E = [];
for (let o3 of [e34.start, e34.end])
switch (iW(t2, o3)) {
case kY.INSIDE:
n2.B2I.push(o3);
break;
case kY.BOUNDARY:
n2.B2B.push(o3);
break;
case kY.OUTSIDE:
n2.B2E.push(o3);
}
return n2;
}
function dW(e34, t2) {
let n2 = new oW, [o2, i2] = jX(e34, t2), r2 = zX(e34, t2), s2 = LX(e34, t2), a2 = LX(t2, e34), [c2, l2] = BX(e34, t2), h2 = FX(e34, t2), d2 = FX(t2, e34);
return n2.I2I = r2.isEmpty() ? [] : [r2], n2.I2B = l2, n2.I2E = s2.isEmpty() ? [] : [s2], n2.B2I = c2, n2.B2B = o2, n2.B2E = h2, n2.E2I = a2.isEmpty() ? [] : [a2], n2.E2B = d2, n2;
}
var uW = Object.freeze({ __proto__: null, contain: function(e34, t2) {
return sW(t2, e34);
}, cover: cW, covered: aW, disjoint: function(e34, t2) {
return !rW(e34, t2);
}, equal: function(e34, t2) {
return lW(e34, t2).equal();
}, inside: sW, intersect: rW, relate: lW, touch: function(e34, t2) {
return lW(e34, t2).touch();
} });
var pW = class e34 {
constructor(e35 = 1, t2 = 0, n2 = 0, o2 = 1, i2 = 0, r2 = 0) {
this.a = e35, this.b = t2, this.c = n2, this.d = o2, this.tx = i2, this.ty = r2;
}
fromMatrix3x3(t2) {
const [n2, o2, i2] = t2[0], [r2, s2, a2] = t2[1];
return new e34(n2, r2, o2, s2, i2, a2);
}
toMatrix3x3() {
return [[this.a, this.c, this.tx], [this.b, this.d, this.ty], [0, 0, 1]];
}
clone() {
return new e34(this.a, this.b, this.c, this.d, this.tx, this.ty);
}
transform(e35) {
return [e35[0] * this.a + e35[1] * this.c + this.tx, e35[0] * this.b + e35[1] * this.d + this.ty];
}
multiply(t2) {
return new e34(this.a * t2.a + this.c * t2.b, this.b * t2.a + this.d * t2.b, this.a * t2.c + this.c * t2.d, this.b * t2.c + this.d * t2.d, this.a * t2.tx + this.c * t2.ty + this.tx, this.b * t2.tx + this.d * t2.ty + this.ty);
}
translate(...t2) {
let n2, o2;
if (t2.length != 1 || isNaN(t2[0].x) || isNaN(t2[0].y)) {
if (t2.length !== 2 || typeof t2[0] != "number" || typeof t2[1] != "number")
throw DY.ILLEGAL_PARAMETERS;
n2 = t2[0], o2 = t2[1];
} else
n2 = t2[0].x, o2 = t2[0].y;
return this.multiply(new e34(1, 0, 0, 1, n2, o2));
}
rotate(t2, n2 = 0, o2 = 0) {
let i2 = Math.cos(t2), r2 = Math.sin(t2);
return this.translate(n2, o2).multiply(new e34(i2, r2, -r2, i2, 0, 0)).translate(-n2, -o2);
}
scale(t2, n2) {
return this.multiply(new e34(t2, 0, 0, n2, 0, 0));
}
equalTo(e35) {
return !!kY.Utils.EQ(this.tx, e35.tx) && (!!kY.Utils.EQ(this.ty, e35.ty) && (!!kY.Utils.EQ(this.a, e35.a) && (!!kY.Utils.EQ(this.b, e35.b) && (!!kY.Utils.EQ(this.c, e35.c) && !!kY.Utils.EQ(this.d, e35.d)))));
}
};
kY.Matrix = pW;
kY.matrix = (...e35) => new kY.Matrix(...e35);
var mW = class {
constructor(e35, t2) {
this.low = e35, this.high = t2;
}
get max() {
return this.clone();
}
less_than(e35) {
return this.low < e35.low || this.low === e35.low && this.high < e35.high;
}
equal_to(e35) {
return this.low === e35.low && this.high === e35.high;
}
intersect(e35) {
return !this.not_intersect(e35);
}
not_intersect(e35) {
return this.high < e35.low || e35.high < this.low;
}
merge(e35) {
const t2 = this.low === undefined ? e35.low : this.low < e35.low ? this.low : e35.low, n2 = this.high === undefined ? e35.high : this.high > e35.high ? this.high : e35.high, o2 = this.clone();
return o2.low = t2, o2.high = n2, o2;
}
output() {
return [this.low, this.high];
}
comparable_less_than(e35, t2) {
return e35 < t2;
}
};
var gW = class e35 extends mW {
clone() {
return new e35(this.low, this.high);
}
};
var fW = class {
constructor(e36, t2, n2 = null, o2 = null, i2 = null, r2 = 0) {
if (this.left = n2, this.right = o2, this.parent = i2, this.color = r2, this.item = { key: undefined, values: [] }, t2 !== undefined && this.item.values.push(t2), e36 !== undefined)
if (Array.isArray(e36)) {
const [t3, n3] = e36;
if (!Number.isNaN(t3) && !Number.isNaN(n3)) {
let e37 = t3, o3 = n3;
e37 > o3 && ([e37, o3] = [o3, e37]), this.item.key = new gW(e37, o3);
}
} else
this.item.key = e36;
this.max = this.item.key ? this.item.key.max : undefined;
}
isNil() {
return this.item.key === undefined && this.item.values.length === 0 && this.left === null && this.right === null && this.color === 0;
}
requireKey() {
if (!this.item.key)
throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");
return this.item.key;
}
less_than(e36) {
const t2 = this.requireKey(), n2 = e36.requireKey();
return t2.less_than(n2);
}
_value_equal(e36) {
const t2 = this.item.values[0], n2 = e36.item.values[0];
return t2 && n2 && t2.equal_to ? t2.equal_to(n2) : t2 === n2;
}
equal_to(e36) {
const t2 = this.requireKey(), n2 = e36.requireKey();
return t2.equal_to(n2);
}
intersect(e36) {
const t2 = this.requireKey(), n2 = e36.requireKey();
return t2.intersect(n2);
}
copy_data(e36) {
this.item.key = e36.item.key, this.item.values = e36.item.values.slice();
}
update_max() {
this.max = this.item.key ? this.item.key.max : undefined, 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(e36) {
if (!this.left)
return true;
const t2 = this.left.max ? this.left.max.high : this.left.item.key.high, n2 = this.requireKey(), o2 = e36.requireKey();
return n2.comparable_less_than(t2, o2.low);
}
not_intersect_right_subtree(e36) {
if (!this.right)
return true;
const t2 = this.right.max ? this.right.max.low : this.right.item.key.low, n2 = this.requireKey(), o2 = e36.requireKey();
return n2.comparable_less_than(o2.high, t2);
}
};
var _W = class e36 {
constructor() {
this.root = null, this.nil_node = new fW;
}
get size() {
let e37 = 0;
return this.tree_walk(this.root, (t2) => e37 += t2.item.values.length), e37;
}
get keys() {
const e37 = [];
return this.tree_walk(this.root, (t2) => e37.push(t2.item.key.output())), e37;
}
get values() {
const e37 = [];
return this.tree_walk(this.root, (t2) => {
for (const n2 of t2.item.values)
e37.push(n2);
}), e37;
}
get items() {
const e37 = [];
return this.tree_walk(this.root, (t2) => {
const n2 = t2.item.key.output();
for (const o2 of t2.item.values)
e37.push({ key: n2, value: o2 });
}), e37;
}
isEmpty() {
return this.root == null || this.root === this.nil_node;
}
clear() {
this.root = null;
}
insert(e37, t2 = e37) {
if (e37 === undefined)
return;
const n2 = this.tree_search(this.root, new fW(e37));
if (n2)
return n2.item.values.push(t2), n2;
const o2 = new fW(e37, t2, this.nil_node, this.nil_node, null, 1);
return this.tree_insert(o2), this.recalc_max(o2), o2;
}
exist(e37, t2 = e37) {
const n2 = this.tree_search(this.root, new fW(e37));
return !!n2 && (arguments.length < 2 || t2 === e37 || n2.item.values.some((e38) => e38 && e38.equal_to ? e38.equal_to(t2) : e38 === t2));
}
remove(e37, t2 = e37) {
const n2 = this.tree_search(this.root, new fW(e37));
if (!n2)
return;
if (arguments.length < 2)
return this.tree_delete(n2), n2;
const o2 = n2.item.values.findIndex((e38) => e38 && e38.equal_to ? e38.equal_to(t2) : e38 === t2);
return o2 >= 0 ? (n2.item.values.splice(o2, 1), n2.item.values.length === 0 && this.tree_delete(n2), n2) : undefined;
}
search(e37, t2 = (e38, t3) => e38 === t3 ? t3.output() : e38) {
const n2 = new fW(e37), o2 = [];
this.tree_search_interval(this.root, n2, o2);
const i2 = [];
for (const e38 of o2)
for (const n3 of e38.item.values)
i2.push(t2(n3, e38.item.key));
return i2;
}
intersect_any(e37) {
const t2 = new fW(e37);
return this.tree_find_any_interval(this.root, t2);
}
forEach(e37) {
this.tree_walk(this.root, (t2) => {
for (const n2 of t2.item.values)
e37(t2.item.key, n2);
});
}
map(t2) {
const n2 = new e36;
return this.tree_walk(this.root, (e37) => {
for (const o2 of e37.item.values)
n2.insert(e37.item.key, t2(o2, e37.item.key));
}), n2;
}
*iterate(e37, t2 = (e38, t3) => e38 === t3 ? t3.output() : e38) {
let n2 = null;
for (e37 ? n2 = this.tree_search_nearest_forward(this.root, new fW(e37)) : this.root && (n2 = this.local_minimum(this.root));n2; ) {
for (const e38 of n2.item.values)
yield t2(e38, n2.item.key);
n2 = this.tree_successor(n2);
}
}
recalc_max(e37) {
let t2 = e37;
for (;t2.parent != null; )
t2.parent.update_max(), t2 = t2.parent;
}
tree_insert(e37) {
let t2 = this.root, n2 = null;
if (this.root == null || this.root === this.nil_node)
this.root = e37;
else {
for (;t2 !== this.nil_node; )
n2 = t2, t2 = e37.less_than(t2) ? t2.left : t2.right;
e37.parent = n2, e37.less_than(n2) ? n2.left = e37 : n2.right = e37;
}
this.insert_fixup(e37);
}
insert_fixup(e37) {
let t2, n2;
for (t2 = e37;t2 !== this.root && t2.parent.color === 1; )
t2.parent === t2.parent.parent.left ? (n2 = t2.parent.parent.right, n2.color === 1 ? (t2.parent.color = 0, n2.color = 0, t2.parent.parent.color = 1, t2 = t2.parent.parent) : (t2 === t2.parent.right && (t2 = t2.parent, this.rotate_left(t2)), t2.parent.color = 0, t2.parent.parent.color = 1, this.rotate_right(t2.parent.parent))) : (n2 = t2.parent.parent.left, n2.color === 1 ? (t2.parent.color = 0, n2.color = 0, t2.parent.parent.color = 1, t2 = t2.parent.parent) : (t2 === t2.parent.left && (t2 = t2.parent, this.rotate_right(t2)), t2.parent.color = 0, t2.parent.parent.color = 1, this.rotate_left(t2.parent.parent)));
this.root.color = 0;
}
tree_delete(e37) {
let t2, n2;
t2 = e37.left === this.nil_node || e37.right === this.nil_node ? e37 : this.tree_successor(e37), n2 = t2.left !== this.nil_node ? t2.left : t2.right, n2.parent = t2.parent, t2 === this.root ? this.root = n2 : (t2 === t2.parent.left ? t2.parent.left = n2 : t2.parent.right = n2, t2.parent.update_max()), this.recalc_max(n2), t2 !== e37 && (e37.copy_data(t2), e37.update_max(), this.recalc_max(e37)), t2.color === 0 && this.delete_fixup(n2);
}
delete_fixup(e37) {
let t2, n2 = e37;
for (;n2 !== this.root && n2.parent != null && n2.color === 0; )
n2 === n2.parent.left ? (t2 = n2.parent.right, t2.color === 1 && (t2.color = 0, n2.parent.color = 1, this.rotate_left(n2.parent), t2 = n2.parent.right), t2.left.color === 0 && t2.right.color === 0 ? (t2.color = 1, n2 = n2.parent) : (t2.right.color === 0 && (t2.color = 1, t2.left.color = 0, this.rotate_right(t2), t2 = n2.parent.right), t2.color = n2.parent.color, n2.parent.color = 0, t2.right.color = 0, this.rotate_left(n2.parent), n2 = this.root)) : (t2 = n2.parent.left, t2.color === 1 && (t2.color = 0, n2.parent.color = 1, this.rotate_right(n2.parent), t2 = n2.parent.left), t2.left.color === 0 && t2.right.color === 0 ? (t2.color = 1, n2 = n2.parent) : (t2.left.color === 0 && (t2.color = 1, t2.right.color = 0, this.rotate_left(t2), t2 = n2.parent.left), t2.color = n2.parent.color, n2.parent.color = 0, t2.left.color = 0, this.rotate_right(n2.parent), n2 = this.root));
n2.color = 0;
}
tree_search(e37, t2) {
if (e37 != null && e37 !== this.nil_node)
return t2.equal_to(e37) ? e37 : t2.less_than(e37) ? this.tree_search(e37.left, t2) : this.tree_search(e37.right, t2);
}
tree_search_nearest_forward(e37, t2) {
let n2 = null, o2 = e37;
for (;o2 && o2 !== this.nil_node; )
o2.less_than(t2) ? o2.intersect(t2) ? (n2 = o2, o2 = o2.left) : o2 = o2.right : (n2 && !o2.less_than(n2) || (n2 = o2), o2 = o2.left);
return n2 || null;
}
tree_search_interval(e37, t2, n2) {
e37 != null && e37 !== this.nil_node && (e37.left === this.nil_node || e37.not_intersect_left_subtree(t2) || this.tree_search_interval(e37.left, t2, n2), e37.intersect(t2) && n2.push(e37), e37.right === this.nil_node || e37.not_intersect_right_subtree(t2) || this.tree_search_interval(e37.right, t2, n2));
}
tree_find_any_interval(e37, t2) {
let n2 = false;
return e37 != null && e37 !== this.nil_node && (e37.left === this.nil_node || e37.not_intersect_left_subtree(t2) || (n2 = this.tree_find_any_interval(e37.left, t2)), n2 || (n2 = e37.intersect(t2)), n2 || e37.right === this.nil_node || e37.not_intersect_right_subtree(t2) || (n2 = this.tree_find_any_interval(e37.right, t2))), n2;
}
local_minimum(e37) {
let t2 = e37;
for (;t2.left != null && t2.left !== this.nil_node; )
t2 = t2.left;
return t2;
}
local_maximum(e37) {
let t2 = e37;
for (;t2.right != null && t2.right !== this.nil_node; )
t2 = t2.right;
return t2;
}
tree_successor(e37) {
let t2, n2, o2;
if (e37.right !== this.nil_node)
t2 = this.local_minimum(e37.right);
else {
for (n2 = e37, o2 = e37.parent;o2 != null && o2.right === n2; )
n2 = o2, o2 = o2.parent;
t2 = o2;
}
return t2;
}
rotate_left(e37) {
const t2 = e37.right;
e37.right = t2.left, t2.left !== this.nil_node && (t2.left.parent = e37), t2.parent = e37.parent, e37 === this.root ? this.root = t2 : e37 === e37.parent.left ? e37.parent.left = t2 : e37.parent.right = t2, t2.left = e37, e37.parent = t2, e37 !== null && e37 !== this.nil_node && e37.update_max(), t2 != null && t2 !== this.nil_node && t2.update_max();
}
rotate_right(e37) {
const t2 = e37.left;
e37.left = t2.right, t2.right !== this.nil_node && (t2.right.parent = e37), t2.parent = e37.parent, e37 === this.root ? this.root = t2 : e37 === e37.parent.left ? e37.parent.left = t2 : e37.parent.right = t2, t2.right = e37, e37.parent = t2, e37 !== null && e37 !== this.nil_node && e37.update_max(), t2 != null && t2 !== this.nil_node && t2.update_max();
}
tree_walk(e37, t2) {
e37 != null && e37 !== this.nil_node && (this.tree_walk(e37.left, t2), t2(e37), this.tree_walk(e37.right, t2));
}
testRedBlackProperty() {
let e37 = true;
return this.tree_walk(this.root, function(t2) {
t2.color === 1 && (t2.left.color === 0 && t2.right.color === 0 || (e37 = false));
}), e37;
}
testBlackHeightProperty(e37) {
let t2 = 0, n2 = 0, o2 = 0;
if (e37.color === 0 && t2++, n2 = e37.left !== this.nil_node ? this.testBlackHeightProperty(e37.left) : 1, o2 = e37.right !== this.nil_node ? this.testBlackHeightProperty(e37.right) : 1, n2 !== o2)
throw new Error("Red-black height property violated");
return t2 += n2, t2;
}
};
var yW = class extends Set {
constructor(e37) {
super(e37), this.index = new _W, this.forEach((e38) => this.index.insert(e38));
}
add(e37) {
let t2 = this.size;
const { key: n2, value: o2 } = e37, i2 = n2 || e37.box, r2 = o2 || e37;
return super.add(r2), this.size > t2 && this.index.insert(i2, r2), this;
}
delete(e37) {
const { key: t2, value: n2 } = e37, o2 = t2 || e37.box, i2 = n2 || e37;
let r2 = super.delete(i2);
return r2 && this.index.remove(o2, i2), r2;
}
clear() {
super.clear(), this.index = new _W;
}
search(e37) {
return this.index.search(e37);
}
hit(e37) {
let t2 = new kY.Box(e37.x - 1, e37.y - 1, e37.x + 1, e37.y + 1);
return this.index.search(t2).filter((t3) => e37.on(t3));
}
svg() {
return [...this].reduce((e37, t2) => e37 + t2.svg(), "");
}
};
kY.PlanarSet = yW;
var bW = class {
get name() {
throw DY.CANNOT_INVOKE_ABSTRACT_METHOD;
}
get box() {
throw DY.CANNOT_INVOKE_ABSTRACT_METHOD;
}
clone() {
throw DY.CANNOT_INVOKE_ABSTRACT_METHOD;
}
translate(...e37) {
return this.transform(new pW().translate(...e37));
}
rotate(e37, t2 = new kY.Point) {
return this.transform(new pW().rotate(e37, t2.x, t2.y));
}
scale(e37, t2) {
return this.transform(new pW().scale(e37, t2));
}
transform(...e37) {
throw DY.CANNOT_INVOKE_ABSTRACT_METHOD;
}
toJSON() {
return Object.assign({}, this, { name: this.name });
}
svg(e37 = {}) {
throw DY.CANNOT_INVOKE_ABSTRACT_METHOD;
}
};
kY.Point = class e37 extends bW {
constructor(...e38) {
if (super(), this.x = 0, this.y = 0, e38.length !== 0) {
if (e38.length === 1 && e38[0] instanceof Array && e38[0].length === 2) {
let t2 = e38[0];
if (typeof t2[0] == "number" && typeof t2[1] == "number")
return this.x = t2[0], void (this.y = t2[1]);
}
if (e38.length === 1 && e38[0] instanceof Object && e38[0].name === "point") {
let { x: t2, y: n2 } = e38[0];
return this.x = t2, void (this.y = n2);
}
if (e38.length === 2 && typeof e38[0] == "number" && typeof e38[1] == "number")
return this.x = e38[0], void (this.y = e38[1]);
throw DY.ILLEGAL_PARAMETERS;
}
}
get box() {
return new kY.Box(this.x, this.y, this.x, this.y);
}
clone() {
return new kY.Point(this.x, this.y);
}
get vertices() {
return [this.clone()];
}
equalTo(e38) {
return kY.Utils.EQ(this.x, e38.x) && kY.Utils.EQ(this.y, e38.y);
}
lessThan(e38) {
return !!kY.Utils.LT(this.y, e38.y) || !(!kY.Utils.EQ(this.y, e38.y) || !kY.Utils.LT(this.x, e38.x));
}
transform(e38) {
return new kY.Point(e38.transform([this.x, this.y]));
}
projectionOn(e38) {
if (this.equalTo(e38.pt))
return this.clone();
let t2 = new kY.Vector(this, e38.pt);
if (kY.Utils.EQ_0(t2.cross(e38.norm)))
return e38.pt.clone();
let n2 = t2.dot(e38.norm), o2 = e38.norm.multiply(n2);
return this.translate(o2);
}
leftTo(e38) {
let t2 = new kY.Vector(e38.pt, this);
return kY.Utils.GT(t2.dot(e38.norm), 0);
}
distanceTo(t2) {
if (t2 instanceof e37) {
let e38 = t2.x - this.x, n2 = t2.y - this.y;
return [Math.sqrt(e38 * e38 + n2 * n2), new kY.Segment(this, t2)];
}
return t2 instanceof kY.Line ? kY.Distance.point2line(this, t2) : t2 instanceof kY.Circle ? kY.Distance.point2circle(this, t2) : t2 instanceof kY.Segment ? kY.Distance.point2segment(this, t2) : t2 instanceof kY.Arc ? kY.Distance.point2arc(this, t2) : t2 instanceof kY.Polygon ? kY.Distance.point2polygon(this, t2) : t2 instanceof kY.PlanarSet ? kY.Distance.shape2planarSet(this, t2) : t2 instanceof kY.Multiline ? kY.Distance.shape2multiline(this, t2) : undefined;
}
on(e38) {
if (e38 instanceof kY.Point)
return this.equalTo(e38);
if (e38.contains && e38.contains instanceof Function)
return e38.contains(this);
throw kY.Errors.UNSUPPORTED_SHAPE_TYPE;
}
get name() {
return "point";
}
svg(e38 = {}) {
const t2 = e38.r ?? 3;
return `
<circle cx="${this.x}" cy="${this.y}" r="${t2}"
${FY({ fill: "red", ...e38 })} />`;
}
};
kY.point = (...e38) => new kY.Point(...e38);
kY.Vector = class extends bW {
constructor(...e38) {
if (super(), this.x = 0, this.y = 0, e38.length !== 0) {
if (e38.length === 1 && e38[0] instanceof Array && e38[0].length === 2) {
let t2 = e38[0];
if (typeof t2[0] == "number" && typeof t2[1] == "number")
return this.x = t2[0], void (this.y = t2[1]);
}
if (e38.length === 1 && e38[0] instanceof Object && e38[0].name === "vector") {
let { x: t2, y: n2 } = e38[0];
return this.x = t2, void (this.y = n2);
}
if (e38.length === 1 && e38[0] instanceof Object && e38[0].name === "segment") {
let { start: t2, end: n2 } = e38[0];
return this.x = n2.x - t2.x, void (this.y = n2.y - t2.y);
}
if (e38.length === 2) {
let t2 = e38[0], n2 = e38[1];
if (typeof t2 == "number" && typeof n2 == "number")
return this.x = t2, void (this.y = n2);
if (t2 instanceof kY.Point && n2 instanceof kY.Point)
return this.x = n2.x - t2.x, void (this.y = n2.y - t2.y);
}
throw DY.ILLEGAL_PARAMETERS;
}
}
clone() {
return new kY.Vector(this.x, this.y);
}
get slope() {
let e38 = Math.atan2(this.y, this.x);
return e38 < 0 && (e38 = 2 * Math.PI + e38), e38;
}
get length() {
return Math.sqrt(this.dot(this));
}
isZeroLength() {
return kY.Utils.EQ_0(this.length);
}
equalTo(e38) {
return kY.Utils.EQ(this.x, e38.x) && kY.Utils.EQ(this.y, e38.y);
}
multiply(e38) {
return new kY.Vector(e38 * this.x, e38 * this.y);
}
dot(e38) {
return this.x * e38.x + this.y * e38.y;
}
cross(e38) {
return this.x * e38.y - this.y * e38.x;
}
normalize() {
if (this.isZeroLength())
throw DY.ZERO_DIVISION;
return new kY.Vector(this.x / this.length, this.y / this.length);
}
rotate(e38, t2 = new kY.Point) {
if (t2.x === 0 && t2.y === 0)
return this.transform(new pW().rotate(e38));
throw DY.OPERATION_IS_NOT_SUPPORTED;
}
transform(e38) {
return new kY.Vector(e38.transform([this.x, this.y]));
}
rotate90CCW() {
return new kY.Vector(-this.y, this.x);
}
rotate90CW() {
return new kY.Vector(this.y, -this.x);
}
invert() {
return new kY.Vector(-this.x, -this.y);
}
add(e38) {
return new kY.Vector(this.x + e38.x, this.y + e38.y);
}
subtract(e38) {
return new kY.Vector(this.x - e38.x, this.y - e38.y);
}
angleTo(e38) {
let t2 = this.normalize(), n2 = e38.normalize(), o2 = Math.atan2(t2.cross(n2), t2.dot(n2));
return o2 < 0 && (o2 += 2 * Math.PI), o2;
}
projectionOn(e38) {
let t2 = e38.normalize(), n2 = this.dot(t2);
return t2.multiply(n2);
}
get name() {
return "vector";
}
};
var xW = (...e38) => new kY.Vector(...e38);
kY.vector = xW;
kY.Segment = class e38 extends bW {
constructor(...e39) {
if (super(), this.ps = new kY.Point, this.pe = new kY.Point, e39.length !== 0) {
if (e39.length === 1 && e39[0] instanceof Array && e39[0].length === 4) {
let t2 = e39[0];
return this.ps = new kY.Point(t2[0], t2[1]), void (this.pe = new kY.Point(t2[2], t2[3]));
}
if (e39.length === 1 && e39[0] instanceof Object && e39[0].name === "segment") {
let { ps: t2, pe: n2 } = e39[0];
return this.ps = new kY.Point(t2.x, t2.y), void (this.pe = new kY.Point(n2.x, n2.y));
}
if (!(e39.length === 1 && e39[0] instanceof kY.Point)) {
if (e39.length === 2 && e39[0] instanceof kY.Point && e39[1] instanceof kY.Point)
return this.ps = e39[0].clone(), void (this.pe = e39[1].clone());
if (e39.length === 4)
return this.ps = new kY.Point(e39[0], e39[1]), void (this.pe = new kY.Point(e39[2], e39[3]));
throw DY.ILLEGAL_PARAMETERS;
}
this.ps = e39[0].clone();
}
}
clone() {
return new kY.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 kY.Vector(this.start, this.end).slope;
}
get box() {
return new kY.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(e39) {
return this.ps.equalTo(e39.ps) && this.pe.equalTo(e39.pe);
}
contains(e39) {
return kY.Utils.EQ_0(this.distanceToPoint(e39));
}
intersect(e39) {
return e39 instanceof kY.Point ? this.contains(e39) ? [e39] : [] : e39 instanceof kY.Line ? WY(this, e39) : e39 instanceof kY.Ray ? hX(e39, this) : e39 instanceof kY.Segment ? VY(this, e39) : e39 instanceof kY.Circle ? GY(this, e39) : e39 instanceof kY.Box ? function(e40, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = VY(o2, e40);
for (let e41 of t3)
n2.push(e41);
}
return n2;
}(this, e39) : e39 instanceof kY.Arc ? UY(this, e39) : e39 instanceof kY.Polygon ? nX(this, e39) : e39 instanceof kY.Multiline ? fX(this, e39) : undefined;
}
distanceTo(e39) {
if (e39 instanceof kY.Point) {
let [t2, n2] = kY.Distance.point2segment(e39, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e39 instanceof kY.Circle) {
let [t2, n2] = kY.Distance.segment2circle(this, e39);
return [t2, n2];
}
if (e39 instanceof kY.Line) {
let [t2, n2] = kY.Distance.segment2line(this, e39);
return [t2, n2];
}
if (e39 instanceof kY.Segment) {
let [t2, n2] = kY.Distance.segment2segment(this, e39);
return [t2, n2];
}
if (e39 instanceof kY.Arc) {
let [t2, n2] = kY.Distance.segment2arc(this, e39);
return [t2, n2];
}
if (e39 instanceof kY.Polygon) {
let [t2, n2] = kY.Distance.shape2polygon(this, e39);
return [t2, n2];
}
if (e39 instanceof kY.PlanarSet) {
let [t2, n2] = kY.Distance.shape2planarSet(this, e39);
return [t2, n2];
}
if (e39 instanceof kY.Multiline)
return kY.Distance.shape2multiline(this, e39);
}
tangentInStart() {
return new kY.Vector(this.start, this.end).normalize();
}
tangentInEnd() {
return new kY.Vector(this.end, this.start).normalize();
}
reverse() {
return new e38(this.end, this.start);
}
split(e39) {
return this.start.equalTo(e39) ? [null, this.clone()] : this.end.equalTo(e39) ? [this.clone(), null] : [new kY.Segment(this.start, e39), new kY.Segment(e39, this.end)];
}
middle() {
return new kY.Point((this.start.x + this.end.x) / 2, (this.start.y + this.end.y) / 2);
}
pointAtLength(e39) {
if (e39 > this.length || e39 < 0)
return null;
if (e39 == 0)
return this.start;
if (e39 == this.length)
return this.end;
let t2 = e39 / this.length;
return new kY.Point((this.end.x - this.start.x) * t2 + this.start.x, (this.end.y - this.start.y) * t2 + this.start.y);
}
distanceToPoint(e39) {
let [t2, ...n2] = kY.Distance.point2segment(e39, this);
return t2;
}
definiteIntegral(e39 = 0) {
return (this.end.x - this.start.x) * (this.start.y - e39 + (this.end.y - e39)) / 2;
}
transform(t2 = new kY.Matrix) {
return new e38(this.ps.transform(t2), this.pe.transform(t2));
}
isZeroLength() {
return this.ps.equalTo(this.pe);
}
sortPoints(e39) {
return new kY.Line(this.start, this.end).sortPoints(e39);
}
get name() {
return "segment";
}
svg(e39 = {}) {
return `
<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${FY(e39)} />`;
}
};
kY.segment = (...e39) => new kY.Segment(...e39);
var { vector: vW } = kY;
kY.Line = class e39 extends bW {
constructor(...t2) {
if (super(), this.pt = new kY.Point, this.norm = new kY.Vector(0, 1), t2.length !== 0) {
if (t2.length === 1 && t2[0] instanceof Object && t2[0].name === "line") {
let { pt: e40, norm: n2 } = t2[0];
return this.pt = new kY.Point(e40), void (this.norm = new kY.Vector(n2));
}
if (t2.length === 2) {
let n2 = t2[0], o2 = t2[1];
if (n2 instanceof kY.Point && o2 instanceof kY.Point)
return this.pt = n2, this.norm = e39.points2norm(n2, o2), void (this.norm.dot(vW(this.pt.x, this.pt.y)) >= 0 && this.norm.invert());
if (n2 instanceof kY.Point && o2 instanceof kY.Vector) {
if (kY.Utils.EQ_0(o2.x) && kY.Utils.EQ_0(o2.y))
throw DY.ILLEGAL_PARAMETERS;
return this.pt = n2.clone(), this.norm = o2.clone(), this.norm = this.norm.normalize(), void (this.norm.dot(vW(this.pt.x, this.pt.y)) >= 0 && this.norm.invert());
}
if (n2 instanceof kY.Vector && o2 instanceof kY.Point) {
if (kY.Utils.EQ_0(n2.x) && kY.Utils.EQ_0(n2.y))
throw DY.ILLEGAL_PARAMETERS;
return this.pt = o2.clone(), this.norm = n2.clone(), this.norm = this.norm.normalize(), void (this.norm.dot(vW(this.pt.x, this.pt.y)) >= 0 && this.norm.invert());
}
}
throw DY.ILLEGAL_PARAMETERS;
}
}
clone() {
return new kY.Line(this.pt, this.norm);
}
get start() {}
get end() {}
get length() {
return Number.POSITIVE_INFINITY;
}
get box() {
return new kY.Box(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
}
get middle() {}
get slope() {
return new kY.Vector(this.norm.y, -this.norm.x).slope;
}
get standard() {
return [this.norm.x, this.norm.y, this.norm.dot(vW(this.pt.x, this.pt.y))];
}
parallelTo(e40) {
return kY.Utils.EQ_0(this.norm.cross(e40.norm));
}
incidentTo(e40) {
return this.parallelTo(e40) && this.pt.on(e40);
}
contains(e40) {
if (this.pt.equalTo(e40))
return true;
let t2 = new kY.Vector(this.pt, e40);
return kY.Utils.EQ_0(this.norm.dot(t2));
}
coord(e40) {
return vW(e40.x, e40.y).cross(this.norm);
}
intersect(e40) {
return e40 instanceof kY.Point ? this.contains(e40) ? [e40] : [] : e40 instanceof kY.Line ? jY(this, e40) : e40 instanceof kY.Ray ? pX(e40, this) : e40 instanceof kY.Circle ? $Y(this, e40) : e40 instanceof kY.Box ? YY(this, e40) : e40 instanceof kY.Segment ? WY(e40, this) : e40 instanceof kY.Arc ? XY(this, e40) : e40 instanceof kY.Polygon ? iX(this, e40) : e40 instanceof kY.Multiline ? fX(this, e40) : undefined;
}
distanceTo(e40) {
if (e40 instanceof kY.Point) {
let [t2, n2] = kY.Distance.point2line(e40, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e40 instanceof kY.Circle) {
let [t2, n2] = kY.Distance.circle2line(e40, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e40 instanceof kY.Segment) {
let [t2, n2] = kY.Distance.segment2line(e40, this);
return [t2, n2.reverse()];
}
if (e40 instanceof kY.Arc) {
let [t2, n2] = kY.Distance.arc2line(e40, this);
return [t2, n2.reverse()];
}
if (e40 instanceof kY.Polygon) {
let [t2, n2] = kY.Distance.shape2polygon(this, e40);
return [t2, n2];
}
}
split(e40) {
if (e40 instanceof kY.Point)
return [new kY.Ray(e40, this.norm), new kY.Ray(e40, this.norm)];
{
let t2 = new kY.Multiline([this]), n2 = this.sortPoints(e40);
return t2.split(n2), t2.toShapes();
}
}
rotate(e40, t2 = new kY.Point) {
return new kY.Line(this.pt.rotate(e40, t2), this.norm.rotate(e40));
}
transform(e40) {
return new kY.Line(this.pt.transform(e40), this.norm.clone());
}
sortPoints(e40) {
return e40.slice().sort((e41, t2) => this.coord(e41) < this.coord(t2) ? -1 : this.coord(e41) > this.coord(t2) ? 1 : 0);
}
get name() {
return "line";
}
svg(e40, t2 = {}) {
let n2 = YY(this, e40);
if (n2.length === 0)
return "";
let o2 = n2[0], i2 = n2.length === 2 ? n2[1] : n2.find((e41) => !e41.equalTo(o2));
return i2 === undefined && (i2 = o2), new kY.Segment(o2, i2).svg(t2);
}
static points2norm(e40, t2) {
if (e40.equalTo(t2))
throw DY.ILLEGAL_PARAMETERS;
return new kY.Vector(e40, t2).normalize().rotate90CCW();
}
};
kY.line = (...e40) => new kY.Line(...e40);
kY.Circle = class extends bW {
constructor(...e40) {
if (super(), this.pc = new kY.Point, this.r = 1, e40.length === 1 && e40[0] instanceof Object && e40[0].name === "circle") {
let { pc: t2, r: n2 } = e40[0];
this.pc = new kY.Point(t2), this.r = n2;
} else {
let [t2, n2] = [...e40];
t2 && t2 instanceof kY.Point && (this.pc = t2.clone()), n2 !== undefined && (this.r = n2);
}
}
clone() {
return new kY.Circle(this.pc.clone(), this.r);
}
get center() {
return this.pc;
}
get box() {
return new kY.Box(this.pc.x - this.r, this.pc.y - this.r, this.pc.x + this.r, this.pc.y + this.r);
}
contains(e40) {
return e40 instanceof kY.Point ? kY.Utils.LE(e40.distanceTo(this.center)[0], this.r) : e40 instanceof kY.Segment ? kY.Utils.LE(e40.start.distanceTo(this.center)[0], this.r) && kY.Utils.LE(e40.end.distanceTo(this.center)[0], this.r) : e40 instanceof kY.Arc ? this.intersect(e40).length === 0 && kY.Utils.LE(e40.start.distanceTo(this.center)[0], this.r) && kY.Utils.LE(e40.end.distanceTo(this.center)[0], this.r) : e40 instanceof kY.Circle ? this.intersect(e40).length === 0 && kY.Utils.LE(e40.r, this.r) && kY.Utils.LE(e40.center.distanceTo(this.center)[0], this.r) : undefined;
}
toArc(e40 = true) {
return new kY.Arc(this.center, this.r, Math.PI, -Math.PI, e40);
}
scale(e40, t2) {
if (e40 !== t2)
throw DY.OPERATION_IS_NOT_SUPPORTED;
if (this.pc.x !== 0 || this.pc.y !== 0)
throw DY.OPERATION_IS_NOT_SUPPORTED;
return new kY.Circle(this.pc, this.r * e40);
}
transform(e40 = new kY.Matrix) {
return new kY.Circle(this.pc.transform(e40), this.r);
}
intersect(e40) {
return e40 instanceof kY.Point ? this.contains(e40) ? [e40] : [] : e40 instanceof kY.Line ? $Y(e40, this) : e40 instanceof kY.Ray ? uX(e40, this) : e40 instanceof kY.Segment ? GY(e40, this) : e40 instanceof kY.Circle ? ZY(e40, this) : e40 instanceof kY.Box ? function(e41, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = GY(o2, e41);
for (let e42 of t3)
n2.push(e42);
}
return n2;
}(this, e40) : e40 instanceof kY.Arc ? JY(e40, this) : e40 instanceof kY.Polygon ? rX(this, e40) : e40 instanceof kY.Multiline ? fX(this, e40) : undefined;
}
distanceTo(e40) {
if (e40 instanceof kY.Point) {
let [t2, n2] = kY.Distance.point2circle(e40, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e40 instanceof kY.Circle) {
let [t2, n2] = kY.Distance.circle2circle(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.Line) {
let [t2, n2] = kY.Distance.circle2line(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.Segment) {
let [t2, n2] = kY.Distance.segment2circle(e40, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e40 instanceof kY.Arc) {
let [t2, n2] = kY.Distance.arc2circle(e40, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e40 instanceof kY.Polygon) {
let [t2, n2] = kY.Distance.shape2polygon(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.PlanarSet) {
let [t2, n2] = kY.Distance.shape2planarSet(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.Multiline) {
let [t2, n2] = kY.Distance.shape2multiline(this, e40);
return [t2, n2];
}
}
get name() {
return "circle";
}
svg(e40 = {}) {
return `
<circle cx="${this.pc.x}" cy="${this.pc.y}" r="${this.r}"
${FY({ fill: "none", ...e40 })} />`;
}
};
kY.circle = (...e40) => new kY.Circle(...e40);
kY.Arc = class extends bW {
constructor(...e40) {
if (super(), this.pc = new kY.Point, this.r = 1, this.startAngle = 0, this.endAngle = 2 * Math.PI, this.counterClockwise = true, e40.length !== 0)
if (e40.length === 1 && e40[0] instanceof Object && e40[0].name === "arc") {
let { pc: t2, r: n2, startAngle: o2, endAngle: i2, counterClockwise: r2 } = e40[0];
this.pc = new kY.Point(t2.x, t2.y), this.r = n2, this.startAngle = o2, this.endAngle = i2, this.counterClockwise = r2;
} else {
let [t2, n2, o2, i2, r2] = [...e40];
t2 && t2 instanceof kY.Point && (this.pc = t2.clone()), n2 !== undefined && (this.r = n2), o2 !== undefined && (this.startAngle = o2), i2 !== undefined && (this.endAngle = i2), r2 !== undefined && (this.counterClockwise = r2);
}
}
clone() {
return new kY.Arc(this.pc.clone(), this.r, this.startAngle, this.endAngle, this.counterClockwise);
}
get sweep() {
let e40 = this.startAngle, t2 = this.endAngle;
if (kY.Utils.EQ(Math.abs(e40 - t2), kY.PIx2))
return kY.PIx2;
Math.abs(e40) > kY.PIx2 && (e40 -= Math.trunc(e40 / kY.PIx2) * kY.PIx2), e40 < 0 && (e40 += kY.PIx2), Math.abs(t2) > kY.PIx2 && (t2 -= Math.trunc(t2 / kY.PIx2) * kY.PIx2), t2 < 0 && (t2 += kY.PIx2);
let n2 = this.counterClockwise ? t2 - e40 : e40 - t2;
return n2 < 0 && (n2 += kY.PIx2), n2;
}
get start() {
return new kY.Point(this.pc.x + this.r, this.pc.y).rotate(this.startAngle, this.pc);
}
get end() {
return new kY.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 e40 = this.breakToFunctional().reduce((e41, t2) => e41.merge(t2.start.box), new kY.Box);
return e40 = e40.merge(this.end.box), e40;
}
contains(e40) {
if (!kY.Utils.EQ(this.pc.distanceTo(e40)[0], this.r))
return false;
if (e40.equalTo(this.start))
return true;
let t2 = new kY.Vector(this.pc, e40).slope, n2 = new kY.Arc(this.pc, this.r, this.startAngle, t2, this.counterClockwise);
return kY.Utils.LE(n2.length, this.length);
}
split(e40) {
if (this.start.equalTo(e40))
return [null, this.clone()];
if (this.end.equalTo(e40))
return [this.clone(), null];
let t2 = new kY.Vector(this.pc, e40).slope;
return [new kY.Arc(this.pc, this.r, this.startAngle, t2, this.counterClockwise), new kY.Arc(this.pc, this.r, t2, this.endAngle, this.counterClockwise)];
}
middle() {
let e40 = this.counterClockwise ? this.startAngle + this.sweep / 2 : this.startAngle - this.sweep / 2;
return new kY.Arc(this.pc, this.r, this.startAngle, e40, this.counterClockwise).end;
}
pointAtLength(e40) {
if (e40 > this.length || e40 < 0)
return null;
if (e40 === 0)
return this.start;
if (e40 === this.length)
return this.end;
let t2 = e40 / this.length, n2 = this.counterClockwise ? this.startAngle + this.sweep * t2 : this.startAngle - this.sweep * t2;
return new kY.Arc(this.pc, this.r, this.startAngle, n2, this.counterClockwise).end;
}
chordHeight() {
return (1 - Math.cos(Math.abs(this.sweep / 2))) * this.r;
}
intersect(e40) {
return e40 instanceof kY.Point ? this.contains(e40) ? [e40] : [] : e40 instanceof kY.Line ? XY(e40, this) : e40 instanceof kY.Ray ? dX(e40, this) : e40 instanceof kY.Circle ? JY(this, e40) : e40 instanceof kY.Segment ? UY(e40, this) : e40 instanceof kY.Box ? function(e41, t2) {
let n2 = [];
for (let o2 of t2.toSegments()) {
let t3 = UY(o2, e41);
for (let e42 of t3)
n2.push(e42);
}
return n2;
}(this, e40) : e40 instanceof kY.Arc ? qY(this, e40) : e40 instanceof kY.Polygon ? oX(this, e40) : e40 instanceof kY.Multiline ? fX(this, e40) : undefined;
}
distanceTo(e40) {
if (e40 instanceof kY.Point) {
let [t2, n2] = kY.Distance.point2arc(e40, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e40 instanceof kY.Circle) {
let [t2, n2] = kY.Distance.arc2circle(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.Line) {
let [t2, n2] = kY.Distance.arc2line(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.Segment) {
let [t2, n2] = kY.Distance.segment2arc(e40, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e40 instanceof kY.Arc) {
let [t2, n2] = kY.Distance.arc2arc(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.Polygon) {
let [t2, n2] = kY.Distance.shape2polygon(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.PlanarSet) {
let [t2, n2] = kY.Distance.shape2planarSet(this, e40);
return [t2, n2];
}
if (e40 instanceof kY.Multiline)
return kY.Distance.shape2multiline(this, e40);
}
breakToFunctional() {
let e40 = [], t2 = [0, Math.PI / 2, Math.PI, 3 * Math.PI / 2], n2 = this.startAngle, o2 = this.endAngle;
kY.Utils.EQ(Math.abs(n2 - o2), kY.PIx2) && (o2 = n2), Math.abs(n2) > kY.PIx2 && (n2 -= Math.trunc(n2 / kY.PIx2) * kY.PIx2), n2 < 0 && (n2 += kY.PIx2), Math.abs(o2) > kY.PIx2 && (o2 -= Math.trunc(o2 / kY.PIx2) * kY.PIx2), o2 < 0 && (o2 += kY.PIx2);
let i2, r2, s2, a2 = n2;
this.counterClockwise ? (r2 = Math.ceil(n2 / (Math.PI / 2)) % 4, s2 = 1) : (r2 = Math.floor(n2 / (Math.PI / 2)) % 4, s2 = -1);
for (let o3 = 0, c2 = r2;o3 < 4; o3++, c2 = (c2 + s2 + 4) % 4) {
if (i2 = t2[c2], i2 === a2)
continue;
let o4 = this.counterClockwise ? i2 - n2 : n2 - i2;
if (o4 < 0 && (o4 += kY.PIx2), o4 > this.sweep)
break;
e40.push(new kY.Arc(this.pc, this.r, a2, i2, this.counterClockwise)), a2 = i2;
}
return e40.length === 0 ? (e40.push(this), e40) : (i2 = o2, a2 !== i2 && e40.push(new kY.Arc(this.pc, this.r, a2, i2, this.counterClockwise)), e40);
}
tangentInStart() {
let e40 = new kY.Vector(this.pc, this.start), t2 = this.counterClockwise ? Math.PI / 2 : -Math.PI / 2;
return e40.rotate(t2).normalize();
}
tangentInEnd() {
let e40 = new kY.Vector(this.pc, this.end), t2 = this.counterClockwise ? -Math.PI / 2 : Math.PI / 2;
return e40.rotate(t2).normalize();
}
reverse() {
return new kY.Arc(this.pc, this.r, this.endAngle, this.startAngle, !this.counterClockwise);
}
transform(e40 = new kY.Matrix) {
let t2 = this.start.transform(e40), n2 = this.end.transform(e40), o2 = this.pc.transform(e40), i2 = this.counterClockwise;
return e40.a * e40.d < 0 && (i2 = !i2), kY.Arc.arcSE(o2, t2, n2, i2);
}
static arcSE(e40, t2, n2, o2) {
let { vector: i2 } = kY, r2 = i2(e40, t2).slope, s2 = i2(e40, n2).slope;
kY.Utils.EQ(r2, s2) && (s2 += 2 * Math.PI, o2 = true);
let a2 = i2(e40, t2).length;
return new kY.Arc(e40, a2, r2, s2, o2);
}
definiteIntegral(e40 = 0) {
return this.breakToFunctional().reduce((t2, n2) => t2 + n2.circularSegmentDefiniteIntegral(e40), 0);
}
circularSegmentDefiniteIntegral(e40) {
let t2 = new kY.Segment(this.start, this.end).definiteIntegral(e40), n2 = kY.Utils.EQ(this.sweep, kY.PIx2) ? 0 : this.circularSegmentArea();
return this.counterClockwise ? t2 - n2 : t2 + n2;
}
circularSegmentArea() {
return 0.5 * this.r * this.r * (this.sweep - Math.sin(this.sweep));
}
sortPoints(e40) {
let { vector: t2 } = kY;
return e40.slice().sort((e41, n2) => {
let o2 = t2(this.pc, e41).slope, i2 = t2(this.pc, n2).slope;
return o2 < i2 ? -1 : o2 > i2 ? 1 : 0;
});
}
get name() {
return "arc";
}
svg(e40 = {}) {
let t2 = this.sweep <= Math.PI ? "0" : "1", n2 = this.counterClockwise ? "1" : "0";
if (kY.Utils.EQ(this.sweep, 2 * Math.PI)) {
return new kY.Circle(this.pc, this.r).svg(e40);
}
return `
<path d="M${this.start.x},${this.start.y}
A${this.r},${this.r} 0 ${t2},${n2} ${this.end.x},${this.end.y}"
${FY({ fill: "none", ...e40 })} />`;
}
};
kY.arc = (...e40) => new kY.Arc(...e40);
kY.Box = class e40 extends bW {
constructor(e41 = undefined, t2 = undefined, n2 = undefined, o2 = undefined) {
super(), this.xmin = e41, this.ymin = t2, this.xmax = n2, this.ymax = o2;
}
clone() {
return new e40(this.xmin, this.ymin, this.xmax, this.ymax);
}
get low() {
return new kY.Point(this.xmin, this.ymin);
}
get high() {
return new kY.Point(this.xmax, this.ymax);
}
get max() {
return this.clone();
}
get center() {
return new kY.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(e41) {
return this.xmax < e41.xmin || this.xmin > e41.xmax || this.ymax < e41.ymin || this.ymin > e41.ymax;
}
intersect(e41) {
return !this.not_intersect(e41);
}
merge(t2) {
return new e40(this.xmin === undefined ? t2.xmin : Math.min(this.xmin, t2.xmin), this.ymin === undefined ? t2.ymin : Math.min(this.ymin, t2.ymin), this.xmax === undefined ? t2.xmax : Math.max(this.xmax, t2.xmax), this.ymax === undefined ? t2.ymax : Math.max(this.ymax, t2.ymax));
}
less_than(e41) {
return !!this.low.lessThan(e41.low) || !(!this.low.equalTo(e41.low) || !this.high.lessThan(e41.high));
}
equal_to(e41) {
return this.low.equalTo(e41.low) && this.high.equalTo(e41.high);
}
output() {
return this.clone();
}
comparable_less_than(e41, t2) {
return e41.lessThan(t2);
}
set(e41, t2, n2, o2) {
this.xmin = e41, this.ymin = t2, this.xmax = n2, this.ymax = o2;
}
extend(t2) {
return t2 <= 0 ? this.clone() : new e40(this.xmin - t2, this.ymin - t2, this.xmax + t2, this.ymax + t2);
}
toPoints() {
return [new kY.Point(this.xmin, this.ymin), new kY.Point(this.xmax, this.ymin), new kY.Point(this.xmax, this.ymax), new kY.Point(this.xmin, this.ymax)];
}
toSegments() {
let e41 = this.toPoints();
return [new kY.Segment(e41[0], e41[1]), new kY.Segment(e41[1], e41[2]), new kY.Segment(e41[2], e41[3]), new kY.Segment(e41[3], e41[0])];
}
rotate(e41, t2 = new kY.Point) {
throw DY.OPERATION_IS_NOT_SUPPORTED;
}
transform(t2 = new kY.Matrix) {
return this.toPoints().map((e41) => e41.transform(t2)).reduce((e41, t3) => e41.merge(t3.box), new e40);
}
contains(e41) {
return e41 instanceof kY.Point ? e41.x >= this.xmin && e41.x <= this.xmax && e41.y >= this.ymin && e41.y <= this.ymax : e41 instanceof kY.Segment ? e41.vertices.every((e42) => this.contains(e42)) : e41 instanceof kY.Box ? e41.toSegments().every((e42) => this.contains(e42)) : e41 instanceof kY.Circle ? this.contains(e41.box) : e41 instanceof kY.Arc ? e41.vertices.every((e42) => this.contains(e42)) && this.toSegments().every((t2) => UY(t2, e41).length === 0) : !(e41 instanceof kY.Line || e41 instanceof kY.Ray) && (e41 instanceof kY.Multiline ? e41.toShapes().every((e42) => this.contains(e42)) : e41 instanceof kY.Polygon ? this.contains(e41.box) : undefined);
}
distanceTo(e41) {
const t2 = this.toSegments().map((t3) => t3.distanceTo(e41));
let n2 = [Number.MAX_SAFE_INTEGER, null];
return t2.forEach((e42) => {
e42[0] < n2[0] && (n2 = e42);
}), n2;
}
get name() {
return "box";
}
svg(e41 = {}) {
const t2 = this.xmax - this.xmin, n2 = this.ymax - this.ymin;
return `
<rect x="${this.xmin}" y="${this.ymin}" width="${t2}" height="${n2}"
${FY({ fill: "none", ...e41 })} />`;
}
};
kY.box = (...e41) => new kY.Box(...e41);
kY.Edge = class {
constructor(e41) {
this.shape = e41, this.next = undefined, this.prev = undefined, this.face = undefined, this.arc_length = 0, this.bvStart = undefined, this.bvEnd = undefined, this.bv = undefined, this.overlap = undefined;
}
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 kY.Segment;
}
get isArc() {
return this.shape instanceof kY.Arc;
}
get isLine() {
return this.shape instanceof kY.Line;
}
get isRay() {
return this.shape instanceof kY.Ray;
}
middle() {
return this.shape.middle();
}
pointAtLength(e41) {
return this.shape.pointAtLength(e41);
}
contains(e41) {
return this.shape.contains(e41);
}
setInclusion(e41) {
if (this.bv !== undefined)
return this.bv;
if (this.shape instanceof kY.Line || this.shape instanceof kY.Ray)
return this.bv = kY.OUTSIDE, this.bv;
if (this.bvStart === undefined && (this.bvStart = iW(e41, this.start)), this.bvEnd === undefined && (this.bvEnd = iW(e41, this.end)), this.bvStart === kY.OUTSIDE || this.bvEnd == kY.OUTSIDE)
this.bv = kY.OUTSIDE;
else if (this.bvStart === kY.INSIDE || this.bvEnd == kY.INSIDE)
this.bv = kY.INSIDE;
else {
let t2 = iW(e41, this.middle());
this.bv = t2;
}
return this.bv;
}
setOverlap(e41) {
let t2, n2 = this.shape, o2 = e41.shape;
n2 instanceof kY.Segment && o2 instanceof kY.Segment ? n2.start.equalTo(o2.start) && n2.end.equalTo(o2.end) ? t2 = kY.OVERLAP_SAME : n2.start.equalTo(o2.end) && n2.end.equalTo(o2.start) && (t2 = kY.OVERLAP_OPPOSITE) : (n2 instanceof kY.Arc && o2 instanceof kY.Arc || n2 instanceof kY.Segment && o2 instanceof kY.Arc || n2 instanceof kY.Arc && o2 instanceof kY.Segment) && (n2.start.equalTo(o2.start) && n2.end.equalTo(o2.end) && n2.middle().equalTo(o2.middle()) ? t2 = kY.OVERLAP_SAME : n2.start.equalTo(o2.end) && n2.end.equalTo(o2.start) && n2.middle().equalTo(o2.middle()) && (t2 = kY.OVERLAP_OPPOSITE)), this.overlap === undefined && (this.overlap = t2), e41.overlap === undefined && (e41.overlap = t2);
}
svg() {
if (this.shape instanceof kY.Segment)
return ` L${this.shape.end.x},${this.shape.end.y}`;
if (this.shape instanceof kY.Arc) {
let e41, t2 = this.shape, n2 = t2.counterClockwise ? "1" : "0";
if (kY.Utils.EQ(t2.sweep, 2 * Math.PI)) {
let o2 = t2.counterClockwise ? 1 : -1, i2 = new kY.Arc(t2.pc, t2.r, t2.startAngle, t2.startAngle + o2 * Math.PI, t2.counterClockwise), r2 = new kY.Arc(t2.pc, t2.r, t2.startAngle + o2 * Math.PI, t2.endAngle, t2.counterClockwise);
return e41 = "0", ` A${i2.r},${i2.r} 0 ${e41},${n2} ${i2.end.x},${i2.end.y}
A${r2.r},${r2.r} 0 ${e41},${n2} ${r2.end.x},${r2.end.y}`;
}
return e41 = t2.sweep <= Math.PI ? "0" : "1", ` A${t2.r},${t2.r} 0 ${e41},${n2} ${t2.end.x},${t2.end.y}`;
}
}
toJSON() {
return this.shape.toJSON();
}
};
var IW = class extends LY {
constructor(e41, t2) {
super(e41, t2), this.setCircularLinks();
}
setCircularLinks() {
this.isEmpty() || (this.last.next = this.first, this.first.prev = this.last);
}
[Symbol.iterator]() {
let e41;
return { next: () => {
let t2 = e41 || this.first, n2 = !this.first || !!e41 && e41 === this.first;
return e41 = t2 ? t2.next : undefined, { value: t2, done: n2 };
} };
}
append(e41) {
return super.append(e41), this.setCircularLinks(), this;
}
insert(e41, t2) {
return super.insert(e41, t2), this.setCircularLinks(), this;
}
remove(e41) {
return super.remove(e41), this;
}
};
kY.Face = class e41 extends IW {
constructor(t2, ...n2) {
if (super(), this._box = undefined, this._orientation = undefined, n2.length !== 0) {
if (n2.length === 1) {
if (n2[0] instanceof Array) {
let o2 = n2[0];
if (o2.length === 0)
return;
if (o2.every((e42) => e42 instanceof kY.Point)) {
let n3 = e41.points2segments(o2);
this.shapes2face(t2.edges, n3);
} else if (o2.every((e42) => e42 instanceof Array && e42.length === 2)) {
let n3 = o2.map((e42) => new kY.Point(e42[0], e42[1])), i2 = e41.points2segments(n3);
this.shapes2face(t2.edges, i2);
} else if (o2.every((e42) => e42 instanceof kY.Segment || e42 instanceof kY.Arc))
this.shapes2face(t2.edges, o2);
else if (o2.every((e42) => e42.name === "segment" || e42.name === "arc")) {
let e42 = [];
for (let t3 of o2) {
let n3;
n3 = t3.name === "segment" ? new kY.Segment(t3) : new kY.Arc(t3), e42.push(n3);
}
this.shapes2face(t2.edges, e42);
}
} else if (n2[0] instanceof e41) {
let e42 = n2[0];
this.first = e42.first, this.last = e42.last;
for (let n3 of e42)
t2.edges.add(n3);
} else if (n2[0] instanceof kY.Circle)
this.shapes2face(t2.edges, [n2[0].toArc(SY)]);
else if (n2[0] instanceof kY.Box) {
let e42 = n2[0];
this.shapes2face(t2.edges, [new kY.Segment(new kY.Point(e42.xmin, e42.ymin), new kY.Point(e42.xmax, e42.ymin)), new kY.Segment(new kY.Point(e42.xmax, e42.ymin), new kY.Point(e42.xmax, e42.ymax)), new kY.Segment(new kY.Point(e42.xmax, e42.ymax), new kY.Point(e42.xmin, e42.ymax)), new kY.Segment(new kY.Point(e42.xmin, e42.ymax), new kY.Point(e42.xmin, e42.ymin))]);
}
}
n2.length === 2 && n2[0] instanceof kY.Edge && n2[1] instanceof kY.Edge && (this.first = n2[0], this.last = n2[1], this.last.next = this.first, this.first.prev = this.last, this.setArcLength());
}
}
get edges() {
return this.toArray();
}
get vertices() {
return this.edges.map((e42) => e42.shape.start.clone());
}
get shapes() {
return this.edges.map((e42) => e42.shape.clone());
}
get box() {
if (this._box === undefined) {
let e42 = new kY.Box;
for (let t2 of this)
e42 = e42.merge(t2.box);
this._box = e42;
}
return this._box;
}
get perimeter() {
return this.last.arc_length + this.last.length;
}
pointAtLength(e42) {
if (e42 > this.perimeter || e42 < 0)
return null;
let t2 = null;
for (let n2 of this)
if (e42 >= n2.arc_length && (n2 === this.last || e42 < n2.next.arc_length)) {
t2 = n2.pointAtLength(e42 - n2.arc_length);
break;
}
return t2;
}
static points2segments(e42) {
let t2 = [];
for (let n2 = 0;n2 < e42.length; n2++)
e42[n2].equalTo(e42[(n2 + 1) % e42.length]) || t2.push(new kY.Segment(e42[n2], e42[(n2 + 1) % e42.length]));
return t2;
}
shapes2face(e42, t2) {
for (let n2 of t2) {
let t3 = new kY.Edge(n2);
this.append(t3), e42.add(t3);
}
}
append(e42) {
return super.append(e42), this.setOneEdgeArcLength(e42), e42.face = this, this;
}
insert(e42, t2) {
return super.insert(e42, t2), this.setOneEdgeArcLength(e42), e42.face = this, this;
}
remove(e42) {
return super.remove(e42), this.setArcLength(), this;
}
merge_with_next_edge(e42) {
return e42.shape.end.x = e42.next.shape.end.x, e42.shape.end.y = e42.next.shape.end.y, this.remove(e42.next), this;
}
reverse() {
let e42 = [], t2 = this.last;
do {
t2.shape = t2.shape.reverse(), e42.push(t2), t2 = t2.prev;
} while (t2 !== this.last);
this.first = undefined, this.last = undefined;
for (let t3 of e42)
this.first === undefined ? (t3.prev = t3, t3.next = t3, this.first = t3, this.last = t3) : (t3.prev = this.last, this.last.next = t3, this.last = t3, this.last.next = this.first, this.first.prev = this.last), this.setOneEdgeArcLength(t3);
this._orientation !== undefined && (this._orientation = undefined, this._orientation = this.orientation());
}
setArcLength() {
for (let e42 of this)
this.setOneEdgeArcLength(e42), e42.face = this;
}
setOneEdgeArcLength(e42) {
e42 === this.first ? e42.arc_length = 0 : e42.arc_length = e42.prev.arc_length + e42.prev.length;
}
area() {
return Math.abs(this.signedArea());
}
signedArea() {
let e42 = 0, t2 = this.box.ymin;
for (let n2 of this)
e42 += n2.shape.definiteIntegral(t2);
return e42;
}
orientation() {
if (this._orientation === undefined) {
let e42 = this.signedArea();
kY.Utils.EQ_0(e42) ? this._orientation = CY.NOT_ORIENTABLE : kY.Utils.LT(e42, 0) ? this._orientation = CY.CCW : this._orientation = CY.CW;
}
return this._orientation;
}
isSimple(t2) {
return e41.getSelfIntersections(this, t2, true).length === 0;
}
static getSelfIntersections(e42, t2, n2 = false) {
let o2 = [];
for (let i2 of e42) {
let r2 = t2.search(i2.box);
for (let t3 of r2) {
if (i2 === t3)
continue;
if (t3.face !== e42)
continue;
if (i2.shape instanceof kY.Segment && t3.shape instanceof kY.Segment && (i2.next === t3 || i2.prev === t3))
continue;
let r3 = i2.shape.intersect(t3.shape);
for (let e43 of r3)
if ((!e43.equalTo(i2.start) || !e43.equalTo(t3.end) || t3 !== i2.prev) && (!e43.equalTo(i2.end) || !e43.equalTo(t3.start) || t3 !== i2.next) && (o2.push(e43), n2))
break;
if (o2.length > 0 && n2)
break;
}
if (o2.length > 0 && n2)
break;
}
return o2;
}
findEdgeByPoint(e42) {
let t2;
for (let n2 of this)
if (!e42.equalTo(n2.shape.start) && (e42.equalTo(n2.shape.end) || n2.shape.contains(e42))) {
t2 = n2;
break;
}
return t2;
}
toPolygon() {
return new kY.Polygon(this.shapes);
}
toJSON() {
return this.edges.map((e42) => e42.toJSON());
}
svg() {
let e42 = `M${this.first.start.x},${this.first.start.y}`;
for (let t2 of this)
e42 += t2.svg();
return e42 += " z", e42;
}
};
kY.Ray = class e42 extends bW {
constructor(...e43) {
if (super(), this.pt = new kY.Point, this.norm = new kY.Vector(0, 1), e43.length !== 0 && (e43.length >= 1 && e43[0] instanceof kY.Point && (this.pt = e43[0].clone()), e43.length !== 1)) {
if (!(e43.length === 2 && e43[1] instanceof kY.Vector))
throw DY.ILLEGAL_PARAMETERS;
this.norm = e43[1].clone();
}
}
clone() {
return new e42(this.pt, this.norm);
}
get slope() {
return new kY.Vector(this.norm.y, -this.norm.x).slope;
}
get box() {
let e43 = this.slope;
return new kY.Box(e43 > Math.PI / 2 && e43 < 3 * Math.PI / 2 ? Number.NEGATIVE_INFINITY : this.pt.x, e43 >= 0 && e43 <= Math.PI ? this.pt.y : Number.NEGATIVE_INFINITY, e43 >= Math.PI / 2 && e43 <= 3 * Math.PI / 2 ? this.pt.x : Number.POSITIVE_INFINITY, e43 >= Math.PI && e43 <= 2 * Math.PI || e43 === 0 ? this.pt.y : Number.POSITIVE_INFINITY);
}
get start() {
return this.pt;
}
get end() {}
get length() {
return Number.POSITIVE_INFINITY;
}
contains(e43) {
if (this.pt.equalTo(e43))
return true;
let t2 = new kY.Vector(this.pt, e43);
return kY.Utils.EQ_0(this.norm.dot(t2)) && kY.Utils.GE(t2.cross(this.norm), 0);
}
coord(e43) {
return xW(e43.x, e43.y).cross(this.norm);
}
split(e43) {
return this.contains(e43) ? this.pt.equalTo(e43) ? [this] : [new kY.Segment(this.pt, e43), new kY.Ray(e43, this.norm)] : [];
}
intersect(e43) {
return e43 instanceof kY.Point ? this.contains(e43) ? [e43] : [] : e43 instanceof kY.Segment ? hX(this, e43) : e43 instanceof kY.Arc ? dX(this, e43) : e43 instanceof kY.Line ? pX(this, e43) : e43 instanceof kY.Ray ? (n2 = e43, jY(lX(t2 = this), lX(n2)).filter((e44) => t2.contains(e44)).filter((e44) => n2.contains(e44))) : e43 instanceof kY.Circle ? uX(this, e43) : e43 instanceof kY.Box ? function(e44, t3) {
return YY(lX(e44), t3).filter((t4) => e44.contains(t4));
}(this, e43) : e43 instanceof kY.Polygon ? mX(this, e43) : e43 instanceof kY.Multiline ? fX(this, e43) : undefined;
var t2, n2;
}
rotate(e43, t2 = new kY.Point) {
return new kY.Ray(this.pt.rotate(e43, t2), this.norm.rotate(e43));
}
transform(e43) {
return new kY.Ray(this.pt.transform(e43), this.norm.clone());
}
get name() {
return "ray";
}
svg(e43, t2 = {}) {
let n2 = YY(new kY.Line(this.pt, this.norm), e43);
return n2 = n2.filter((e44) => this.contains(e44)), n2.length === 0 || n2.length === 2 ? "" : new kY.Segment(this.pt, n2[0]).svg(t2);
}
};
kY.ray = (...e43) => new kY.Ray(...e43);
kY.Polygon = class e43 {
constructor() {
this.faces = new kY.PlanarSet, this.edges = new kY.PlanarSet;
let e44 = [...arguments];
if (e44.length === 1 && (e44[0] instanceof Array && e44[0].length > 0 || e44[0] instanceof kY.Circle || e44[0] instanceof kY.Box)) {
let t2 = e44[0];
if (e44[0] instanceof Array && e44[0].every((e45) => e45 instanceof Array))
if (t2.every((e45) => e45 instanceof Array && e45.length === 2 && typeof e45[0] == "number" && typeof e45[1] == "number"))
this.faces.add(new kY.Face(this, t2));
else
for (let e45 of t2)
if (e45 instanceof Array && e45[0] instanceof Array && e45[0].every((e46) => e46 instanceof Array && e46.length === 2 && typeof e46[0] == "number" && typeof e46[1] == "number"))
for (let t3 of e45)
this.faces.add(new kY.Face(this, t3));
else
this.faces.add(new kY.Face(this, e45));
else
this.faces.add(new kY.Face(this, t2));
}
}
get box() {
return [...this.faces].reduce((e44, t2) => e44.merge(t2.box), new kY.Box);
}
get vertices() {
return [...this.faces].flatMap((e44) => e44.vertices);
}
clone() {
let t2 = new e43;
for (let e44 of this.faces)
t2.addFace(e44.shapes);
return t2;
}
createFromArray(t2) {
const n2 = new e43;
return t2.forEach((e44) => [...e44.faces].forEach((e45) => n2.addFace(e45.shapes))), n2;
}
isEmpty() {
return this.edges.size === 0 || this.faces.size === 0;
}
isValid() {
let e44 = true;
for (let t2 of this.faces)
if (!t2.isSimple(this.edges)) {
e44 = false;
break;
}
return e44;
}
area() {
let e44 = [...this.faces].reduce((e45, t2) => e45 + t2.signedArea(), 0);
return Math.abs(e44);
}
addFace(...e44) {
let t2 = new kY.Face(this, ...e44);
return this.faces.add(t2), t2;
}
deleteFace(e44) {
for (let t2 of e44)
this.edges.delete(t2);
return this.faces.delete(e44);
}
recreateFaces() {
this.faces.clear();
for (let e45 of this.edges)
e45.face = null;
let e44, t2 = true;
for (;t2; ) {
t2 = false;
for (let n2 of this.edges)
if (n2.face === null) {
e44 = n2, t2 = true;
break;
}
if (t2) {
let t3 = e44;
do {
t3 = t3.next;
} while (t3.next !== e44);
this.addFace(e44, t3);
}
}
}
removeChain(e44, t2, n2) {
if (n2.next !== t2) {
for (let o2 = t2;o2 !== n2.next; o2 = o2.next)
if (e44.remove(o2), this.edges.delete(o2), e44.isEmpty()) {
this.deleteFace(e44);
break;
}
} else
this.deleteFace(e44);
}
addVertex(e44, t2) {
let n2 = t2.shape.split(e44);
if (n2[0] === null)
return t2.prev;
if (n2[1] === null)
return t2;
let o2 = new kY.Edge(n2[0]), i2 = t2.prev;
return t2.face.insert(o2, i2), this.edges.delete(t2), this.edges.add(o2), t2.shape = n2[1], this.edges.add(t2), o2;
}
removeEndVertex(e44) {
const t2 = e44.next;
t2 !== e44 && (e44.face.merge_with_next_edge(e44), this.edges.delete(t2));
}
cut(e44) {
const t2 = this.splitToIslands().flatMap((t3) => t3._cutSingleIsland(e44)).filter((e45) => e45.isValid() && e45.isEmpty() === false);
return this.createFromArray(t2);
}
_cutSingleIsland(e44) {
let t2 = this.clone();
const n2 = e44.clone();
let o2, i2, r2 = { int_points1: [], int_points2: [], int_points1_sorted: [], int_points2_sorted: [] };
for (let e45 of n2.edges)
for (let n3 of t2.edges) {
let t3 = sX(e45, n3);
for (let o3 of t3)
yX(e45, o3, r2.int_points1), yX(n3, o3, r2.int_points2);
}
if (r2.int_points1.length === 0)
return t2;
r2.int_points1_sorted = xX(r2.int_points1), r2.int_points2_sorted = xX(r2.int_points2), MX(n2, r2.int_points1_sorted), MX(t2, r2.int_points2_sorted), IX(r2), r2.int_points1_sorted = xX(r2.int_points1), r2.int_points2_sorted = xX(r2.int_points2), SX(r2.int_points1), CX(r2.int_points1, t2);
for (let e45 of r2.int_points1_sorted)
e45.edge_before && e45.edge_after && e45.edge_before.bv === e45.edge_after.bv && (r2.int_points2[e45.id] = -1, e45.id = -1);
if (r2.int_points1 = r2.int_points1.filter((e45) => e45.id >= 0), r2.int_points2 = r2.int_points2.filter((e45) => e45.id >= 0), r2.int_points1.forEach((e45, t3) => {
e45.id = t3;
}), r2.int_points2.forEach((e45, t3) => {
e45.id = t3;
}), r2.int_points1.length === 0)
return t2;
r2.int_points1_sorted = xX(r2.int_points1), r2.int_points2_sorted = xX(r2.int_points2);
for (let e45 = 1;e45 < r2.int_points1_sorted.length; e45++)
if (i2 = r2.int_points1_sorted[e45], o2 = r2.int_points1_sorted[e45 - 1], i2.edge_before && i2.edge_before.bv === 1) {
let e46 = o2.edge_after, s2 = i2.edge_before, a2 = n2.getChain(e46, s2);
wX(r2.int_points2[o2.id], r2.int_points2[i2.id], a2), a2.forEach((e47) => t2.edges.add(e47)), a2 = a2.reverse().map((e47) => new kY.Edge(e47.shape.reverse()));
for (let e47 = 0;e47 < a2.length - 1; e47++)
a2[e47].next = a2[e47 + 1], a2[e47 + 1].prev = a2[e47];
wX(r2.int_points2[i2.id], r2.int_points2[o2.id], a2), a2.forEach((e47) => t2.edges.add(e47));
}
return t2.recreateFaces(), t2;
}
cutWithLine(e44) {
let t2 = new _X([e44]);
return this.cut(t2);
}
findEdgeByPoint(e44) {
let t2;
for (let n2 of this.faces)
if (t2 = n2.findEdgeByPoint(e44), t2 !== undefined)
break;
return t2;
}
splitToIslands() {
if (this.isEmpty())
return [];
let e44 = this.toArray();
e44.sort((e45, t3) => t3.area() - e45.area());
let t2 = [...e44[0].faces][0].orientation(), n2 = e44.filter((e45) => [...e45.faces][0].orientation() === t2);
for (let o2 of e44) {
let e45 = [...o2.faces][0];
if (e45.orientation() !== t2) {
for (let t3 of n2)
if (e45.shapes.every((e46) => t3.contains(e46))) {
t3.addFace(e45.shapes);
break;
}
}
}
return n2;
}
rearrange() {
if (this.faces.size <= 1)
return this.clone();
const t2 = this.splitToIslands(), n2 = new e43;
return t2.forEach((e44) => {
e44.faces.forEach((e45) => n2.addFace(e45.shapes));
}), n2;
}
orientation() {
return this.isEmpty() ? CY.NOT_ORIENTABLE : [...this.faces][0].orientation();
}
isOuter(e44) {
return e44.orientation() === this.orientation();
}
isMultiPolygon() {
let e44 = 0;
return this.faces.forEach((t2) => {
this.isOuter(t2) && e44++;
}), e44 > 1;
}
reverse() {
for (let e44 of this.faces)
e44.reverse();
return this;
}
contains(e44) {
if (e44 instanceof kY.Point) {
let t2 = iW(this, e44);
return t2 === 1 || t2 === 2;
}
return cW(this, e44);
}
distanceTo(e44) {
if (e44 instanceof kY.Point) {
let [t2, n2] = kY.Distance.point2polygon(e44, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e44 instanceof kY.Circle || e44 instanceof kY.Line || e44 instanceof kY.Segment || e44 instanceof kY.Arc) {
let [t2, n2] = kY.Distance.shape2polygon(e44, this);
return n2 = n2.reverse(), [t2, n2];
}
if (e44 instanceof kY.Polygon) {
let t2, n2, o2 = [Number.POSITIVE_INFINITY, new kY.Segment];
for (let i2 of this.edges) {
let r2 = o2[0];
[t2, n2] = kY.Distance.shape2planarSet(i2.shape, e44.edges, r2), kY.Utils.LT(t2, r2) && (o2 = [t2, n2]);
}
return o2;
}
}
intersect(e44) {
return e44 instanceof kY.Point ? this.contains(e44) ? [e44] : [] : e44 instanceof kY.Line ? iX(e44, this) : e44 instanceof kY.Ray ? mX(e44, this) : e44 instanceof kY.Circle ? rX(e44, this) : e44 instanceof kY.Segment ? nX(e44, this) : e44 instanceof kY.Arc ? oX(e44, this) : e44 instanceof kY.Polygon ? function(e45, t2) {
let n2 = [];
if (e45.isEmpty() || t2.isEmpty())
return n2;
if (e45.box.not_intersect(t2.box))
return n2;
for (let o2 of e45.edges)
n2 = [...n2, ...aX(o2, t2)];
return n2;
}(e44, this) : e44 instanceof kY.Multiline ? function(e45, t2) {
let n2 = [];
if (t2.isEmpty() || e45.size === 0)
return n2;
for (let o2 of e45)
n2 = [...n2, ...aX(o2, t2)];
return n2;
}(e44, this) : undefined;
}
translate(t2) {
let n2 = new e43;
for (let e44 of this.faces)
n2.addFace(e44.shapes.map((e45) => e45.translate(t2)));
return n2;
}
rotate(t2 = 0, n2 = new kY.Point) {
let o2 = new e43;
for (let e44 of this.faces)
o2.addFace(e44.shapes.map((e45) => e45.rotate(t2, n2)));
return o2;
}
scale(t2, n2) {
let o2 = new e43;
for (let e44 of this.faces)
o2.addFace(e44.shapes.map((e45) => e45.scale(t2, n2)));
return o2;
}
transform(t2 = new kY.Matrix) {
let n2 = new e43;
for (let e44 of this.faces)
n2.addFace(e44.shapes.map((e45) => e45.transform(t2)));
return n2;
}
toJSON() {
return [...this.faces].map((e44) => e44.toJSON());
}
toArray() {
return [...this.faces].map((e44) => e44.toPolygon());
}
dpath() {
return [...this.faces].reduce((e44, t2) => e44 + t2.svg(), "");
}
svg(e44 = {}) {
let t2 = `
<path ${FY({ fillRule: "evenodd", fill: "lightcyan", ...e44 })} d="`;
for (let e45 of this.faces)
t2 += `
${e45.svg()}`;
return t2 += `" >
</path>`, t2;
}
};
kY.polygon = (...e44) => new kY.Polygon(...e44);
var { Circle: SW, Line: CW, Point: PW, Vector: MW, Utils: wW } = kY;
kY.Inversion = class e44 {
constructor(e45) {
this.circle = e45;
}
get inversion_circle() {
return this.circle;
}
static inversePoint(e45, t2) {
const n2 = new MW(e45.pc, t2), o2 = e45.r * e45.r, i2 = n2.dot(n2);
return wW.EQ_0(i2) ? new PW(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY) : e45.pc.translate(n2.multiply(o2 / i2));
}
static inverseCircle(e45, t2) {
const n2 = e45.pc.distanceTo(t2.pc)[0];
if (wW.EQ(n2, t2.r)) {
let n3 = e45.r * e45.r / (2 * t2.r), o2 = new MW(e45.pc, t2.pc);
o2 = o2.normalize();
let i2 = e45.pc.translate(o2.multiply(n3));
return new CW(i2, o2);
}
{
let n3 = new MW(e45.pc, t2.pc), o2 = e45.r * e45.r / (n3.dot(n3) - t2.r * t2.r), i2 = e45.pc.translate(n3.multiply(o2)), r2 = Math.abs(o2) * t2.r;
return new SW(i2, r2);
}
}
static inverseLine(e45, t2) {
const [n2, o2] = e45.pc.distanceTo(t2);
if (wW.EQ_0(n2))
return t2.clone();
{
let t3 = e45.r * e45.r / (2 * n2), i2 = new MW(e45.pc, o2.end);
return i2 = i2.multiply(t3 / n2), new SW(e45.pc.translate(i2), t3);
}
}
inverse(t2) {
return t2 instanceof PW ? e44.inversePoint(this.circle, t2) : t2 instanceof SW ? e44.inverseCircle(this.circle, t2) : t2 instanceof CW ? e44.inverseLine(this.circle, t2) : undefined;
}
};
kY.inversion = (e45) => new kY.Inversion(e45);
kY.Distance = class e45 {
static point2point(e46, t2) {
return e46.distanceTo(t2);
}
static point2line(e46, t2) {
let n2 = e46.projectionOn(t2);
return [new kY.Vector(e46, n2).length, new kY.Segment(e46, n2)];
}
static point2circle(e46, t2) {
let [n2, o2] = e46.distanceTo(t2.center);
if (kY.Utils.EQ_0(n2))
return [t2.r, new kY.Segment(e46, t2.toArc().start)];
{
let o3 = Math.abs(n2 - t2.r), i2 = new kY.Vector(t2.pc, e46).normalize().multiply(t2.r), r2 = t2.pc.translate(i2);
return [o3, new kY.Segment(e46, r2)];
}
}
static point2segment(t2, n2) {
if (n2.start.equalTo(n2.end))
return e45.point2point(t2, n2.start);
let o2, i2, r2 = new kY.Vector(n2.start, n2.end), s2 = new kY.Vector(n2.start, t2), a2 = new kY.Vector(n2.end, t2), c2 = r2.dot(s2), l2 = -r2.dot(a2);
if (kY.Utils.GE(c2, 0) && kY.Utils.GE(l2, 0)) {
let e46 = n2.tangentInStart();
return o2 = Math.abs(e46.cross(s2)), i2 = n2.start.translate(e46.multiply(e46.dot(s2))), [o2, new kY.Segment(t2, i2)];
}
return c2 < 0 ? t2.distanceTo(n2.start) : t2.distanceTo(n2.end);
}
static point2arc(t2, n2) {
let o2, i2, r2 = new kY.Circle(n2.pc, n2.r), s2 = [];
return [o2, i2] = e45.point2circle(t2, r2), i2.end.on(n2) && s2.push(e45.point2circle(t2, r2)), s2.push(e45.point2point(t2, n2.start)), s2.push(e45.point2point(t2, n2.end)), e45.sort(s2), s2[0];
}
static point2edge(t2, n2) {
return n2.shape instanceof kY.Segment ? e45.point2segment(t2, n2.shape) : e45.point2arc(t2, n2.shape);
}
static segment2line(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let i2 = [];
return i2.push(e45.point2line(t2.start, n2)), i2.push(e45.point2line(t2.end, n2)), e45.sort(i2), i2[0];
}
static segment2segment(t2, n2) {
let o2 = VY(t2, n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let i2, r2, s2 = [];
return [i2, r2] = e45.point2segment(n2.start, t2), s2.push([i2, r2.reverse()]), [i2, r2] = e45.point2segment(n2.end, t2), s2.push([i2, r2.reverse()]), s2.push(e45.point2segment(t2.start, n2)), s2.push(e45.point2segment(t2.end, n2)), e45.sort(s2), s2[0];
}
static segment2circle(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let i2 = new kY.Line(t2.ps, t2.pe), [r2, s2] = e45.point2line(n2.center, i2);
if (kY.Utils.GE(r2, n2.r) && s2.end.on(t2))
return e45.point2circle(s2.end, n2);
{
let [o3, i3] = e45.point2circle(t2.start, n2), [r3, s3] = e45.point2circle(t2.end, n2);
return kY.Utils.LT(o3, r3) ? [o3, i3] : [r3, s3];
}
}
static segment2arc(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let i2 = new kY.Line(t2.ps, t2.pe), r2 = new kY.Circle(n2.pc, n2.r), [s2, a2] = e45.point2line(r2.center, i2);
if (kY.Utils.GE(s2, r2.r) && a2.end.on(t2)) {
let [t3, o3] = e45.point2circle(a2.end, r2);
if (o3.end.on(n2))
return [t3, o3];
}
let c2, l2, h2 = [];
return h2.push(e45.point2arc(t2.start, n2)), h2.push(e45.point2arc(t2.end, n2)), [c2, l2] = e45.point2segment(n2.start, t2), h2.push([c2, l2.reverse()]), [c2, l2] = e45.point2segment(n2.end, t2), h2.push([c2, l2.reverse()]), e45.sort(h2), h2[0];
}
static circle2circle(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
if (t2.center.equalTo(n2.center)) {
let o3 = t2.toArc(), i2 = n2.toArc();
return e45.point2point(o3.start, i2.start);
}
{
let o3 = new kY.Line(t2.center, n2.center), i2 = o3.intersect(t2), r2 = o3.intersect(n2), s2 = [];
return s2.push(e45.point2point(i2[0], r2[0])), s2.push(e45.point2point(i2[0], r2[1])), s2.push(e45.point2point(i2[1], r2[0])), s2.push(e45.point2point(i2[1], r2[1])), e45.sort(s2), s2[0];
}
}
static circle2line(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let [i2, r2] = e45.point2line(t2.center, n2), [s2, a2] = e45.point2circle(r2.end, t2);
return a2 = a2.reverse(), [s2, a2];
}
static arc2line(t2, n2) {
let o2 = n2.intersect(t2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let i2 = new kY.Circle(t2.center, t2.r), [r2, s2] = e45.point2line(i2.center, n2);
if (!kY.Utils.GE(r2, i2.r)) {
let o3 = [];
return o3.push(e45.point2line(t2.start, n2)), o3.push(e45.point2line(t2.end, n2)), e45.sort(o3), o3[0];
}
{
let [n3, o3] = e45.point2circle(s2.end, i2);
if (o3.end.on(t2))
return [n3, o3];
}
}
static arc2circle(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let i2 = new kY.Circle(t2.center, t2.r), [r2, s2] = e45.circle2circle(i2, n2);
if (s2.start.on(t2))
return [r2, s2];
{
let o3 = [];
return o3.push(e45.point2circle(t2.start, n2)), o3.push(e45.point2circle(t2.end, n2)), e45.sort(o3), o3[0];
}
}
static arc2arc(t2, n2) {
let o2 = t2.intersect(n2);
if (o2.length > 0)
return [0, new kY.Segment(o2[0], o2[0])];
let i2 = new kY.Circle(t2.center, t2.r), r2 = new kY.Circle(n2.center, n2.r), [s2, a2] = e45.circle2circle(i2, r2);
if (a2.start.on(t2) && a2.end.on(n2))
return [s2, a2];
{
let o3, i3, r3 = [];
return [o3, i3] = e45.point2arc(t2.start, n2), i3.end.on(n2) && r3.push([o3, i3]), [o3, i3] = e45.point2arc(t2.end, n2), i3.end.on(n2) && r3.push([o3, i3]), [o3, i3] = e45.point2arc(n2.start, t2), i3.end.on(t2) && r3.push([o3, i3.reverse()]), [o3, i3] = e45.point2arc(n2.end, t2), i3.end.on(t2) && r3.push([o3, i3.reverse()]), [o3, i3] = e45.point2point(t2.start, n2.start), r3.push([o3, i3]), [o3, i3] = e45.point2point(t2.start, n2.end), r3.push([o3, i3]), [o3, i3] = e45.point2point(t2.end, n2.start), r3.push([o3, i3]), [o3, i3] = e45.point2point(t2.end, n2.end), r3.push([o3, i3]), e45.sort(r3), r3[0];
}
}
static point2polygon(t2, n2) {
let o2 = [Number.POSITIVE_INFINITY, new kY.Segment];
for (let i2 of n2.edges) {
let [n3, r2] = e45.point2edge(t2, i2);
kY.Utils.LT(n3, o2[0]) && (o2 = [n3, r2]);
}
return o2;
}
static shape2polygon(e46, t2) {
let n2 = [Number.POSITIVE_INFINITY, new kY.Segment];
for (let o2 of t2.edges) {
let [t3, i2] = e46.distanceTo(o2.shape);
kY.Utils.LT(t3, n2[0]) && (n2 = [t3, i2]);
}
return n2;
}
static polygon2polygon(e46, t2) {
let n2 = [Number.POSITIVE_INFINITY, new kY.Segment];
for (let o2 of e46.edges)
for (let e47 of t2.edges) {
let [t3, i2] = o2.shape.distanceTo(e47.shape);
kY.Utils.LT(t3, n2[0]) && (n2 = [t3, i2]);
}
return n2;
}
static box2box_minmax(e46, t2) {
let n2 = Math.max(Math.max(e46.xmin - t2.xmax, 0), Math.max(t2.xmin - e46.xmax, 0)), o2 = Math.max(Math.max(e46.ymin - t2.ymax, 0), Math.max(t2.ymin - e46.ymax, 0)), i2 = n2 * n2 + o2 * o2, r2 = e46.merge(t2), s2 = r2.xmax - r2.xmin, a2 = r2.ymax - r2.ymin;
return [i2, s2 * s2 + a2 * a2];
}
static minmax_tree_process_level(t2, n2, o2, i2) {
let r2, s2;
for (let a3 of n2) {
[r2, s2] = e45.box2box_minmax(t2.box, a3.item.key);
for (let e46 of a3.item.values)
e46 instanceof kY.Edge ? i2.insert([r2, s2], e46.shape) : i2.insert([r2, s2], e46);
kY.Utils.LT(s2, o2) && (o2 = s2);
}
if (n2.length === 0)
return o2;
let a2 = [...n2.map((e46) => e46.left.isNil() ? undefined : e46.left).filter((e46) => e46 !== undefined), ...n2.map((e46) => e46.right.isNil() ? undefined : e46.right).filter((e46) => e46 !== undefined)].filter((n3) => {
let [i3, r3] = e45.box2box_minmax(t2.box, n3.max);
return kY.Utils.LE(i3, o2);
});
return o2 = e45.minmax_tree_process_level(t2, a2, o2, i2);
}
static minmax_tree(t2, n2, o2) {
let i2 = new _W, r2 = [n2.index.root], s2 = o2 < Number.POSITIVE_INFINITY ? o2 * o2 : Number.POSITIVE_INFINITY;
return s2 = e45.minmax_tree_process_level(t2, r2, s2, i2), i2;
}
static minmax_tree_calc_distance(t2, n2, o2) {
let i2, r2;
if (n2 != null && !n2.isNil()) {
if ([i2, r2] = e45.minmax_tree_calc_distance(t2, n2.left, o2), r2)
return [i2, r2];
if (kY.Utils.LT(i2[0], Math.sqrt(n2.item.key.low)))
return [i2, true];
let [s2, a2] = e45.distanceToArray(t2, n2.item.values);
return kY.Utils.LT(s2, i2[0]) && (i2 = [s2, a2]), [i2, r2] = e45.minmax_tree_calc_distance(t2, n2.right, i2), [i2, r2];
}
return [o2, false];
}
static shape2planarSet(t2, n2, o2 = Number.POSITIVE_INFINITY) {
let i2 = [o2, new kY.Segment], r2 = false;
if (n2 instanceof kY.PlanarSet) {
let s2 = e45.minmax_tree(t2, n2, o2);
[i2, r2] = e45.minmax_tree_calc_distance(t2, s2.root, i2);
}
return i2;
}
static sort(e46) {
e46.sort((e47, t2) => kY.Utils.LT(e47[0], t2[0]) ? -1 : kY.Utils.GT(e47[0], t2[0]) ? 1 : 0);
}
static distance(e46, t2) {
return e46.distanceTo(t2);
}
static distanceToArray(e46, t2) {
let n2 = [Number.POSITIVE_INFINITY, new kY.Segment];
for (let o2 of t2) {
let [t3, i2] = e46.distanceTo(o2);
kY.Utils.LT(t3, n2[0]) && (n2 = [t3, i2]);
}
return n2;
}
static shape2multiline(t2, n2) {
let o2 = [Number.POSITIVE_INFINITY, new kY.Segment];
for (let i2 of n2) {
let [n3, r2] = e45.distance(t2, i2.shape);
kY.Utils.LT(n3, o2[0]) && (o2 = [n3, r2]);
}
return o2;
}
static multiline2multiline(t2, n2) {
let o2 = [Number.POSITIVE_INFINITY, new kY.Segment];
for (let i2 of t2)
for (let t3 of n2) {
let [n3, r2] = e45.distance(i2.shape, t3.shape);
kY.Utils.LT(n3, o2[0]) && (o2 = [n3, r2]);
}
return o2;
}
};
var { Multiline: NW, Point: TW, Segment: RW, Polygon: EW } = kY;
function AW(e46) {
return new TW(e46.split(" ").map(Number));
}
function OW(e46) {
return e46.split(", ").map(AW);
}
function kW(e46) {
const t2 = OW(e46);
let n2 = [];
for (let e47 = 0;e47 < t2.length - 1; e47++)
n2.push(new RW(t2[e47], t2[e47 + 1]));
return new NW(n2);
}
function DW(e46) {
const t2 = e46.replace(/\(\(/, "").replace(/\)\)$/, "").split("), ("), n2 = new EW;
let o2;
return t2.forEach((e47, t3) => {
let i2 = e47.split(", ").map((e48) => new TW(e48.split(" ").map(Number)));
const r2 = n2.addFace(i2);
t3 === 0 ? o2 = r2.orientation() : r2.orientation() === o2 && r2.reverse();
}), n2;
}
function LW(e46) {
if (e46.startsWith("POLYGON")) {
return DW(e46.replace(/^POLYGON /, ""));
}
return function(e47) {
const t2 = e47.split(/\)\), \(\(/).map((e48) => "((" + e48 + "))").map(DW), n2 = new EW;
return t2.reduce((e48, t3) => [...e48, ...t3?.faces], []).forEach((e48) => n2.addFace([...e48?.shapes])), n2;
}(e46.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/, "$1"));
}
function zW(e46) {
return e46.split(`
`)?.every((e47) => e47.includes("POINT"));
}
function BW(e46) {
return e46.split(`
`)?.every((e47) => e47.includes("LINESTRING"));
}
kY.isWktString = function(e47) {
return e47.startsWith("POINT") || zW(e47) || e47.startsWith("LINESTRING") || BW(e47) || e47.startsWith("MULTILINESTRING") || e47.startsWith("POLYGON") || e47.startsWith("MULTIPOINT") || e47.startsWith("MULTIPOLYGON") || e47.startsWith("GEOMETRYCOLLECTION");
}, kY.parseWKT = function e46(t2) {
if (t2.startsWith("POINT")) {
return AW(t2.replace(/^POINT \(/, "").replace(/\)$/, ""));
}
if (t2.startsWith("MULTIPOINT")) {
return OW(t2.replace(/^MULTIPOINT \(/, "").replace(/\)$/, ""));
}
if (t2.startsWith("LINESTRING")) {
return kW(t2.replace(/^LINESTRING \(/, "").replace(/\)$/, ""));
}
if (t2.startsWith("MULTILINESTRING")) {
return function(e47) {
return e47.replace(/\(\(/, "").replace(/\)\)$/, "").split("), (").map(kW);
}(t2.replace(/^MULTILINESTRING /, ""));
}
if (t2.startsWith("POLYGON") || t2.startsWith("MULTIPOLYGON"))
return LW(t2);
if (t2.startsWith("GEOMETRYCOLLECTION")) {
const n2 = /(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g, o2 = t2.match(n2);
o2[0].startsWith("GEOMETRYCOLLECTION") && (o2[0] = o2[0].replace("GEOMETRYCOLLECTION (", ""));
return o2.map(e46).map((e47) => e47 instanceof Array ? e47 : [e47]).reduce((e47, t3) => [...e47, ...t3], []);
}
return zW(t2) ? function(e47) {
return e47.split(`
`).map((e48) => e48.match(/\(([^)]+)\)/)[1]).map(AW);
}(t2) : BW(t2) ? function(e47) {
return e47.split(`
`).map((e48) => e48.match(/\(([^)]+)\)/)[1]).map(kW).reduce((e48, t3) => [...e48, ...t3], []);
}(t2) : [];
}, kY.BooleanOperations = JX, kY.Relations = uW;
FW = S$(), jW = 1, $W = FW != null ? i$(c$(FW)) : {}, ((e47, t2, n2, o2) => {
if (t2 && typeof t2 == "object" || typeof t2 == "function")
for (let i2 of a$(t2))
l$.call(e47, i2) || i2 === n2 || r$(e47, i2, { get: () => t2[i2], enumerable: !(o2 = s$(t2, i2)) || o2.enumerable });
})(!jW && FW && FW.__esModule ? $W : r$($W, "default", { value: FW, enumerable: true }), FW);
var FW;
var jW;
var $W;
var YW = Object.create;
var XW = Object.defineProperty;
var WW = Object.getOwnPropertyDescriptor;
var VW = Object.getOwnPropertyNames;
var HW = Object.getPrototypeOf;
var GW = Object.prototype.hasOwnProperty;
var UW = (e47, t2) => function() {
return t2 || (0, e47[VW(e47)[0]])((t2 = { exports: {} }).exports, t2), t2.exports;
};
var ZW = (e47, t2, n2) => (n2 = e47 != null ? YW(HW(e47)) : {}, ((e48, t3, n3, o2) => {
if (t3 && typeof t3 == "object" || typeof t3 == "function")
for (let i2 of VW(t3))
GW.call(e48, i2) || i2 === n3 || XW(e48, i2, { get: () => t3[i2], enumerable: !(o2 = WW(t3, i2)) || o2.enumerable });
return e48;
})(e47 && e47.__esModule ? n2 : XW(n2, "default", { value: e47, enumerable: true }), e47));
var qW = UW({ "node_modules/is-buffer/index.js"(e47, t2) {
function n2(e48) {
return !!e48.constructor && typeof e48.constructor.isBuffer == "function" && e48.constructor.isBuffer(e48);
}
t2.exports = function(e48) {
return e48 != null && (n2(e48) || function(e49) {
return typeof e49.readFloatLE == "function" && typeof e49.slice == "function" && n2(e49.slice(0, 0));
}(e48) || !!e48._isBuffer);
};
} });
var JW = UW({ "node_modules/kind-of/index.js"(e47, t2) {
var n2 = qW(), o2 = Object.prototype.toString;
t2.exports = function(e48) {
if (e48 === undefined)
return "undefined";
if (e48 === null)
return "null";
if (e48 === true || e48 === false || e48 instanceof Boolean)
return "boolean";
if (typeof e48 == "string" || e48 instanceof String)
return "string";
if (typeof e48 == "number" || e48 instanceof Number)
return "number";
if (typeof e48 == "function" || e48 instanceof Function)
return "function";
if (Array.isArray !== undefined && Array.isArray(e48))
return "array";
if (e48 instanceof RegExp)
return "regexp";
if (e48 instanceof Date)
return "date";
var t3 = o2.call(e48);
return t3 === "[object RegExp]" ? "regexp" : t3 === "[object Date]" ? "date" : t3 === "[object Arguments]" ? "arguments" : t3 === "[object Error]" ? "error" : n2(e48) ? "buffer" : t3 === "[object Set]" ? "set" : t3 === "[object WeakSet]" ? "weakset" : t3 === "[object Map]" ? "map" : t3 === "[object WeakMap]" ? "weakmap" : t3 === "[object Symbol]" ? "symbol" : t3 === "[object Int8Array]" ? "int8array" : t3 === "[object Uint8Array]" ? "uint8array" : t3 === "[object Uint8ClampedArray]" ? "uint8clampedarray" : t3 === "[object Int16Array]" ? "int16array" : t3 === "[object Uint16Array]" ? "uint16array" : t3 === "[object Int32Array]" ? "int32array" : t3 === "[object Uint32Array]" ? "uint32array" : t3 === "[object Float32Array]" ? "float32array" : t3 === "[object Float64Array]" ? "float64array" : "object";
};
} });
var QW = UW({ "node_modules/rename-keys/index.js"(e47, t2) {
(function() {
function e48(e49, t3) {
if (typeof t3 != "function")
return e49;
var n2 = {};
for (var o2 in e49)
Object.prototype.hasOwnProperty.call(e49, o2) && (n2[t3(o2, e49[o2]) || o2] = e49[o2]);
return n2;
}
t2 !== undefined && t2.exports ? t2.exports = e48 : typeof define == "function" && define.amd ? define([], function() {
return e48;
}) : window.rename = e48;
})();
} });
var KW = UW({ "node_modules/deep-rename-keys/index.js"(e47, t2) {
var n2 = JW(), o2 = QW();
t2.exports = function e48(t3, i2) {
var r2 = n2(t3);
if (r2 !== "object" && r2 !== "array")
throw new Error("expected an object");
var s2 = [];
for (var a2 in r2 === "object" && (t3 = o2(t3, i2), s2 = {}), t3)
if (t3.hasOwnProperty(a2)) {
var c2 = t3[a2];
n2(c2) === "object" || n2(c2) === "array" ? s2[a2] = e48(c2, i2) : s2[a2] = c2;
}
return s2;
};
} });
var eV = UW({ "node_modules/eventemitter3/index.js"(e47, t2) {
var n2 = Object.prototype.hasOwnProperty, o2 = "~";
function i2() {}
function r2(e48, t3, n3) {
this.fn = e48, this.context = t3, this.once = n3 || false;
}
function s2() {
this._events = new i2, this._eventsCount = 0;
}
Object.create && (i2.prototype = Object.create(null), new i2().__proto__ || (o2 = false)), s2.prototype.eventNames = function() {
var e48, t3, i3 = [];
if (this._eventsCount === 0)
return i3;
for (t3 in e48 = this._events)
n2.call(e48, t3) && i3.push(o2 ? t3.slice(1) : t3);
return Object.getOwnPropertySymbols ? i3.concat(Object.getOwnPropertySymbols(e48)) : i3;
}, s2.prototype.listeners = function(e48, t3) {
var n3 = o2 ? o2 + e48 : e48, i3 = this._events[n3];
if (t3)
return !!i3;
if (!i3)
return [];
if (i3.fn)
return [i3.fn];
for (var r3 = 0, s3 = i3.length, a2 = new Array(s3);r3 < s3; r3++)
a2[r3] = i3[r3].fn;
return a2;
}, s2.prototype.emit = function(e48, t3, n3, i3, r3, s3) {
var a2 = o2 ? o2 + e48 : e48;
if (!this._events[a2])
return false;
var c2, l2, h2 = this._events[a2], d2 = arguments.length;
if (h2.fn) {
switch (h2.once && this.removeListener(e48, h2.fn, undefined, true), d2) {
case 1:
return h2.fn.call(h2.context), true;
case 2:
return h2.fn.call(h2.context, t3), true;
case 3:
return h2.fn.call(h2.context, t3, n3), true;
case 4:
return h2.fn.call(h2.context, t3, n3, i3), true;
case 5:
return h2.fn.call(h2.context, t3, n3, i3, r3), true;
case 6:
return h2.fn.call(h2.context, t3, n3, i3, r3, s3), true;
}
for (l2 = 1, c2 = new Array(d2 - 1);l2 < d2; l2++)
c2[l2 - 1] = arguments[l2];
h2.fn.apply(h2.context, c2);
} else {
var u2, p2 = h2.length;
for (l2 = 0;l2 < p2; l2++)
switch (h2[l2].once && this.removeListener(e48, h2[l2].fn, undefined, true), d2) {
case 1:
h2[l2].fn.call(h2[l2].context);
break;
case 2:
h2[l2].fn.call(h2[l2].context, t3);
break;
case 3:
h2[l2].fn.call(h2[l2].context, t3, n3);
break;
case 4:
h2[l2].fn.call(h2[l2].context, t3, n3, i3);
break;
default:
if (!c2)
for (u2 = 1, c2 = new Array(d2 - 1);u2 < d2; u2++)
c2[u2 - 1] = arguments[u2];
h2[l2].fn.apply(h2[l2].context, c2);
}
}
return true;
}, s2.prototype.on = function(e48, t3, n3) {
var i3 = new r2(t3, n3 || this), s3 = o2 ? o2 + e48 : e48;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.once = function(e48, t3, n3) {
var i3 = new r2(t3, n3 || this, true), s3 = o2 ? o2 + e48 : e48;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.removeListener = function(e48, t3, n3, r3) {
var s3 = o2 ? o2 + e48 : e48;
if (!this._events[s3])
return this;
if (!t3)
return --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3], this;
var a2 = this._events[s3];
if (a2.fn)
a2.fn !== t3 || r3 && !a2.once || n3 && a2.context !== n3 || (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3]);
else {
for (var c2 = 0, l2 = [], h2 = a2.length;c2 < h2; c2++)
(a2[c2].fn !== t3 || r3 && !a2[c2].once || n3 && a2[c2].context !== n3) && l2.push(a2[c2]);
l2.length ? this._events[s3] = l2.length === 1 ? l2[0] : l2 : --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3];
}
return this;
}, s2.prototype.removeAllListeners = function(e48) {
var t3;
return e48 ? (t3 = o2 ? o2 + e48 : e48, this._events[t3] && (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[t3])) : (this._events = new i2, this._eventsCount = 0), this;
}, s2.prototype.off = s2.prototype.removeListener, s2.prototype.addListener = s2.prototype.on, s2.prototype.setMaxListeners = function() {
return this;
}, s2.prefixed = o2, s2.EventEmitter = s2, t2 !== undefined && (t2.exports = s2);
} });
var tV = UW({ "node_modules/xml-lexer/dist/lexer.js"(e47, t2) {
function n2(e48, t3, n3) {
return t3 in e48 ? Object.defineProperty(e48, t3, { value: n3, enumerable: true, configurable: true, writable: true }) : e48[t3] = n3, e48;
}
var o2 = eV(), i2 = function() {}, r2 = { 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" }, s2 = { lt: "action-lt", gt: "action-gt", space: "action-space", equal: "action-equal", quote: "action-quote", slash: "action-slash", char: "action-char", error: "action-error" }, a2 = { text: "text", openTag: "open-tag", closeTag: "close-tag", attributeName: "attribute-name", attributeValue: "attribute-value" }, c2 = { " ": s2.space, "\t": s2.space, "\n": s2.space, "\r": s2.space, "<": s2.lt, ">": s2.gt, '"': s2.quote, "'": s2.quote, "=": s2.equal, "/": s2.slash };
t2.exports = { State: r2, Action: s2, Type: a2, create: function(e48) {
var t3, l2, h2, d2, u2, p2, m2, g2, f2, _2;
e48 = Object.assign({ debug: false }, e48);
var y2 = new o2, b2 = r2.data, x2 = "", v2 = "", I2 = "", S2 = "", C2 = "", P2 = "", M2 = function(t4, n3) {
if (v2[0] !== "?" && v2[0] !== "!") {
var o3 = { type: t4, value: n3 };
e48.debug && console.log("emit:", o3), y2.emit("data", o3);
}
};
y2.stateMachine = (n2(_2 = {}, r2.data, (n2(t3 = {}, s2.lt, function() {
x2.trim() && M2(a2.text, x2), v2 = "", C2 = false, b2 = r2.tagBegin;
}), n2(t3, s2.char, function(e49) {
x2 += e49;
}), t3)), n2(_2, r2.cdata, n2({}, s2.char, function(e49) {
(x2 += e49).substr(-3) === "]]>" && (M2(a2.text, x2.slice(0, -3)), x2 = "", b2 = r2.data);
})), n2(_2, r2.tagBegin, (n2(l2 = {}, s2.space, i2), n2(l2, s2.char, function(e49) {
v2 = e49, b2 = r2.tagName;
}), n2(l2, s2.slash, function() {
v2 = "", C2 = true;
}), l2)), n2(_2, r2.tagName, (n2(h2 = {}, s2.space, function() {
C2 ? b2 = r2.tagEnd : (b2 = r2.attributeNameStart, M2(a2.openTag, v2));
}), n2(h2, s2.gt, function() {
M2(C2 ? a2.closeTag : a2.openTag, v2), x2 = "", b2 = r2.data;
}), n2(h2, s2.slash, function() {
b2 = r2.tagEnd, M2(a2.openTag, v2);
}), n2(h2, s2.char, function(e49) {
(v2 += e49) === "![CDATA[" && (b2 = r2.cdata, x2 = "", v2 = "");
}), h2)), n2(_2, r2.tagEnd, (n2(d2 = {}, s2.gt, function() {
M2(a2.closeTag, v2), x2 = "", b2 = r2.data;
}), n2(d2, s2.char, i2), d2)), n2(_2, r2.attributeNameStart, (n2(u2 = {}, s2.char, function(e49) {
I2 = e49, b2 = r2.attributeName;
}), n2(u2, s2.gt, function() {
x2 = "", b2 = r2.data;
}), n2(u2, s2.space, i2), n2(u2, s2.slash, function() {
C2 = true, b2 = r2.tagEnd;
}), u2)), n2(_2, r2.attributeName, (n2(p2 = {}, s2.space, function() {
b2 = r2.attributeNameEnd;
}), n2(p2, s2.equal, function() {
M2(a2.attributeName, I2), b2 = r2.attributeValueBegin;
}), n2(p2, s2.gt, function() {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), x2 = "", b2 = r2.data;
}), n2(p2, s2.slash, function() {
C2 = true, S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), b2 = r2.tagEnd;
}), n2(p2, s2.char, function(e49) {
I2 += e49;
}), p2)), n2(_2, r2.attributeNameEnd, (n2(m2 = {}, s2.space, i2), n2(m2, s2.equal, function() {
M2(a2.attributeName, I2), b2 = r2.attributeValueBegin;
}), n2(m2, s2.gt, function() {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), x2 = "", b2 = r2.data;
}), n2(m2, s2.char, function(e49) {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), I2 = e49, b2 = r2.attributeName;
}), m2)), n2(_2, r2.attributeValueBegin, (n2(g2 = {}, s2.space, i2), n2(g2, s2.quote, function(e49) {
P2 = e49, S2 = "", b2 = r2.attributeValue;
}), n2(g2, s2.gt, function() {
M2(a2.attributeValue, S2 = ""), x2 = "", b2 = r2.data;
}), n2(g2, s2.char, function(e49) {
P2 = "", S2 = e49, b2 = r2.attributeValue;
}), g2)), n2(_2, r2.attributeValue, (n2(f2 = {}, s2.space, function(e49) {
P2 ? S2 += e49 : (M2(a2.attributeValue, S2), b2 = r2.attributeNameStart);
}), n2(f2, s2.quote, function(e49) {
P2 === e49 ? (M2(a2.attributeValue, S2), b2 = r2.attributeNameStart) : S2 += e49;
}), n2(f2, s2.gt, function(e49) {
P2 ? S2 += e49 : (M2(a2.attributeValue, S2), x2 = "", b2 = r2.data);
}), n2(f2, s2.slash, function(e49) {
P2 ? S2 += e49 : (M2(a2.attributeValue, S2), C2 = true, b2 = r2.tagEnd);
}), n2(f2, s2.char, function(e49) {
S2 += e49;
}), f2)), _2);
var w2 = function(t4) {
e48.debug && console.log(b2, t4);
var n3 = y2.stateMachine[b2], o3 = n3[function(e49) {
return c2[e49] || s2.char;
}(t4)] || n3[s2.error] || n3[s2.char];
o3(t4);
};
return y2.write = function(e49) {
for (var t4 = e49.length, n3 = 0;n3 < t4; n3++)
w2(e49[n3]);
}, y2;
} };
} });
var nV = UW({ "node_modules/xml-reader/dist/reader.js"(e47, t2) {
var n2 = eV(), o2 = tV(), i2 = o2.Type, r2 = { element: "element", text: "text" }, s2 = function(e48) {
return Object.assign({ name: "", type: r2.element, value: "", parent: null, attributes: {}, children: [] }, e48);
}, a2 = function(e48) {
e48 = Object.assign({ stream: false, parentNodes: true, doneEvent: "done", tagPrefix: "tag:", emitTopLevelOnly: false, debug: false }, e48);
var t3 = undefined, a3 = undefined, c2 = undefined, l2 = undefined, h2 = new n2, d2 = function(n3) {
switch (n3.type) {
case i2.openTag:
if (c2 === null)
(c2 = a3).name = n3.value;
else {
var o3 = s2({ name: n3.value, parent: c2 });
c2.children.push(o3), c2 = o3;
}
break;
case i2.closeTag:
var d3 = c2.parent;
if (e48.parentNodes || (c2.parent = null), c2.name !== n3.value)
break;
e48.stream && d3 === a3 && (a3.children = [], c2.parent = null), e48.emitTopLevelOnly && d3 !== a3 || (h2.emit(e48.tagPrefix + c2.name, c2), h2.emit("tag", c2.name, c2)), c2 === a3 && (t3.removeAllListeners("data"), h2.emit(e48.doneEvent, c2), a3 = null), c2 = d3;
break;
case i2.text:
c2 && c2.children.push(s2({ type: r2.text, value: n3.value, parent: e48.parentNodes ? c2 : null }));
break;
case i2.attributeName:
l2 = n3.value, c2.attributes[l2] = "";
break;
case i2.attributeValue:
c2.attributes[l2] = n3.value;
}
};
return h2.reset = function() {
(t3 = o2.create({ debug: e48.debug })).on("data", d2), a3 = s2(), c2 = null, l2 = "", h2.parse = t3.write;
}, h2.reset(), h2;
};
t2.exports = { parseSync: function(e48, t3) {
t3 = Object.assign({}, t3, { stream: false, tagPrefix: ":" });
var n3 = a2(t3), o3 = undefined;
return n3.on("done", function(e49) {
o3 = e49;
}), n3.parse(e48), o3;
}, create: a2, NodeType: r2 };
} });
var aV = (ZW(KW()), ZW(nV()), Object.create);
var cV = Object.defineProperty;
var lV = Object.getOwnPropertyDescriptor;
var hV = Object.getOwnPropertyNames;
var dV = Object.getPrototypeOf;
var uV = Object.prototype.hasOwnProperty;
var pV = (e47, t2) => function() {
return t2 || (0, e47[hV(e47)[0]])((t2 = { exports: {} }).exports, t2), t2.exports;
};
var mV = (e47, t2, n2) => (n2 = e47 != null ? aV(dV(e47)) : {}, ((e48, t3, n3, o2) => {
if (t3 && typeof t3 == "object" || typeof t3 == "function")
for (let i2 of hV(t3))
uV.call(e48, i2) || i2 === n3 || cV(e48, i2, { get: () => t3[i2], enumerable: !(o2 = lV(t3, i2)) || o2.enumerable });
return e48;
})(e47 && e47.__esModule ? n2 : cV(n2, "default", { value: e47, enumerable: true }), e47));
var gV = pV({ "node_modules/is-buffer/index.js"(e47, t2) {
function n2(e48) {
return !!e48.constructor && typeof e48.constructor.isBuffer == "function" && e48.constructor.isBuffer(e48);
}
t2.exports = function(e48) {
return e48 != null && (n2(e48) || function(e49) {
return typeof e49.readFloatLE == "function" && typeof e49.slice == "function" && n2(e49.slice(0, 0));
}(e48) || !!e48._isBuffer);
};
} });
var fV = pV({ "node_modules/kind-of/index.js"(e47, t2) {
var n2 = gV(), o2 = Object.prototype.toString;
t2.exports = function(e48) {
if (e48 === undefined)
return "undefined";
if (e48 === null)
return "null";
if (e48 === true || e48 === false || e48 instanceof Boolean)
return "boolean";
if (typeof e48 == "string" || e48 instanceof String)
return "string";
if (typeof e48 == "number" || e48 instanceof Number)
return "number";
if (typeof e48 == "function" || e48 instanceof Function)
return "function";
if (Array.isArray !== undefined && Array.isArray(e48))
return "array";
if (e48 instanceof RegExp)
return "regexp";
if (e48 instanceof Date)
return "date";
var t3 = o2.call(e48);
return t3 === "[object RegExp]" ? "regexp" : t3 === "[object Date]" ? "date" : t3 === "[object Arguments]" ? "arguments" : t3 === "[object Error]" ? "error" : n2(e48) ? "buffer" : t3 === "[object Set]" ? "set" : t3 === "[object WeakSet]" ? "weakset" : t3 === "[object Map]" ? "map" : t3 === "[object WeakMap]" ? "weakmap" : t3 === "[object Symbol]" ? "symbol" : t3 === "[object Int8Array]" ? "int8array" : t3 === "[object Uint8Array]" ? "uint8array" : t3 === "[object Uint8ClampedArray]" ? "uint8clampedarray" : t3 === "[object Int16Array]" ? "int16array" : t3 === "[object Uint16Array]" ? "uint16array" : t3 === "[object Int32Array]" ? "int32array" : t3 === "[object Uint32Array]" ? "uint32array" : t3 === "[object Float32Array]" ? "float32array" : t3 === "[object Float64Array]" ? "float64array" : "object";
};
} });
var _V = pV({ "node_modules/rename-keys/index.js"(e47, t2) {
(function() {
function e48(e49, t3) {
if (typeof t3 != "function")
return e49;
var n2 = {};
for (var o2 in e49)
Object.prototype.hasOwnProperty.call(e49, o2) && (n2[t3(o2, e49[o2]) || o2] = e49[o2]);
return n2;
}
t2 !== undefined && t2.exports ? t2.exports = e48 : typeof define == "function" && define.amd ? define([], function() {
return e48;
}) : window.rename = e48;
})();
} });
var yV = pV({ "node_modules/deep-rename-keys/index.js"(e47, t2) {
var n2 = fV(), o2 = _V();
t2.exports = function e48(t3, i2) {
var r2 = n2(t3);
if (r2 !== "object" && r2 !== "array")
throw new Error("expected an object");
var s2 = [];
for (var a2 in r2 === "object" && (t3 = o2(t3, i2), s2 = {}), t3)
if (t3.hasOwnProperty(a2)) {
var c2 = t3[a2];
n2(c2) === "object" || n2(c2) === "array" ? s2[a2] = e48(c2, i2) : s2[a2] = c2;
}
return s2;
};
} });
var bV = pV({ "node_modules/eventemitter3/index.js"(e47, t2) {
var n2 = Object.prototype.hasOwnProperty, o2 = "~";
function i2() {}
function r2(e48, t3, n3) {
this.fn = e48, this.context = t3, this.once = n3 || false;
}
function s2() {
this._events = new i2, this._eventsCount = 0;
}
Object.create && (i2.prototype = Object.create(null), new i2().__proto__ || (o2 = false)), s2.prototype.eventNames = function() {
var e48, t3, i3 = [];
if (this._eventsCount === 0)
return i3;
for (t3 in e48 = this._events)
n2.call(e48, t3) && i3.push(o2 ? t3.slice(1) : t3);
return Object.getOwnPropertySymbols ? i3.concat(Object.getOwnPropertySymbols(e48)) : i3;
}, s2.prototype.listeners = function(e48, t3) {
var n3 = o2 ? o2 + e48 : e48, i3 = this._events[n3];
if (t3)
return !!i3;
if (!i3)
return [];
if (i3.fn)
return [i3.fn];
for (var r3 = 0, s3 = i3.length, a2 = new Array(s3);r3 < s3; r3++)
a2[r3] = i3[r3].fn;
return a2;
}, s2.prototype.emit = function(e48, t3, n3, i3, r3, s3) {
var a2 = o2 ? o2 + e48 : e48;
if (!this._events[a2])
return false;
var c2, l2, h2 = this._events[a2], d2 = arguments.length;
if (h2.fn) {
switch (h2.once && this.removeListener(e48, h2.fn, undefined, true), d2) {
case 1:
return h2.fn.call(h2.context), true;
case 2:
return h2.fn.call(h2.context, t3), true;
case 3:
return h2.fn.call(h2.context, t3, n3), true;
case 4:
return h2.fn.call(h2.context, t3, n3, i3), true;
case 5:
return h2.fn.call(h2.context, t3, n3, i3, r3), true;
case 6:
return h2.fn.call(h2.context, t3, n3, i3, r3, s3), true;
}
for (l2 = 1, c2 = new Array(d2 - 1);l2 < d2; l2++)
c2[l2 - 1] = arguments[l2];
h2.fn.apply(h2.context, c2);
} else {
var u2, p2 = h2.length;
for (l2 = 0;l2 < p2; l2++)
switch (h2[l2].once && this.removeListener(e48, h2[l2].fn, undefined, true), d2) {
case 1:
h2[l2].fn.call(h2[l2].context);
break;
case 2:
h2[l2].fn.call(h2[l2].context, t3);
break;
case 3:
h2[l2].fn.call(h2[l2].context, t3, n3);
break;
case 4:
h2[l2].fn.call(h2[l2].context, t3, n3, i3);
break;
default:
if (!c2)
for (u2 = 1, c2 = new Array(d2 - 1);u2 < d2; u2++)
c2[u2 - 1] = arguments[u2];
h2[l2].fn.apply(h2[l2].context, c2);
}
}
return true;
}, s2.prototype.on = function(e48, t3, n3) {
var i3 = new r2(t3, n3 || this), s3 = o2 ? o2 + e48 : e48;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.once = function(e48, t3, n3) {
var i3 = new r2(t3, n3 || this, true), s3 = o2 ? o2 + e48 : e48;
return this._events[s3] ? this._events[s3].fn ? this._events[s3] = [this._events[s3], i3] : this._events[s3].push(i3) : (this._events[s3] = i3, this._eventsCount++), this;
}, s2.prototype.removeListener = function(e48, t3, n3, r3) {
var s3 = o2 ? o2 + e48 : e48;
if (!this._events[s3])
return this;
if (!t3)
return --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3], this;
var a2 = this._events[s3];
if (a2.fn)
a2.fn !== t3 || r3 && !a2.once || n3 && a2.context !== n3 || (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3]);
else {
for (var c2 = 0, l2 = [], h2 = a2.length;c2 < h2; c2++)
(a2[c2].fn !== t3 || r3 && !a2[c2].once || n3 && a2[c2].context !== n3) && l2.push(a2[c2]);
l2.length ? this._events[s3] = l2.length === 1 ? l2[0] : l2 : --this._eventsCount === 0 ? this._events = new i2 : delete this._events[s3];
}
return this;
}, s2.prototype.removeAllListeners = function(e48) {
var t3;
return e48 ? (t3 = o2 ? o2 + e48 : e48, this._events[t3] && (--this._eventsCount === 0 ? this._events = new i2 : delete this._events[t3])) : (this._events = new i2, this._eventsCount = 0), this;
}, s2.prototype.off = s2.prototype.removeListener, s2.prototype.addListener = s2.prototype.on, s2.prototype.setMaxListeners = function() {
return this;
}, s2.prefixed = o2, s2.EventEmitter = s2, t2 !== undefined && (t2.exports = s2);
} });
var xV = pV({ "node_modules/xml-lexer/dist/lexer.js"(e47, t2) {
function n2(e48, t3, n3) {
return t3 in e48 ? Object.defineProperty(e48, t3, { value: n3, enumerable: true, configurable: true, writable: true }) : e48[t3] = n3, e48;
}
var o2 = bV(), i2 = function() {}, r2 = { 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" }, s2 = { lt: "action-lt", gt: "action-gt", space: "action-space", equal: "action-equal", quote: "action-quote", slash: "action-slash", char: "action-char", error: "action-error" }, a2 = { text: "text", openTag: "open-tag", closeTag: "close-tag", attributeName: "attribute-name", attributeValue: "attribute-value" }, c2 = { " ": s2.space, "\t": s2.space, "\n": s2.space, "\r": s2.space, "<": s2.lt, ">": s2.gt, '"': s2.quote, "'": s2.quote, "=": s2.equal, "/": s2.slash };
t2.exports = { State: r2, Action: s2, Type: a2, create: function(e48) {
var t3, l2, h2, d2, u2, p2, m2, g2, f2, _2;
e48 = Object.assign({ debug: false }, e48);
var y2 = new o2, b2 = r2.data, x2 = "", v2 = "", I2 = "", S2 = "", C2 = "", P2 = "", M2 = function(t4, n3) {
if (v2[0] !== "?" && v2[0] !== "!") {
var o3 = { type: t4, value: n3 };
e48.debug && console.log("emit:", o3), y2.emit("data", o3);
}
};
y2.stateMachine = (n2(_2 = {}, r2.data, (n2(t3 = {}, s2.lt, function() {
x2.trim() && M2(a2.text, x2), v2 = "", C2 = false, b2 = r2.tagBegin;
}), n2(t3, s2.char, function(e49) {
x2 += e49;
}), t3)), n2(_2, r2.cdata, n2({}, s2.char, function(e49) {
(x2 += e49).substr(-3) === "]]>" && (M2(a2.text, x2.slice(0, -3)), x2 = "", b2 = r2.data);
})), n2(_2, r2.tagBegin, (n2(l2 = {}, s2.space, i2), n2(l2, s2.char, function(e49) {
v2 = e49, b2 = r2.tagName;
}), n2(l2, s2.slash, function() {
v2 = "", C2 = true;
}), l2)), n2(_2, r2.tagName, (n2(h2 = {}, s2.space, function() {
C2 ? b2 = r2.tagEnd : (b2 = r2.attributeNameStart, M2(a2.openTag, v2));
}), n2(h2, s2.gt, function() {
M2(C2 ? a2.closeTag : a2.openTag, v2), x2 = "", b2 = r2.data;
}), n2(h2, s2.slash, function() {
b2 = r2.tagEnd, M2(a2.openTag, v2);
}), n2(h2, s2.char, function(e49) {
(v2 += e49) === "![CDATA[" && (b2 = r2.cdata, x2 = "", v2 = "");
}), h2)), n2(_2, r2.tagEnd, (n2(d2 = {}, s2.gt, function() {
M2(a2.closeTag, v2), x2 = "", b2 = r2.data;
}), n2(d2, s2.char, i2), d2)), n2(_2, r2.attributeNameStart, (n2(u2 = {}, s2.char, function(e49) {
I2 = e49, b2 = r2.attributeName;
}), n2(u2, s2.gt, function() {
x2 = "", b2 = r2.data;
}), n2(u2, s2.space, i2), n2(u2, s2.slash, function() {
C2 = true, b2 = r2.tagEnd;
}), u2)), n2(_2, r2.attributeName, (n2(p2 = {}, s2.space, function() {
b2 = r2.attributeNameEnd;
}), n2(p2, s2.equal, function() {
M2(a2.attributeName, I2), b2 = r2.attributeValueBegin;
}), n2(p2, s2.gt, function() {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), x2 = "", b2 = r2.data;
}), n2(p2, s2.slash, function() {
C2 = true, S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), b2 = r2.tagEnd;
}), n2(p2, s2.char, function(e49) {
I2 += e49;
}), p2)), n2(_2, r2.attributeNameEnd, (n2(m2 = {}, s2.space, i2), n2(m2, s2.equal, function() {
M2(a2.attributeName, I2), b2 = r2.attributeValueBegin;
}), n2(m2, s2.gt, function() {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), x2 = "", b2 = r2.data;
}), n2(m2, s2.char, function(e49) {
S2 = "", M2(a2.attributeName, I2), M2(a2.attributeValue, S2), I2 = e49, b2 = r2.attributeName;
}), m2)), n2(_2, r2.attributeValueBegin, (n2(g2 = {}, s2.space, i2), n2(g2, s2.quote, function(e49) {
P2 = e49, S2 = "", b2 = r2.attributeValue;
}), n2(g2, s2.gt, function() {
M2(a2.attributeValue, S2 = ""), x2 = "", b2 = r2.data;
}), n2(g2, s2.char, function(e49) {
P2 = "", S2 = e49, b2 = r2.attributeValue;
}), g2)), n2(_2, r2.attributeValue, (n2(f2 = {}, s2.space, function(e49) {
P2 ? S2 += e49 : (M2(a2.attributeValue, S2), b2 = r2.attributeNameStart);
}), n2(f2, s2.quote, function(e49) {
P2 === e49 ? (M2(a2.attributeValue, S2), b2 = r2.attributeNameStart) : S2 += e49;
}), n2(f2, s2.gt, function(e49) {
P2 ? S2 += e49 : (M2(a2.attributeValue, S2), x2 = "", b2 = r2.data);
}), n2(f2, s2.slash, function(e49) {
P2 ? S2 += e49 : (M2(a2.attributeValue, S2), C2 = true, b2 = r2.tagEnd);
}), n2(f2, s2.char, function(e49) {
S2 += e49;
}), f2)), _2);
var w2 = function(t4) {
e48.debug && console.log(b2, t4);
var n3 = y2.stateMachine[b2], o3 = n3[function(e49) {
return c2[e49] || s2.char;
}(t4)] || n3[s2.error] || n3[s2.char];
o3(t4);
};
return y2.write = function(e49) {
for (var t4 = e49.length, n3 = 0;n3 < t4; n3++)
w2(e49[n3]);
}, y2;
} };
} });
var vV = pV({ "node_modules/xml-reader/dist/reader.js"(e47, t2) {
var n2 = bV(), o2 = xV(), i2 = o2.Type, r2 = { element: "element", text: "text" }, s2 = function(e48) {
return Object.assign({ name: "", type: r2.element, value: "", parent: null, attributes: {}, children: [] }, e48);
}, a2 = function(e48) {
e48 = Object.assign({ stream: false, parentNodes: true, doneEvent: "done", tagPrefix: "tag:", emitTopLevelOnly: false, debug: false }, e48);
var t3 = undefined, a3 = undefined, c2 = undefined, l2 = undefined, h2 = new n2, d2 = function(n3) {
switch (n3.type) {
case i2.openTag:
if (c2 === null)
(c2 = a3).name = n3.value;
else {
var o3 = s2({ name: n3.value, parent: c2 });
c2.children.push(o3), c2 = o3;
}
break;
case i2.closeTag:
var d3 = c2.parent;
if (e48.parentNodes || (c2.parent = null), c2.name !== n3.value)
break;
e48.stream && d3 === a3 && (a3.children = [], c2.parent = null), e48.emitTopLevelOnly && d3 !== a3 || (h2.emit(e48.tagPrefix + c2.name, c2), h2.emit("tag", c2.name, c2)), c2 === a3 && (t3.removeAllListeners("data"), h2.emit(e48.doneEvent, c2), a3 = null), c2 = d3;
break;
case i2.text:
c2 && c2.children.push(s2({ type: r2.text, value: n3.value, parent: e48.parentNodes ? c2 : null }));
break;
case i2.attributeName:
l2 = n3.value, c2.attributes[l2] = "";
break;
case i2.attributeValue:
c2.attributes[l2] = n3.value;
}
};
return h2.reset = function() {
(t3 = o2.create({ debug: e48.debug })).on("data", d2), a3 = s2(), c2 = null, l2 = "", h2.parse = t3.write;
}, h2.reset(), h2;
};
t2.exports = { parseSync: function(e48, t3) {
t3 = Object.assign({}, t3, { stream: false, tagPrefix: ":" });
var n3 = a2(t3), o3 = undefined;
return n3.on("done", function(e49) {
o3 = e49;
}), n3.parse(e48), o3;
}, create: a2, NodeType: r2 };
} });
mV(yV()), mV(vV());
var kH = (e47) => {
const { candidates: t2, mapOfCapacityMeshNodeIdToRef: n2 } = e47;
let o2 = true;
for (const e48 of t2) {
let t3 = false;
e48.port.nodeIds.forEach((e49) => {
const o3 = n2.get(e49);
if (!o3)
throw new Error(`Could not find capacity mesh node for id ${e49}`);
o3._containsObstacle && (t3 = true);
}), t3 || (o2 = false);
}
return o2;
};
var DH = (e47) => e47.depth + 1000 * e47.countOfCrampedPortPointsInPath;
var LH = class extends De {
constructor(e47) {
if (super(), this.input = e47, 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 e47 = this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(this.input.target.capacityMeshNodeId) ?? [];
for (const t2 of e47) {
if (this.input.shouldIgnoreCrampedPortPoints && t2.cramped)
continue;
const e48 = { port: t2, depth: 1, parent: null, countOfCrampedPortPointsInPath: t2.cramped ? 1 : 0 }, n2 = this.visitedExploredPortPoints.get(t2);
(!n2 || this.getCandidateCost(e48) < this.getCandidateCost(n2)) && (this.visitedExploredPortPoints.set(t2, e48), this.queue.push(e48));
}
}
_step() {
if (this.queue.length === 0)
return this.currentExploredPortPoints = null, void (this.solved = true);
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 e47 = this.currentExploredPortPoints.port.nodeIds.map((e48) => {
const t2 = this.input.mapOfCapacityMeshNodeIdToRef.get(e48);
if (!t2)
throw new Error(`Could not find capacity mesh node for id ${e48}`);
return t2;
}).flatMap((e48) => this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(e48.capacityMeshNodeId) ?? []);
for (const t2 of e47) {
if (this.input.shouldIgnoreCrampedPortPoints && t2.cramped)
continue;
const e48 = { port: t2, depth: this.currentExploredPortPoints.depth + 1, parent: this.currentExploredPortPoints, countOfCrampedPortPointsInPath: this.currentExploredPortPoints.countOfCrampedPortPointsInPath + (t2.cramped ? 1 : 0) }, n2 = this.visitedExploredPortPoints.get(t2);
n2 && this.getCandidateCost(n2) <= this.getCandidateCost(e48) || (this.visitedExploredPortPoints.set(t2, e48), this.queue.push(e48));
}
}
this.solved = true;
}
getCandidateCost(e47) {
return e47.depth + 1000 * e47.countOfCrampedPortPointsInPath;
}
getOutput() {
return this.resultExploredPortPoints;
}
visualize() {
const e47 = { points: [], rects: [] };
for (const t2 of this.visitedExploredPortPoints.keys())
e47.points.push({ ...t2, color: t2.cramped ? "blue" : "green" });
return e47;
}
};
var zH = class extends De {
constructor(e47) {
super(), this.input = e47, this._setup();
}
input;
unprocessedTargets = [];
targetNode = [];
currentTarget;
crampedPortPointsToKeep = new Set;
candidatesAtDepth = [];
isRunningCrampedPass = false;
filteredOutput;
activeSubSolver = null;
nodeMap = new Map;
mapOfCapacityMeshNodeIdToSegmentPortPoints = new Map;
getSolverName() {
return "multiTargetNecessaryCrampedPortPointSolver";
}
_setup() {
this.targetNode = this.input.capacityMeshNodes.filter((e47) => e47._containsObstacle), this.targetNode = this.targetNode.filter((e47) => {
for (const t2 of this.input.simpleRouteJson.connections)
for (const n2 of t2.pointsToConnect)
if (jt(n2, e47) <= 0)
return true;
return false;
}), this.unprocessedTargets = [...this.targetNode], this.unprocessedTargets.sort((e47, t2) => e47.center.x - t2.center.x);
for (const e47 of this.input.capacityMeshNodes)
this.nodeMap.set(e47.capacityMeshNodeId, e47);
for (const e47 of this.input.sharedEdgeSegments)
for (const t2 of e47.portPoints) {
const e48 = t2.nodeIds;
for (const n2 of e48) {
if (!this.nodeMap.get(n2))
throw new Error(`Could not find capacity mesh node for id ${n2}`);
const e49 = this.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(n2) || [];
this.mapOfCapacityMeshNodeIdToSegmentPortPoints.set(n2, [...e49, t2]);
}
}
}
_step() {
if (this.activeSubSolver) {
if (this.activeSubSolver._step(), !this.activeSubSolver.solved)
return;
if (this.activeSubSolver.failed)
return this.failed = true, void (this.error = this.activeSubSolver.error);
if (this.candidatesAtDepth = this.activeSubSolver.getOutput(), this.activeSubSolver = null, !this.currentTarget)
return this.failed = true, void (this.error = "Missing current capacity mesh node while finishing BFS");
if (!this.isRunningCrampedPass) {
return kH({ candidates: this.candidatesAtDepth, mapOfCapacityMeshNodeIdToRef: this.nodeMap }) || this.candidatesAtDepth.length === 0 ? (this.isRunningCrampedPass = true, void (this.activeSubSolver = new LH({ target: this.currentTarget, depthLimit: 3, shouldIgnoreCrampedPortPoints: false, mapOfCapacityMeshNodeIdToSegmentPortPoints: this.mapOfCapacityMeshNodeIdToSegmentPortPoints, mapOfCapacityMeshNodeIdToRef: this.nodeMap }))) : void (this.currentTarget = undefined);
}
let e47 = this.candidatesAtDepth.filter((e48) => {
const t2 = e48.port;
return t2.nodeIds.map((e49) => {
const t3 = this.nodeMap.get(e49);
if (!t3)
throw this.failed = true, this.error = `Could not find capacity mesh node for id ${e49}`, new Error(`Could not find capacity mesh node for id ${e49}`);
return t3;
}).every((e49) => !e49._containsObstacle) && t2.cramped;
});
if (kH({ candidates: e47, 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 = [...e47].sort((e48, t2) => {
const n2 = DH(e48) - DH(t2);
return n2 !== 0 ? n2 : this.getCandidateExitCapacity(t2) - this.getCandidateExitCapacity(e48);
}), this.candidatesAtDepth.length === 0)
this.error = `No candidates found for capacity mesh node ${this.currentTarget.capacityMeshNodeId} even after including cramped port points`;
else {
const e48 = new Map;
for (const t3 of this.candidatesAtDepth) {
if (!t3.parent)
throw new Error(`Missing parent for cramped escape candidate ${t3.port.segmentPortPointId}`);
const n2 = `${t3.parent.port.segmentPortPointId}->${t3.port.segmentPortPointId}`;
if (!e48.has(n2) && (e48.set(n2, t3), e48.size === 5))
break;
}
const t2 = [...e48.values()];
for (const e49 of t2)
this.keepCandidatePath(e49);
}
return this.isRunningCrampedPass = false, void (this.currentTarget = undefined);
}
if (!this.currentTarget)
return this.currentTarget = this.unprocessedTargets.shift(), this.currentTarget ? (this.isRunningCrampedPass = false, this.candidatesAtDepth = [], void (this.activeSubSolver = new LH({ target: this.currentTarget, depthLimit: 2, shouldIgnoreCrampedPortPoints: true, mapOfCapacityMeshNodeIdToSegmentPortPoints: this.mapOfCapacityMeshNodeIdToSegmentPortPoints, mapOfCapacityMeshNodeIdToRef: this.nodeMap }))) : void (this.solved = true);
}
getOutput() {
return this.filteredOutput || (this.filteredOutput = this.input.sharedEdgeSegments.map((e47) => ({ ...e47, portPoints: e47.portPoints.flatMap((e48) => !e48.cramped || this.crampedPortPointsToKeep.has(e48) ? [e48] : this.isMultilayerEscapePort(e48) ? [{ ...e48, tinyHypergraphPortPenalty: 1000 }] : []) }))), this.filteredOutput;
}
getCandidateExitCapacity(e47) {
if (!e47.parent)
throw new Error(`Missing parent for cramped escape candidate ${e47.port.segmentPortPointId}`);
const t2 = new Set(e47.parent.port.nodeIds), n2 = e47.port.nodeIds.filter((e48) => !t2.has(e48)).map((e48) => {
const t3 = this.nodeMap.get(e48);
if (!t3)
throw new Error(`Could not find capacity mesh node for id ${e48}`);
return t3;
});
if (n2.length === 0)
throw new Error(`Could not find exit node for cramped escape candidate ${e47.port.segmentPortPointId}`);
return Math.max(0, ...n2.map((e48) => e48.width * e48.height * e48.availableZ.length));
}
keepCandidatePath(e47) {
this.crampedPortPointsToKeep.add(e47.port);
let t2 = e47.parent;
for (;t2; )
this.crampedPortPointsToKeep.add(t2.port), t2 = t2.parent;
}
isMultilayerEscapePort(e47) {
return e47.nodeIds.some((e48) => (this.nodeMap.get(e48)?.availableZ.length ?? 0) > 1);
}
visualize() {
const e47 = { rects: [], points: [] };
for (const t2 of this.targetNode)
e47.rects.push({ ...t2, fill: this.currentTarget?.capacityMeshNodeId === t2.capacityMeshNodeId ? "rgba(255, 0, 0, 0.5)" : "rgba(255, 0, 0, 0.2)" });
for (const t2 of this.candidatesAtDepth)
e47.points.push({ ...t2.port, color: t2.port.cramped ? "blue" : "green" });
for (const t2 of this.crampedPortPointsToKeep)
e47.points.push({ ...t2, color: "blue" });
return this.activeSubSolver ? Oe(e47, this.activeSubSolver.visualize()) : e47;
}
};
var BH = (e47) => `${e47.x.toFixed(4)},${e47.y.toFixed(4)}`;
var FH = (e47) => e47.netIsAssignable === true && (e47.layers?.length ?? 0) > 1;
var jH = (e47, t2) => e47.connectedTo?.find((e48) => e48.startsWith("pcb_via")) ?? e47.obstacleId ?? `assignable_via_${t2}`;
var $H = (e47) => [...new Set(e47.obstacle.layers.map((t2) => go(t2, e47.layerCount)))].sort((e48, t2) => e48 - t2);
function WH(e47, t2) {
if (e47 == null)
throw new Error(t2);
}
function VH({ point: e47, layerCount: t2 }) {
const n2 = Co(e47).map((e48) => go(e48, t2));
return [...new Set(n2)];
}
function HH(e47) {
if (jt(e47.point, e47.region.d) <= 0.001) {
return (e47.pointZLayers ?? VH(e47)).some((t2) => e47.region.d.availableZ.includes(t2));
}
return false;
}
function GH({ region: e47, pointZLayers: t2 }) {
return e47.ports.some((e48) => t2.includes(e48.d.z) && t2.some((t3) => e48.region1.d.availableZ.includes(t3)) && t2.some((t3) => e48.region2.d.availableZ.includes(t3)));
}
function UH({ graph: e47, point: t2, layerCount: n2 }) {
const o2 = VH({ point: t2, layerCount: n2 });
let i2;
for (const r2 of e47.regions)
if (HH({ point: t2, region: r2, layerCount: n2, pointZLayers: o2 }) && (i2 ??= r2, GH({ region: r2, pointZLayers: o2 })))
return r2;
return i2;
}
var ZH = (e47, t2) => {
const n2 = e47.getNetConnectedToId(t2);
if (!n2)
throw new Error(`Could not resolve net ID for connection "${t2}"`);
return n2;
};
var qH = (e47) => {
const t2 = e47.graph.regions.filter((t3) => t3.d.availableZ.includes(e47.z) && !t3.d._assignableVia).map((t3) => ({ region: t3, distance: jt(e47.point, t3.d) })).sort((e48, t3) => e48.distance - t3.distance || e48.region.d.width * e48.region.d.height - t3.region.d.width * t3.region.d.height), n2 = t2[0]?.distance;
if (n2 === undefined)
return [];
const o2 = Math.max(n2 + 0.000001, e47.viaRadius + 0.15);
return t2.filter((e48) => e48.distance <= o2).slice(0, 4).map((e48) => e48.region);
};
function JH(e47) {
const t2 = { ports: [], regions: [] }, n2 = [], o2 = new Map;
for (const n3 of e47.capacityMeshNodes) {
const i2 = n3._connectedTo?.map((t3) => ZH(e47.connectivityMap, t3)), r2 = { regionId: n3.capacityMeshNodeId, d: i2 ? { ...n3, _connectedTo: [...new Set(i2)] } : n3, ports: [] };
t2.regions.push(r2), o2.has(r2.regionId) || o2.set(r2.regionId, r2);
}
for (const n3 of e47.segmentPortPoints) {
const [e48, i2] = n3.nodeIds, r2 = o2.get(e48), s2 = o2.get(i2);
WH(r2, `Could not find region with id ${e48} for segment port point ${n3.segmentPortPointId}`), WH(s2, `Could not find region with id ${i2} for segment port point ${n3.segmentPortPointId}`);
for (const e49 of n3.availableZ) {
const o3 = n3._preloadedTracePortAssignments?.filter((t3) => t3.z === e49), i3 = { portId: `${n3.segmentPortPointId}::${e49}`, x: n3.x, y: n3.y, z: e49, distToCentermostPortOnZ: n3.distToCentermostPortOnZ, cramped: n3.cramped, regions: [r2, s2], tinyHypergraphPortPenalty: n3.tinyHypergraphPortPenalty, _preloadedFixedNetIds: o3 && o3.length > 0 ? [...new Set(o3.map((e50) => e50.fixedNetId))].sort() : undefined, _preloadedTracePortAssignments: o3 }, a2 = { portId: n3.segmentPortPointId, d: i3, region1: r2, region2: s2 };
t2.ports.push(a2), r2.ports.push(a2), s2.ports.push(a2);
}
}
((e48) => {
for (const [t3, n3] of e48.assignableViaObstacles.entries()) {
if (!FH(n3))
continue;
const o3 = $H({ obstacle: n3, layerCount: e48.layerCount });
if (o3.length < 2)
continue;
const i2 = `assignable-via:${jH(n3, t3)}`, r2 = Math.min(n3.width, n3.height) / 2, s2 = { regionId: i2, d: { capacityMeshNodeId: i2, center: { ...n3.center }, width: n3.width, height: n3.height, layer: `z${o3.join(",")}`, availableZ: o3, _containsObstacle: false, _completelyInsideObstacle: false, _containsTarget: false, _assignableVia: true, _assignedViaObstacle: n3 }, ports: [] }, a2 = [];
for (const t4 of o3)
for (const o4 of qH({ graph: e48.graph, point: n3.center, z: t4, viaRadius: r2 })) {
const e49 = { portId: `${i2}:port:${o4.regionId}:z${t4}`, x: n3.center.x, y: n3.center.y, z: t4, distToCentermostPortOnZ: 0, cramped: false, regions: [o4, s2] }, r3 = { portId: e49.portId, d: e49, region1: o4, region2: s2 };
a2.push(r3), o4.ports.push(r3);
}
if (new Set(a2.map((e49) => e49.d.z)).size < 2)
for (const e49 of a2)
e49.region1.ports = e49.region1.ports.filter((t4) => t4 !== e49);
else
s2.ports.push(...a2), e48.graph.regions.push(s2), e48.graph.ports.push(...a2);
}
})({ graph: t2, assignableViaObstacles: e47.assignableViaObstacles ?? [], layerCount: e47.layerCount });
for (const o3 of e47.simpleRouteJsonConnections) {
const [i2, r2] = o3.pointsToConnect, s2 = UH({ graph: t2, point: i2, layerCount: e47.layerCount }), a2 = UH({ graph: t2, point: r2, layerCount: e47.layerCount });
WH(s2, `Could not find start region for connection "${o3.name}"`), WH(a2, `Could not find end region for connection "${o3.name}"`), n2.push({ connectionId: o3.name, mutuallyConnectedNetworkId: ZH(e47.connectivityMap, o3.name), startRegion: s2, endRegion: a2, simpleRouteConnection: o3 });
}
return { graph: t2, connections: n2 };
}
var sG = class {
MAX_ITERATIONS = 1000;
solved = false;
failed = false;
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 (e47) {
throw this.error = `${this.getSolverName()} error: ${e47}`, console.error(this.error), this.failed = true, e47;
}
!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 = true), "computeProgress" in this && (this.progress = this.computeProgress());
}
}
_step() {}
getConstructorParams() {
throw new Error("getConstructorParams not implemented");
}
solve() {
const e47 = Date.now();
for (;!this.solved && !this.failed; )
this.step();
const t2 = Date.now();
this.timeToSolve = t2 - e47;
}
visualize() {
return { lines: [], points: [], rects: [], circles: [] };
}
tryFinalAcceptance() {}
preview() {
return { lines: [], points: [], rects: [], circles: [] };
}
};
var aG = (e47, t2) => {
const n2 = (e48) => e48 === " " || e48 === `
` || e48 === "\r" || e48 === "\t", o2 = (e48) => {
let t3 = 0, o3 = e48.length;
for (;t3 < o3 && n2(e48[t3]); )
t3 += 1;
for (;o3 > t3 && n2(e48[o3 - 1]); )
o3 -= 1;
return e48.slice(t3, o3);
}, i2 = (e48) => {
const t3 = [];
let n3 = 0, i3 = 0;
for (let r3 = 0;r3 < e48.length; r3 += 1) {
const s3 = e48[r3];
s3 !== "(" ? s3 !== ")" ? s3 === "," && i3 === 0 && (t3.push(o2(e48.slice(n3, r3))), n3 = r3 + 1) : i3 > 0 && (i3 -= 1) : i3 += 1;
}
return t3.push(o2(e48.slice(n3))), t3;
}, r2 = (e48) => {
return `${t3 = e48, Math.min(1, Math.max(0, t3))}`;
var t3;
}, s2 = ((e48) => {
const t3 = o2(e48);
if (!t3.startsWith("#"))
return null;
const n3 = t3.slice(1);
if (n3.length !== 3 && n3.length !== 6)
return null;
for (const e49 of n3) {
const t4 = e49.toLowerCase();
if (!(t4 >= "0" && t4 <= "9") && !(t4 >= "a" && t4 <= "f"))
return null;
}
if (n3.length === 3) {
const [e49, t4, o3] = n3;
return { r: Number.parseInt(e49 + e49, 16), g: Number.parseInt(t4 + t4, 16), b: Number.parseInt(o3 + o3, 16) };
}
return { r: Number.parseInt(n3.slice(0, 2), 16), g: Number.parseInt(n3.slice(2, 4), 16), b: Number.parseInt(n3.slice(4, 6), 16) };
})(t2);
if (s2)
return `rgba(${s2.r}, ${s2.g}, ${s2.b}, ${r2(1 - e47)})`;
const a2 = ((e48) => {
const t3 = o2(e48), n3 = t3.indexOf("(");
return n3 <= 0 || t3[t3.length - 1] !== ")" ? null : { name: o2(t3.slice(0, n3)).toLowerCase(), args: i2(t3.slice(n3 + 1, -1)) };
})(t2);
if (!a2)
return t2;
const { name: c2, args: l2 } = a2;
if (c2 === "hsl" || c2 === "rgb")
return l2.length !== 3 ? t2 : `${c2}a(${l2[0]}, ${l2[1]}, ${l2[2]}, ${r2(1 - e47)})`;
if (c2 === "hsla" || c2 === "rgba") {
if (l2.length !== 4)
return t2;
const n3 = ((e48) => {
const t3 = o2(e48);
if (!t3)
return null;
const n4 = Number.parseFloat(t3);
return Number.isFinite(n4) ? n4 : null;
})(l2[3]);
return n3 === null ? t2 : `${c2}(${l2[0]}, ${l2[1]}, ${l2[2]}, ${r2(n3 - e47)})`;
}
return t2;
};
var cG = (e47, t2) => {
try {
return aG(t2, e47);
} catch (t3) {
return console.error(t3), e47;
}
};
var lG = (e47) => e47.rootConnectionName ?? e47.connectionName;
var hG = (e47) => {
const t2 = [];
for (let n2 = 0;n2 < e47.route.length - 1; n2 += 1) {
const o2 = e47.route[n2], i2 = e47.route[n2 + 1];
if (!o2 || !i2 || o2.z === i2.z)
continue;
if (Math.abs(o2.x - i2.x) > 0.000001 || Math.abs(o2.y - i2.y) > 0.000001)
continue;
const r2 = { x: Math.round(1000 * o2.x) / 1000, y: Math.round(1000 * o2.y) / 1000 }, s2 = t2.at(-1);
s2 && s2.x === r2.x && s2.y === r2.y || t2.push(r2);
}
return t2;
};
var dG = (e47, t2, n2 = 0.001) => Math.abs(e47.x - t2.x) <= n2 && Math.abs(e47.y - t2.y) <= n2;
var uG = (e47, t2) => ({ minX: e47.center.x - e47.width / 2 + t2, maxX: e47.center.x + e47.width / 2 - t2, minY: e47.center.y - e47.height / 2 + t2, maxY: e47.center.y + e47.height / 2 - t2 });
var pG = (e47, t2) => {
const n2 = Math.max(Math.abs(e47), Math.abs(t2));
if (n2 === 0 || n2 === Number.POSITIVE_INFINITY)
return n2;
const o2 = e47 / n2, i2 = t2 / n2;
return n2 * Math.sqrt(o2 * o2 + i2 * i2);
};
var mG = (e47, t2) => ({ x: e47.x - t2.x, y: e47.y - t2.y });
var gG = (e47, t2) => e47.x * t2.x + e47.y * t2.y;
var fG = (e47, t2, n2) => ({ x: e47.x + (t2.x - e47.x) * n2, y: e47.y + (t2.y - e47.y) * n2 });
var _G = (e47) => {
const t2 = [];
for (let n2 = 0;n2 < e47.length; n2 += 1) {
const o2 = e47[n2];
if (o2)
for (let e48 = 0;e48 < o2.route.length - 1; e48 += 1) {
const i2 = o2.route[e48], r2 = o2.route[e48 + 1];
i2 && r2 && (i2.z !== r2.z || dG(i2, r2) || t2.push({ routeIndex: n2, rootConnectionName: lG(o2), startIndex: e48, endIndex: e48 + 1, start: i2, end: r2, z: i2.z, traceRadius: (o2.traceThickness ?? 0.1) / 2 }));
}
}
return t2;
};
var yG = (e47, t2, n2 = 0.000001) => {
const o2 = t2.end.x - t2.start.x, i2 = t2.end.y - t2.start.y, r2 = o2 * o2 + i2 * i2;
if (r2 <= n2)
return { x: t2.start.x, y: t2.start.y, t: 0 };
const s2 = ((e47.x - t2.start.x) * o2 + (e47.y - t2.start.y) * i2) / r2, a2 = (c2 = s2, Math.max(0, Math.min(c2, 1)));
var c2;
return { x: t2.start.x + o2 * a2, y: t2.start.y + i2 * a2, t: a2 };
};
var bG = (e47, t2, n2 = 0.000001) => {
const o2 = mG(e47.end, e47.start), i2 = mG(t2.end, t2.start), r2 = mG(e47.start, t2.start), s2 = gG(o2, o2), a2 = gG(o2, i2), c2 = gG(i2, i2), l2 = gG(o2, r2), h2 = gG(i2, r2), d2 = s2 * c2 - a2 * a2, u2 = n2;
let p2, m2, g2 = d2, f2 = d2;
d2 <= u2 ? (p2 = 0, g2 = 1, m2 = h2, f2 = c2) : (p2 = a2 * h2 - c2 * l2, m2 = s2 * h2 - a2 * l2, p2 < 0 ? (p2 = 0, m2 = h2, f2 = c2) : p2 > g2 && (p2 = g2, m2 = h2 + a2, f2 = c2)), m2 < 0 ? (m2 = 0, -l2 < 0 ? p2 = 0 : -l2 > s2 ? p2 = g2 : (p2 = -l2, g2 = s2)) : m2 > f2 && (m2 = f2, -l2 + a2 < 0 ? p2 = 0 : -l2 + a2 > s2 ? p2 = g2 : (p2 = -l2 + a2, g2 = s2));
const _2 = Math.abs(p2) <= u2 ? 0 : p2 / g2, y2 = Math.abs(m2) <= u2 ? 0 : m2 / f2, b2 = fG(e47.start, e47.end, _2), x2 = fG(t2.start, t2.end, y2), v2 = yG(e47.start, t2, n2), I2 = yG(e47.end, t2, n2), S2 = yG(t2.start, e47, n2), C2 = yG(t2.end, e47, n2);
return [{ leftT: _2, rightT: y2, leftPoint: b2, rightPoint: x2 }, { leftT: 0, rightT: v2.t, leftPoint: e47.start, rightPoint: v2 }, { leftT: 1, rightT: I2.t, leftPoint: e47.end, rightPoint: I2 }, { leftT: S2.t, rightT: 0, leftPoint: S2, rightPoint: t2.start }, { leftT: C2.t, rightT: 1, leftPoint: C2, rightPoint: t2.end }].sort((e48, t3) => pG(e48.leftPoint.x - e48.rightPoint.x, e48.leftPoint.y - e48.rightPoint.y) - pG(t3.leftPoint.x - t3.rightPoint.x, t3.leftPoint.y - t3.rightPoint.y));
};
var xG = 0.000001;
var vG = (e47) => {
const t2 = [];
for (const n2 of e47) {
const e48 = t2[n2.routeIndex] ?? [];
e48[n2.startIndex] = n2, t2[n2.routeIndex] = e48;
}
return t2;
};
var IG = (e47, t2) => e47 < t2 ? [e47, t2] : [t2, e47];
var SG = (e47, t2) => e47.some(([e48, n2]) => e48 === t2[0] && n2 === t2[1]);
var CG = (e47, t2, n2) => {
let o2, i2 = Number.POSITIVE_INFINITY;
for (const r2 of e47) {
if (r2.routeIndex !== t2.routeIndex || r2.z !== t2.z || r2.endIndex !== t2.startIndex && r2.startIndex !== t2.endIndex)
continue;
const [e48] = bG(r2, n2);
if (!e48)
continue;
const s2 = pG(e48.leftPoint.x - e48.rightPoint.x, e48.leftPoint.y - e48.rightPoint.y);
s2 >= i2 || (i2 = s2, o2 = r2);
}
return o2;
};
var PG = (e47, t2) => {
const n2 = _G(t2), o2 = _G(e47), i2 = vG(o2), r2 = [];
for (let e48 = 0;e48 < n2.length; e48 += 1) {
const t3 = n2[e48];
if (t3)
for (let s2 = e48 + 1;s2 < n2.length; s2 += 1) {
const e49 = n2[s2];
if (!e49 || t3.z !== e49.z || t3.rootConnectionName === e49.rootConnectionName || Math.max(t3.start.x, t3.end.x) < Math.min(e49.start.x, e49.end.x) || Math.max(e49.start.x, e49.end.x) < Math.min(t3.start.x, t3.end.x) || Math.max(t3.start.y, t3.end.y) < Math.min(e49.start.y, e49.end.y) || Math.max(e49.start.y, e49.end.y) < Math.min(t3.start.y, t3.end.y))
continue;
const [a2] = bG(t3, e49);
if (!a2 || pG(a2.leftPoint.x - a2.rightPoint.x, a2.leftPoint.y - a2.rightPoint.y) > xG || a2.leftT <= xG || a2.leftT >= 0.999999 || a2.rightT <= xG || a2.rightT >= 0.999999)
continue;
const c2 = i2[t3.routeIndex]?.[t3.startIndex], l2 = i2[e49.routeIndex]?.[e49.startIndex];
if (!c2 || !l2)
continue;
const [h2] = bG(c2, l2);
if (!h2 || pG(h2.leftPoint.x - h2.rightPoint.x, h2.leftPoint.y - h2.rightPoint.y) <= xG)
continue;
const d2 = CG(o2, c2, l2), u2 = CG(o2, l2, c2), p2 = d2 ? [c2, d2] : [c2], m2 = u2 ? [l2, u2] : [l2];
for (const n3 of p2)
for (const o3 of m2) {
const i3 = { leftRouteIndex: t3.routeIndex, leftStartPointIndex: n3.startIndex, rightRouteIndex: e49.routeIndex, rightStartPointIndex: o3.startIndex };
r2.some((e50) => e50.leftRouteIndex === i3.leftRouteIndex && e50.leftStartPointIndex === i3.leftStartPointIndex && e50.rightRouteIndex === i3.rightRouteIndex && e50.rightStartPointIndex === i3.rightStartPointIndex) || r2.push(i3);
}
}
}
return r2;
};
var MG = (e47) => {
const t2 = _G(e47), n2 = [];
for (let e48 = 0;e48 < t2.length; e48 += 1) {
const o2 = t2[e48];
if (o2)
for (let i2 = e48 + 1;i2 < t2.length; i2 += 1) {
const e49 = t2[i2];
if (!e49 || o2.z !== e49.z || o2.rootConnectionName === e49.rootConnectionName)
continue;
const [r2] = bG(o2, e49);
if (!r2)
continue;
if (pG(r2.leftPoint.x - r2.rightPoint.x, r2.leftPoint.y - r2.rightPoint.y) + xG < o2.traceRadius + e49.traceRadius) {
const t3 = IG(o2.routeIndex, e49.routeIndex);
SG(n2, t3) || n2.push(t3);
}
}
}
return n2;
};
var wG = (e47, t2) => t2 <= 1 || t2 >= e47 - 2;
var NG = (e47, t2) => t2.some((t3) => wG(e47, t3));
var TG = 0.2;
var RG = 0.4;
var EG = 0.65 + 0.05;
var AG = 0.03;
var OG = 1000;
var kG = 0.000001;
var DG = 0.015;
var LG = (e47) => Math.round(e47 * OG) / OG;
var zG = (e47, t2) => ({ x: e47.x - t2.x, y: e47.y - t2.y });
var BG = (e47, t2) => ({ x: e47.x * t2, y: e47.y * t2 });
var FG = (e47, t2) => e47.x * t2.x + e47.y * t2.y;
var jG = (e47, t2, n2) => ({ x: e47.x + (t2.x - e47.x) * n2, y: e47.y + (t2.y - e47.y) * n2 });
var $G = (e47) => Math.max(0, Math.min(e47, 1));
var YG = (e47, t2, n2) => Math.max(t2, Math.min(e47, n2));
var XG = (e47, t2) => {
const n2 = ((e48) => pG(e48.x, e48.y))(e47);
return n2 <= t2 || n2 <= kG ? e47 : BG(e47, t2 / n2);
};
var WG = (e47, t2 = 0) => ({ minX: e47.center.x - e47.width / 2 - t2, maxX: e47.center.x + e47.width / 2 + t2, minY: e47.center.y - e47.height / 2 - t2, maxY: e47.center.y + e47.height / 2 + t2 });
var VG = (e47, t2, n2 = 0) => {
const o2 = WG(t2, n2);
return e47.x >= o2.minX && e47.x <= o2.maxX && e47.y >= o2.minY && e47.y <= o2.maxY;
};
var HG = (e47, t2, n2) => {
if (e47.regionId) {
const n3 = t2.findIndex((t3) => t3.capacityMeshNodeId === e47.regionId);
if (n3 !== -1)
return n3;
}
const o2 = [...e47.route.map(({ x: e48, y: t3 }) => ({ x: e48, y: t3 })), ...e47.vias.map(({ x: e48, y: t3 }) => ({ x: e48, y: t3 }))];
let i2 = -1, r2 = Number.POSITIVE_INFINITY;
for (let e48 = 0;e48 < t2.length; e48++) {
const s2 = t2[e48];
if (!s2 || !o2.every((e49) => VG(e49, s2, n2)))
continue;
const a2 = s2.width * s2.height;
a2 < r2 && (r2 = a2, i2 = e48);
}
return i2;
};
var GG = (e47, t2, n2, o2) => {
const i2 = ((e48, t3, n3) => {
const o3 = Math.min(Math.abs(e48.originalX - n3.minX), Math.abs(n3.maxX - e48.originalX)), i3 = Math.min(Math.abs(e48.originalY - n3.minY), Math.abs(n3.maxY - e48.originalY));
if (Math.abs(o3 - i3) <= kG)
return Math.abs(t3.x - e48.x) >= Math.abs(t3.y - e48.y) ? "y" : "x";
return o3 < i3 ? "y" : "x";
})(e47, t2, n2);
return XG(i2 === "x" ? { x: 1.1 * (e47.x - t2.x) * o2, y: 0 } : { x: 0, y: 1.1 * (e47.y - t2.y) * o2 }, 0.06 * o2);
};
var UG = (e47, t2, n2, o2, i2 = 3.5, r2 = 0.2, s2 = 0.4) => {
const a2 = Math.max(e47, 0);
if (a2 >= s2)
return 0;
const c2 = a2 / r2;
if (c2 < 1) {
const e48 = 1 - c2;
return t2 * e48 ** 3 * (1 + e48 * i2);
}
const l2 = (a2 - r2) / Math.max(s2 - r2, kG), h2 = t2 * n2 * Math.exp(-l2 * o2);
return h2 < 0.00001 ? 0 : h2;
};
var ZG = (e47, t2) => {
const n2 = e47.boundaryPadding > 0 ? 0.001 : 0, o2 = t2.minX + e47.boundaryPadding + n2, i2 = t2.maxX - e47.boundaryPadding - n2, r2 = t2.minY + e47.boundaryPadding + n2, s2 = t2.maxY - e47.boundaryPadding - n2;
e47.x = YG(e47.x, o2, i2), e47.y = YG(e47.y, r2, s2);
};
var qG = (e47, t2) => {
for (const n2 of e47)
for (const e48 of n2.nodes)
ZG(e48, t2);
};
var JG = (e47) => e47.kind === "via" ? 0.4 : 0.25;
var QG = (e47) => (e47.kind, 0.5);
var KG = (e47) => e47.kind === "via" ? 12 : 3.5;
var eU = (e47) => e47.kind === "via" ? 0.18 : 0.06;
var tU = (e47) => e47.kind === "via" ? 1.35 : 1.05;
var nU = (e47, t2) => e47.kind === "via" ? 3 * t2 : t2;
var oU = (e47, t2, n2, o2) => {
const i2 = 2 * t2;
e47[i2] = (e47[i2] ?? 0) + n2, e47[i2 + 1] = (e47[i2 + 1] ?? 0) + o2;
};
var iU = (e47, t2, n2, o2, i2, r2) => {
if (e47.fixed || oU(o2, e47.node.forceIndex, t2, n2), !e47.fixed && i2 && r2 !== undefined) {
const e48 = 2 * r2;
i2[e48] = (i2[e48] ?? 0) + t2, i2[e48 + 1] = (i2[e48 + 1] ?? 0) + n2;
}
};
var rU = (e47, t2, n2, o2, i2 = 0.5) => {
const { startNode: r2, endNode: s2 } = e47, a2 = 1 - $G(i2), c2 = $G(i2), l2 = r2.fixed ? 0 : a2, h2 = s2.fixed ? 0 : c2, d2 = l2 + h2;
if (!(d2 <= kG)) {
if (!r2.fixed && l2 > 0) {
const e48 = l2 / d2;
oU(o2, r2.forceIndex, t2 * e48, n2 * e48);
}
if (!s2.fixed && h2 > 0) {
const e48 = h2 / d2;
oU(o2, s2.forceIndex, t2 * e48, n2 * e48);
}
}
};
var sU = (e47, t2, n2, o2, i2) => {
if (t2.fixed)
return { x: 0, y: 0 };
const { minX: r2, maxX: s2, minY: a2, maxY: c2 } = e47, l2 = ((e48) => e48.kind === "via" ? 0.65 : TG)(t2), h2 = ((e48) => e48.kind === "via" ? EG : RG)(t2), d2 = ((e48) => e48.kind === "via" ? 0.015 : 0.08)(t2), u2 = ((e48) => e48.kind === "via" ? 80 : 20)(t2), p2 = KG(t2);
return { x: UG(n2 - r2, AG, d2, u2, p2, l2, h2) * i2 - UG(s2 - n2, AG, d2, u2, p2, l2, h2) * i2, y: UG(o2 - a2, AG, d2, u2, p2, l2, h2) * i2 - UG(c2 - o2, AG, d2, u2, p2, l2, h2) * i2 };
};
var aU = (e47) => {
if (e47.length === 0)
return null;
const t2 = new je(e47.length);
for (const n2 of e47) {
const { startNode: e48, endNode: o2 } = n2;
t2.add(Math.min(e48.x, o2.x), Math.min(e48.y, o2.y), Math.max(e48.x, o2.x), Math.max(e48.y, o2.y));
}
return t2.finish(), { index: t2, segments: e47 };
};
var cU = (e47) => {
const t2 = new Map, n2 = new Map;
for (const t3 of e47) {
const e48 = n2.get(t3.z) ?? [];
e48.push(t3), n2.set(t3.z, e48);
}
for (const [e48, o2] of n2) {
const n3 = aU(o2);
n3 && t2.set(e48, n3);
}
return { byLayer: t2 };
};
var lU = (e47, t2, n2, o2, i2) => {
const r2 = (e48) => ({ candidateIndexes: e48.index.search(n2 - i2, o2 - i2, n2 + i2, o2 + i2), segments: e48.segments });
if (t2.kind === "point") {
const n3 = e47.byLayer.get(t2.z);
return n3 ? [r2(n3)] : [];
}
const s2 = [];
for (const t3 of e47.byLayer.values())
s2.push(r2(t3));
return s2;
};
var hU = (e47) => {
const t2 = [];
for (let n2 = 0;n2 < e47.length; n2 += 1) {
const o2 = e47[n2];
if (!o2)
continue;
const i2 = new Set;
for (let e48 = 0;e48 < o2.route.length - 1; e48 += 1) {
const r2 = o2.route[e48], s2 = o2.route[e48 + 1];
if (!r2 || !s2)
continue;
if (r2.z === s2.z || !dG(r2, s2))
continue;
const a2 = [e48, e48 + 1];
for (let t3 = e48 - 1;t3 >= 0; t3 -= 1) {
const e49 = o2.route[t3];
if (!e49 || !dG(e49, r2))
break;
a2.push(t3);
}
for (let t3 = e48 + 2;t3 < o2.route.length; t3 += 1) {
const e49 = o2.route[t3];
if (!e49 || !dG(e49, r2))
break;
a2.push(t3);
}
const c2 = [...new Set(a2)].sort((e49, t3) => e49 - t3);
let l2 = false;
for (const e49 of c2)
if (i2.has(e49)) {
l2 = true;
break;
}
if (!l2) {
for (const e49 of c2)
i2.add(e49);
t2.push({ routeIndex: n2, rootConnectionName: lG(o2), pointIndexes: c2, x: r2.x, y: r2.y, radius: (o2.viaDiameter ?? 0.3) / 2, movable: !NG(o2.route.length, c2) });
}
}
}
return t2;
};
var dU = (e47) => {
const { routes: t2, via: n2, dx: o2, dy: i2, node: r2 } = e47;
if (!n2.movable)
return false;
n2.x += o2, n2.y += i2, ((e48, t3) => {
const n3 = uG(t3, e48.radius + kG);
e48.x = YG(e48.x, n3.minX, n3.maxX), e48.y = YG(e48.y, n3.minY, n3.maxY);
})(n2, r2);
const s2 = t2[n2.routeIndex];
if (!s2)
return false;
for (const e48 of n2.pointIndexes) {
const t3 = s2.route[e48];
t3 && (t3.x = n2.x, t3.y = n2.y);
}
return true;
};
var uU = (e47) => {
const { routes: t2, node: n2, vias: o2 } = e47;
let i2 = false;
for (let e48 = 0;e48 < o2.length; e48 += 1) {
const r2 = o2[e48];
if (r2)
for (let s2 = e48 + 1;s2 < o2.length; s2 += 1) {
const a2 = o2[s2];
if (!a2)
continue;
const c2 = r2.radius + a2.radius + 0.1 + DG, l2 = r2.x - a2.x, h2 = r2.y - a2.y, d2 = pG(l2, h2), u2 = c2 - d2;
if (u2 <= 0)
continue;
const p2 = 1.61803398875 * (97 * e48 + 13 * s2), m2 = d2 > kG ? l2 / d2 : Math.cos(p2), g2 = d2 > kG ? h2 / d2 : Math.sin(p2), f2 = Number(r2.movable) + Number(a2.movable);
if (f2 === 0)
continue;
const _2 = Math.min(0.04, u2 / f2);
i2 = dU({ routes: t2, via: r2, dx: m2 * _2, dy: g2 * _2, node: n2 }) || i2, i2 = dU({ routes: t2, via: a2, dx: -m2 * _2, dy: -g2 * _2, node: n2 }) || i2;
}
}
return i2;
};
var pU = (e47) => {
const { routes: t2, node: n2, vias: o2, segments: i2 } = e47;
let r2 = false;
for (let e48 = 0;e48 < o2.length; e48 += 1) {
const s2 = o2[e48];
if (s2?.movable)
for (const o3 of i2) {
if (s2.rootConnectionName === o3.rootConnectionName)
continue;
const i3 = yG(s2, o3), a2 = s2.x - i3.x, c2 = s2.y - i3.y, l2 = pG(a2, c2), h2 = s2.radius + o3.traceRadius + 0.1 + DG - l2;
if (h2 <= 0)
continue;
const d2 = o3.end.x - o3.start.x, u2 = o3.end.y - o3.start.y, p2 = pG(d2, u2), m2 = e48 % 2 == 0 ? 1 : -1, g2 = l2 > kG ? a2 / l2 : p2 > kG ? -u2 / p2 * m2 : 1, f2 = l2 > kG ? c2 / l2 : p2 > kG ? d2 / p2 * m2 : 0, _2 = Math.min(0.04, h2);
r2 = dU({ routes: t2, via: s2, dx: g2 * _2, dy: f2 * _2, node: n2 }) || r2;
}
}
return r2;
};
var mU = (e47) => {
const { routes: t2, routeIndex: n2, pointIndex: o2, dx: i2, dy: r2, node: s2 } = e47, a2 = t2[n2];
if (!a2 || o2 <= 0 || o2 >= a2.route.length - 1)
return false;
const c2 = ((e48, t3, n3 = 0.001) => {
const o3 = e48[t3];
if (!o3)
return [];
const i3 = [t3];
for (let r3 = t3 - 1;r3 >= 0; r3 -= 1) {
const t4 = e48[r3];
if (!t4 || !dG(t4, o3, n3))
break;
i3.push(r3);
}
for (let r3 = t3 + 1;r3 < e48.length; r3 += 1) {
const t4 = e48[r3];
if (!t4 || !dG(t4, o3, n3))
break;
i3.push(r3);
}
return [...new Set(i3)];
})(a2.route, o2);
if (NG(a2.route.length, c2))
return false;
const l2 = uG(s2, kG);
let h2 = false;
for (const e48 of c2) {
const t3 = a2.route[e48];
t3 && (t3.x = YG(t3.x + i2, l2.minX, l2.maxX), t3.y = YG(t3.y + r2, l2.minY, l2.maxY), h2 = true);
}
return h2;
};
var gU = (e47) => {
const { routes: t2, segment: n2, dx: o2, dy: i2, node: r2, t: s2 } = e47, a2 = 1 - $G(s2), c2 = $G(s2), l2 = mU({ routes: t2, routeIndex: n2.routeIndex, pointIndex: n2.startIndex, dx: o2 * a2, dy: i2 * a2, node: r2 }), h2 = mU({ routes: t2, routeIndex: n2.routeIndex, pointIndex: n2.endIndex, dx: o2 * c2, dy: i2 * c2, node: r2 });
return l2 || h2;
};
var fU = (e47) => {
const { routes: t2, node: n2, segments: o2, movableRouteIndexes: i2 } = e47;
let r2 = false;
for (let e48 = 0;e48 < o2.length; e48 += 1) {
const s2 = o2[e48];
if (s2)
for (let a2 = e48 + 1;a2 < o2.length; a2 += 1) {
const c2 = o2[a2];
if (!c2 || s2.z !== c2.z || s2.rootConnectionName === c2.rootConnectionName)
continue;
const l2 = s2.traceRadius + c2.traceRadius + 0.1 + DG;
if (Math.max(s2.start.x, s2.end.x) + l2 <= Math.min(c2.start.x, c2.end.x) || Math.max(c2.start.x, c2.end.x) + l2 <= Math.min(s2.start.x, s2.end.x) || Math.max(s2.start.y, s2.end.y) + l2 <= Math.min(c2.start.y, c2.end.y) || Math.max(c2.start.y, c2.end.y) + l2 <= Math.min(s2.start.y, s2.end.y))
continue;
const [h2] = bG(s2, c2);
if (!h2)
continue;
const d2 = h2.leftPoint.x - h2.rightPoint.x, u2 = h2.leftPoint.y - h2.rightPoint.y, p2 = pG(d2, u2), m2 = l2 - p2;
if (m2 <= 0)
continue;
const g2 = !i2 || i2.has(s2.routeIndex), f2 = !i2 || i2.has(c2.routeIndex), _2 = Number(g2) + Number(f2);
if (_2 === 0)
continue;
const y2 = s2.end.x - s2.start.x, b2 = s2.end.y - s2.start.y, x2 = pG(y2, b2), v2 = (e48 + a2) % 2 == 0 ? 1 : -1, I2 = p2 > kG ? d2 / p2 : x2 > kG ? -b2 / x2 * v2 : 1, S2 = p2 > kG ? u2 / p2 : x2 > kG ? y2 / x2 * v2 : 0, C2 = Math.min(0.025, m2 / _2);
g2 && (r2 = gU({ routes: t2, segment: s2, dx: I2 * C2, dy: S2 * C2, node: n2, t: h2.leftT }) || r2), f2 && (r2 = gU({ routes: t2, segment: c2, dx: -I2 * C2, dy: -S2 * C2, node: n2, t: h2.rightT }) || r2);
}
}
return r2;
};
var _U = (e47, t2) => {
for (let n2 = 0;n2 < 10; n2 += 1) {
const n3 = hU(t2), o2 = _G(t2), i2 = uU({ routes: t2, node: e47, vias: n3 }), r2 = pU({ routes: t2, node: e47, vias: n3, segments: o2 }), s2 = fU({ routes: t2, node: e47, segments: o2 });
if (!i2 && !r2 && !s2)
break;
}
for (const e48 of t2)
e48.vias = hG(e48);
return t2;
};
var yU = (e47, t2, n2) => {
for (let o2 = 0;o2 < 10; o2 += 1) {
if (!fU({ routes: t2, node: e47, segments: _G(t2), movableRouteIndexes: n2 }))
break;
}
for (const e48 of n2) {
const n3 = t2[e48];
n3 && (n3.vias = hG(n3));
}
return t2;
};
var bU = (e47, t2, n2, o2, i2, r2 = 3, s2 = 0.02) => {
for (let a2 = 0;a2 < r2; a2 += 1) {
i2.fill(0);
const r3 = cU(o2);
for (let e48 = 0;e48 < n2.length; e48 += 1) {
const t3 = n2[e48];
if (!t3 || t3.kind !== "via")
continue;
const o3 = t3.node;
for (let r4 = e48 + 1;r4 < n2.length; r4 += 1) {
const c2 = n2[r4];
if (!c2 || c2.kind !== "via")
continue;
if (t3.rootConnectionName === c2.rootConnectionName)
continue;
const l2 = c2.node, h2 = o3.x - l2.x, d2 = o3.y - l2.y;
if (Math.abs(h2) >= TG || Math.abs(d2) >= TG)
continue;
const u2 = pG(h2, d2), p2 = TG - u2;
if (p2 <= 0)
continue;
let m2 = 0, g2 = 0;
if (u2 > kG) {
const e49 = 1 / u2;
m2 = h2 * e49, g2 = d2 * e49;
} else {
const t4 = 1.61803398875 * (1009 * a2 + 97 * e48 + 13 * r4);
m2 = Math.cos(t4), g2 = Math.sin(t4);
}
const f2 = Math.min(s2, 0.9 * p2), _2 = m2 * f2, y2 = g2 * f2;
iU(t3, _2, y2, i2), iU(c2, -_2, -y2, i2);
}
}
for (let e48 = 0;e48 < n2.length; e48 += 1) {
const t3 = n2[e48];
if (!t3)
continue;
const o3 = t3.node, c2 = JG(t3), l2 = lU(r3, t3, o3.x, o3.y, c2);
for (const n3 of l2)
for (const r4 of n3.candidateIndexes) {
const l3 = n3.segments[r4];
if (!l3)
continue;
if (t3.rootConnectionName === l3.rootConnectionName)
continue;
const { startNode: h2, endNode: d2 } = l3, u2 = d2.x - h2.x, p2 = d2.y - h2.y, m2 = u2 * u2 + p2 * p2;
if (m2 <= kG)
continue;
const g2 = o3.x - h2.x, f2 = o3.y - h2.y, _2 = $G((g2 * u2 + f2 * p2) / m2), y2 = h2.x + u2 * _2, b2 = h2.y + p2 * _2, x2 = o3.x - y2, v2 = o3.y - b2, I2 = pG(x2, v2), S2 = c2 - I2;
if (S2 <= 0)
continue;
const C2 = 1009 * a2 + 97 * e48 + 13 * l3.obstacleIndex;
let P2 = 0, M2 = 0;
if (I2 > kG) {
const e49 = 1 / I2;
P2 = x2 * e49, M2 = v2 * e49;
} else {
const e49 = -p2, t4 = u2, n4 = pG(e49, t4);
if (n4 > kG) {
const o4 = (C2 % 2 == 0 ? 1 : -1) / n4;
P2 = e49 * o4, M2 = t4 * o4;
} else {
const e50 = 1.61803398875 * C2;
P2 = Math.cos(e50), M2 = Math.sin(e50);
}
}
const w2 = Math.min(nU(t3, s2), S2 * tU(t3)), N2 = P2 * w2, T2 = M2 * w2;
iU(t3, N2, T2, i2), rU(l3, -N2, -T2, i2, _2);
}
}
for (let e48 = 0;e48 < t2.length; e48 += 1) {
const n3 = t2[e48];
if (n3)
for (let e49 = 0;e49 < n3.nodes.length; e49 += 1) {
const t3 = n3.nodes[e49];
if (!t3 || t3.fixed)
continue;
const o3 = 2 * t3.forceIndex;
let r4 = i2[o3] ?? 0, a3 = i2[o3 + 1] ?? 0;
const c2 = pG(r4, a3);
if (c2 > s2 && c2 > kG) {
const e50 = s2 / c2;
r4 *= e50, a3 *= e50;
}
t3.x += r4, t3.y += a3;
}
}
qG(t2, e47);
}
};
var xU = (e47, t2, n2, o2) => {
const { mutableRoutes: i2, totalNodeCount: r2 } = ((e48) => {
let t3 = 0;
return { mutableRoutes: e48.map((e49) => {
const n3 = [], o3 = new Int32Array(e49.route.length);
o3.fill(-1);
for (let i3 = 0;i3 < e49.route.length; i3 += 1) {
const r3 = e49.route[i3];
if (!r3)
continue;
const s3 = e49.route[i3 - 1], a3 = n3.at(-1), c3 = n3.length - 1;
a3 && s3 && s3.x === r3.x && s3.y === r3.y ? (s3.z !== r3.z && (a3.boundaryPadding = Math.max(a3.boundaryPadding, e49.viaDiameter / 2)), a3.pointIndexes.push(i3), a3.fixed ||= wG(e49.route.length, i3), o3[i3] = c3) : (n3.push({ x: r3.x, y: r3.y, originalX: r3.x, originalY: r3.y, boundaryPadding: 0, pointIndexes: [i3], fixed: wG(e49.route.length, i3), forceIndex: t3 }), o3[i3] = n3.length - 1, t3 += 1);
}
return { route: e49, rootConnectionName: e49.rootConnectionName ?? e49.connectionName, nodes: n3, pointNodeIndexes: o3 };
}), totalNodeCount: t3 };
})(t2), s2 = ((e48) => {
const t3 = [];
for (let n3 = 0;n3 < e48.length; n3 += 1) {
const o3 = e48[n3];
if (o3)
for (let e49 = 0;e49 < o3.nodes.length; e49 += 1) {
const i3 = o3.nodes[e49], r3 = i3?.pointIndexes[0], s3 = r3 === undefined ? undefined : o3.route.route[r3];
i3 && s3 && (i3.pointIndexes.length > 1 ? t3.push({ kind: "via", routeIndex: n3, rootConnectionName: o3.rootConnectionName, node: i3, fixed: i3.fixed }) : t3.push({ kind: "point", routeIndex: n3, rootConnectionName: o3.rootConnectionName, node: i3, z: s3.z, fixed: i3.fixed }));
}
}
return t3;
})(i2), a2 = ((e48) => {
const t3 = [];
for (let n3 = 0;n3 < e48.length; n3 += 1) {
const o3 = e48[n3];
if (o3)
for (let e49 = 0;e49 < o3.nodes.length - 1; e49 += 1) {
const n4 = o3.nodes[e49], i3 = o3.nodes[e49 + 1], r3 = n4?.pointIndexes[0], s3 = r3 === undefined ? undefined : o3.route.route[r3];
n4 && i3 && s3 && t3.push({ obstacleIndex: t3.length, rootConnectionName: o3.rootConnectionName, z: s3.z, startNode: n4, endNode: i3 });
}
}
return t3;
})(i2), c2 = new Float64Array(2 * r2), l2 = new Float64Array(2 * r2), h2 = o2?.includeForceVectors ?? true;
qG(i2, e47);
let d2 = [];
for (let t3 = 0;t3 < n2; t3 += 1) {
const o3 = n2 <= 1 ? 0 : t3 / Math.max(n2 - 1, 1), r3 = 0.25 + 0.75 * (1 - o3), u3 = 1 - o3, p2 = h2 && t3 === n2 - 1, m2 = p2 ? new Float64Array(2 * s2.length) : undefined;
c2.fill(0);
for (let e48 = 0;e48 < s2.length; e48 += 1) {
const t4 = s2[e48];
if (!t4 || t4.kind !== "via")
continue;
const n3 = t4.node;
for (let o4 = e48 + 1;o4 < s2.length; o4 += 1) {
const i3 = s2[o4];
if (!i3 || i3.kind !== "via")
continue;
if (t4.rootConnectionName === i3.rootConnectionName)
continue;
const a3 = i3.node, l3 = n3.x - a3.x, h3 = n3.y - a3.y;
if (Math.abs(l3) >= RG || Math.abs(h3) >= RG)
continue;
const d3 = pG(l3, h3);
let u4 = 0, p3 = 0;
if (d3 > kG) {
const e49 = 1 / d3;
u4 = l3 * e49, p3 = h3 * e49;
} else {
const t5 = 1.61803398875 * (97 * e48 + 13 * o4);
u4 = Math.cos(t5), p3 = Math.sin(t5);
}
const g3 = UG(d3, 0.034, 0.08, 18) * r3;
if (g3 <= 0)
continue;
const f2 = u4 * g3, _2 = p3 * g3;
iU(t4, f2, _2, c2, m2, e48), iU(i3, -f2, -_2, c2, m2, o4);
}
}
const g2 = cU(a2);
for (let e48 = 0;e48 < s2.length; e48 += 1) {
const t4 = s2[e48];
if (!t4)
continue;
const n3 = t4.node, o4 = QG(t4), i3 = lU(g2, t4, n3.x, n3.y, o4);
for (const s3 of i3)
for (const i4 of s3.candidateIndexes) {
const a3 = s3.segments[i4];
if (!a3)
continue;
if (t4.rootConnectionName === a3.rootConnectionName)
continue;
const { startNode: l3, endNode: h3 } = a3, d3 = h3.x - l3.x, u4 = h3.y - l3.y, p3 = d3 * d3 + u4 * u4;
if (p3 <= kG)
continue;
const g3 = n3.x - l3.x, f2 = n3.y - l3.y, _2 = $G((g3 * d3 + f2 * u4) / p3), y2 = l3.x + d3 * _2, b2 = l3.y + u4 * _2, x2 = n3.x - y2, v2 = n3.y - b2, I2 = pG(x2, v2), S2 = 97 * e48 + 13 * a3.obstacleIndex;
let C2 = 0, P2 = 0;
if (I2 > kG) {
const e49 = 1 / I2;
C2 = x2 * e49, P2 = v2 * e49;
} else {
const e49 = -u4, t5 = d3, n4 = pG(e49, t5);
if (n4 > kG) {
const o5 = (S2 % 2 == 0 ? 1 : -1) / n4;
C2 = e49 * o5, P2 = t5 * o5;
} else {
const e50 = 1.61803398875 * S2;
C2 = Math.cos(e50), P2 = Math.sin(e50);
}
}
const M2 = UG(I2, eU(t4), 0.08, 18, KG(t4), JG(t4), o4) * r3;
if (M2 <= 0)
continue;
const w2 = C2 * M2, N2 = P2 * M2;
iU(t4, w2, N2, c2, m2, e48), rU(a3, -w2, -N2, c2, _2);
}
}
p2 && (d2 = new Array(s2.length));
for (let t4 = 0;t4 < s2.length; t4 += 1) {
const n3 = s2[t4];
if (!n3)
continue;
const o4 = n3.node, i3 = sU(e47, n3, o4.x, o4.y, r3);
if (iU(n3, i3.x, i3.y, c2, m2, t4), p2 && m2) {
const e48 = 2 * t4;
d2[t4] = { kind: n3.kind, routeIndex: n3.routeIndex, rootConnectionName: n3.rootConnectionName, x: o4.x, y: o4.y, dx: m2[e48] ?? 0, dy: m2[e48 + 1] ?? 0 };
}
}
for (let t4 = 0;t4 < i2.length; t4 += 1) {
const n3 = i2[t4];
if (!n3)
continue;
const o4 = n3.nodes.length - 2;
for (let t5 = 0;t5 < n3.nodes.length; t5 += 1) {
const i3 = n3.nodes[t5];
if (!i3 || i3.fixed)
continue;
const s3 = 2 * i3.forceIndex;
let a3 = (c2[s3] ?? 0) + 0.14 * (i3.originalX - i3.x), l3 = (c2[s3 + 1] ?? 0) + 0.14 * (i3.originalY - i3.y), h3 = 0, d3 = 0, p3 = 0, m3 = 0;
const g3 = n3.nodes[t5 - 1], f2 = n3.nodes[t5 + 1];
if (g3 || f2) {
let e48 = 0, t6 = 0, n4 = 0;
if (g3 && (e48 += g3.x, t6 += g3.y, n4 += 1), f2 && (e48 += f2.x, t6 += f2.y, n4 += 1), n4 > 0) {
const o5 = 1 / n4;
a3 += 0.22 * (e48 * o5 - i3.x), l3 += 0.22 * (t6 * o5 - i3.y);
}
}
if (g3 && f2 && u3 > 0) {
const e48 = zG(f2, g3), t6 = FG(e48, e48);
if (t6 > kG) {
const n4 = $G(FG(zG(i3, g3), e48) / t6), o5 = jG(g3, f2, n4), r4 = XG(BG(zG(o5, i3), 0.55 * u3), 0.02 * u3);
h3 = r4.x, d3 = r4.y;
}
}
if (u3 > 0) {
if (t5 === 1 && g3?.fixed) {
const t6 = GG(g3, i3, e47, u3);
p3 += t6.x, m3 += t6.y;
}
if (t5 === o4 && f2?.fixed) {
const t6 = GG(f2, i3, e47, u3);
p3 += t6.x, m3 += t6.y;
}
}
let _2 = 0.85 * a3 * r3, y2 = 0.85 * l3 * r3;
const b2 = pG(_2, y2), x2 = 0.012 * r3;
if (b2 > x2 && b2 > kG) {
const e48 = x2 / b2;
_2 *= e48, y2 *= e48;
}
i3.x += _2 + h3 + p3, i3.y += y2 + d3 + m3;
}
}
qG(i2, e47), bU(e47, i2, s2, a2, l2, 3, 0.02);
}
bU(e47, i2, s2, a2, l2, 8, 0.03);
const u2 = ((e48) => e48.map(({ route: e49, nodes: t3, pointNodeIndexes: n3 }) => {
const o3 = e49.route.map((e50, o4) => {
const i4 = n3[o4] ?? -1, r3 = i4 >= 0 ? t3[i4] : undefined;
return r3 ? { ...e50, x: LG(r3.x), y: LG(r3.y) } : e50;
}), i3 = { ...e49, route: o3, vias: [] };
return i3.vias = hG(i3), i3;
}))(i2);
return { routes: u2, forceVectors: d2, stepsCompleted: n2 };
};
var vU = class extends sG {
sampleEntries;
originalHdRoutes;
originalNodeWithPortPoints;
colorMap;
totalStepsPerNode;
nodeAssignmentMargin;
improvedRoutesByIndex = new Map;
activeSampleIndex = 0;
latestVisualization = {};
constructor(e47) {
super(), this.originalHdRoutes = e47.hdRoutes, this.originalNodeWithPortPoints = e47.nodeWithPortPoints, this.colorMap = e47.colorMap ?? {}, this.totalStepsPerNode = e47.totalStepsPerNode ?? 60, this.nodeAssignmentMargin = e47.nodeAssignmentMargin ?? 0.2;
const t2 = new Map;
for (let n2 = 0;n2 < e47.hdRoutes.length; n2++) {
const o2 = HG(e47.hdRoutes[n2], e47.nodeWithPortPoints, this.nodeAssignmentMargin);
if (o2 === -1)
continue;
const i2 = t2.get(o2) ?? [];
i2.push(n2), t2.set(o2, i2);
}
this.sampleEntries = Array.from(t2.entries()).map(([t3, n2]) => ({ node: e47.nodeWithPortPoints[t3], routeIndexes: n2 })), this.MAX_ITERATIONS = Math.max(10 * this.sampleEntries.length, 1000), 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 e47 = this.sampleEntries[this.activeSampleIndex];
if (!e47)
return void (this.solved = true);
const t2 = WG(e47.node), n2 = e47.routeIndexes.map((e48) => this.originalHdRoutes[e48]), o2 = xU(t2, n2, this.totalStepsPerNode, { includeForceVectors: true });
_U(e47.node, o2.routes);
const i2 = PG(n2, o2.routes);
let r2 = i2.length === 0 ? o2 : xU(t2, ((e48, t3) => {
const { routes: n3, node: o3, selectors: i3 } = e48, r3 = structuredClone(n3), s2 = _G(n3), a2 = vG(s2), c2 = i3.flatMap((e49) => {
const t4 = a2[e49.leftRouteIndex]?.[e49.leftStartPointIndex], n4 = a2[e49.rightRouteIndex]?.[e49.rightStartPointIndex];
if (!t4 || !n4)
return [];
const [o4] = bG(t4, n4);
if (!o4)
return [];
const i4 = o4.leftPoint.x - o4.rightPoint.x, r4 = o4.leftPoint.y - o4.rightPoint.y, s3 = pG(i4, r4);
return s3 <= xG ? [] : [{ selector: e49, directionX: i4 / s3, directionY: r4 / s3, requiredDistance: t4.traceRadius + n4.traceRadius + 0.015 }];
});
for (let e49 = 0;e49 < 3; e49 += 1) {
const e50 = _G(r3), n4 = vG(e50);
for (const e51 of c2) {
const i4 = n4[e51.selector.leftRouteIndex]?.[e51.selector.leftStartPointIndex], s3 = n4[e51.selector.rightRouteIndex]?.[e51.selector.rightStartPointIndex];
if (!i4 || !s3)
continue;
const [a3] = bG(i4, s3);
if (!a3)
continue;
const c3 = (a3.leftPoint.x - a3.rightPoint.x) * e51.directionX + (a3.leftPoint.y - a3.rightPoint.y) * e51.directionY, l2 = e51.requiredDistance - c3;
if (l2 <= 0)
continue;
const h2 = Math.min(0.025, l2 / 2);
t3({ routes: r3, segment: i4, dx: e51.directionX * h2, dy: e51.directionY * h2, node: o3, t: a3.leftT }), t3({ routes: r3, segment: s3, dx: -e51.directionX * h2, dy: -e51.directionY * h2, node: o3, t: a3.rightT });
}
}
for (const e49 of r3)
e49.vias = hG(e49);
return r3;
})({ routes: n2, node: e47.node, selectors: i2 }, gU), this.totalStepsPerNode, { includeForceVectors: true });
if (r2 !== o2) {
_U(e47.node, r2.routes);
const t3 = PG(n2, r2.routes);
if (t3.length > 0) {
const o3 = ((e48, t4) => {
const { originalRoutes: n3, guardedRoutes: o4, node: i3, crossingSelectors: r3, protectedSelectors: s2 } = e48, a2 = vG(_G(n3)), c2 = vG(_G(o4)), l2 = MG(o4), h2 = s2.map(({ leftRouteIndex: e49, rightRouteIndex: t5 }) => IG(e49, t5)), d2 = uG(i3, xG);
for (const e49 of r3) {
const r4 = c2[e49.leftRouteIndex]?.[e49.leftStartPointIndex], s3 = c2[e49.rightRouteIndex]?.[e49.rightStartPointIndex];
if (!r4 || !s3)
continue;
const [u2] = bG(r4, s3);
if (!(!u2 || pG(u2.leftPoint.x - u2.rightPoint.x, u2.leftPoint.y - u2.rightPoint.y) > xG || u2.leftT <= xG || u2.leftT >= 0.999999 || u2.rightT <= xG || u2.rightT >= 0.999999))
for (const r5 of ["right", "left"]) {
const s4 = r5 === "left" ? e49.leftRouteIndex : e49.rightRouteIndex, u3 = r5 === "left" ? e49.leftStartPointIndex : e49.rightStartPointIndex, p2 = r5 === "left" ? e49.rightRouteIndex : e49.leftRouteIndex, m2 = r5 === "left" ? e49.rightStartPointIndex : e49.leftStartPointIndex, g2 = n3[s4], f2 = o4[s4], _2 = a2[p2]?.[m2], y2 = c2[p2]?.[m2];
if (!(g2 && f2 && _2 && y2))
continue;
const b2 = g2.route[u3]?.z, x2 = [];
for (let e50 = u3 - 2;e50 <= u3 + 3; e50 += 1) {
const t5 = g2.route[e50];
!t5 || e50 <= 0 || e50 >= g2.route.length - 1 || t5.z !== b2 || [g2.route[e50 - 1], g2.route[e50 + 1]].some((e51) => e51 && e51.z !== t5.z) || x2.push(e50);
}
if (x2.length !== 0)
for (const [e50, n4] of [[_2.start, y2.start], [_2.end, y2.end]])
for (const r6 of [1.51, 1.25, 1.75, 2]) {
const a3 = [...o4], c3 = structuredClone(f2);
a3[s4] = c3;
let u4 = true;
for (const t5 of x2) {
const o5 = g2.route[t5], i4 = c3.route[t5];
if (!o5 || !i4)
continue;
const s5 = n4.x + (o5.x - e50.x) * r6, a4 = n4.y + (o5.y - e50.y) * r6;
if (s5 <= d2.minX || s5 >= d2.maxX || a4 <= d2.minY || a4 >= d2.maxY) {
u4 = false;
break;
}
i4.x = s5, i4.y = a4;
}
if (!u4)
continue;
c3.vias = hG(c3);
let p3 = a3, m3 = MG(p3);
const _3 = new Set;
for (const [e51, t5] of m3)
SG(l2, [e51, t5]) || (e51 === s4 && t5 !== s4 ? _3.add(t5) : t5 === s4 && e51 !== s4 && _3.add(e51));
if (_3.size > 0) {
const e51 = t4(i3, structuredClone(a3), _3), n5 = MG(e51);
h2.every((e52) => !SG(n5, e52)) && n5.length < m3.length && (p3 = e51, m3 = n5);
}
if (h2.every((e51) => !SG(m3, e51)) && m3.length < l2.length)
return p3;
}
}
}
})({ originalRoutes: n2, guardedRoutes: r2.routes, node: e47.node, crossingSelectors: t3, protectedSelectors: [...i2, ...t3] }, yU);
o3 && (r2 = { ...r2, routes: o3 });
}
}
for (let t3 = 0;t3 < e47.routeIndexes.length; t3++)
this.improvedRoutesByIndex.set(e47.routeIndexes[t3], r2.routes[t3]);
this.latestVisualization = IU({ node: e47.node, routes: r2.routes, forceVectors: r2.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 = true);
}
getOutput() {
return this.originalHdRoutes.map((e47, t2) => this.improvedRoutesByIndex.get(t2) ?? e47);
}
visualize() {
return this.solved ? IU({ routes: this.getOutput(), colorMap: this.colorMap }) : this.latestVisualization;
}
};
var IU = (e47) => {
const t2 = [], n2 = [], o2 = [];
e47.node && o2.push({ center: e47.node.center, width: e47.node.width, height: e47.node.height, stroke: "rgba(14,165,233,0.7)", fill: "rgba(14,165,233,0.04)", label: e47.node.capacityMeshNodeId });
for (const o3 of e47.routes) {
const i2 = e47.colorMap?.[o3.connectionName] ?? "#0ea5e9";
for (let e48 = 0;e48 < o3.route.length - 1; e48++) {
const n3 = o3.route[e48], r2 = o3.route[e48 + 1];
n3.z === r2.z && t2.push({ points: [{ x: n3.x, y: n3.y }, { x: r2.x, y: r2.y }], strokeColor: n3.z === 0 ? i2 : cG(i2, 0.5), strokeWidth: o3.traceThickness, layer: `z${n3.z}`, strokeDash: n3.z !== 0 ? [0.1, 0.3] : undefined });
}
for (const e48 of o3.vias)
n2.push({ center: { x: e48.x, y: e48.y }, radius: o3.viaDiameter / 2, stroke: i2, fill: "rgba(14,165,233,0.12)" });
}
for (const n3 of e47.forceVectors ?? [])
t2.push({ points: [{ x: n3.x, y: n3.y }, { x: n3.x + 5 * n3.dx, y: n3.y + 5 * n3.dy }], strokeColor: "rgba(244,63,94,0.85)", strokeWidth: 0.06, strokeDash: [0.08, 0.08] });
return { lines: t2, circles: n2, rects: o2 };
};
var SU = class extends ai {
constructor(e47, t2, n2 = Number.POSITIVE_INFINITY, o2 = 0.010000000000000002) {
super(), this.nodes = e47, this.maxNodeDimension = t2, this.maxNodeRatio = n2, this.minNodeArea = o2, this.outputNodes = [];
}
nodes;
maxNodeDimension;
maxNodeRatio;
minNodeArea;
outputNodes;
getSolverName() {
return "NodeDimensionSubdivisionSolver";
}
getSubdivisionGrid(e47) {
const t2 = Number.isFinite(this.maxNodeDimension) && this.maxNodeDimension > 0, n2 = Number.isFinite(this.maxNodeRatio) && this.maxNodeRatio > 0;
let o2 = t2 ? Math.max(1, Math.ceil(e47.width / this.maxNodeDimension)) : 1, i2 = t2 ? Math.max(1, Math.ceil(e47.height / this.maxNodeDimension)) : 1;
if (n2 && e47.width > 0 && e47.height > 0)
for (;; ) {
const t3 = e47.width / o2, n3 = e47.height / i2;
if ((t3 >= n3 ? t3 / n3 : n3 / t3) <= this.maxNodeRatio)
break;
t3 >= n3 ? o2++ : i2++;
}
return { cols: o2, rows: i2 };
}
shouldRemoveNode(e47) {
const t2 = Number.isFinite(this.minNodeArea) && this.minNodeArea > 0;
if (!Number.isFinite(e47.width) || !Number.isFinite(e47.height))
return true;
if (!t2 || e47.width * e47.height >= this.minNodeArea)
return false;
if (Math.min(e47.width, e47.height) < 0.002)
return true;
if (e47._containsTarget)
return false;
let n2 = 0;
for (const t3 of this.nodes)
if (t3.capacityMeshNodeId !== e47.capacityMeshNodeId && e47.availableZ.some((e48) => t3.availableZ.includes(e48)) && hi(e47, t3)) {
if (t3._containsTarget)
return false;
if (n2++, n2 >= 2)
return false;
}
return true;
}
subdivideNode(e47) {
if (this.shouldRemoveNode(e47))
return [];
const { cols: t2, rows: n2 } = this.getSubdivisionGrid(e47);
if (t2 === 1 && n2 === 1)
return [e47];
const o2 = e47.width / t2, i2 = e47.height / n2, r2 = e47.center.x - e47.width / 2, s2 = e47.center.y - e47.height / 2, a2 = [];
for (let c2 = 0;c2 < n2; c2++)
for (let n3 = 0;n3 < t2; n3++)
a2.push({ ...e47, capacityMeshNodeId: `${e47.capacityMeshNodeId}__sub_${c2}_${n3}`, center: { x: r2 + o2 * (n3 + 0.5), y: s2 + i2 * (c2 + 0.5) }, width: o2, height: i2, availableZ: [...e47.availableZ] });
return a2;
}
_step() {
const e47 = this.nodes.length;
let t2 = 0, n2 = 0, o2 = 0;
for (const e48 of this.nodes) {
const i2 = !Number.isFinite(e48.width) || !Number.isFinite(e48.height), r2 = this.subdivideNode(e48);
r2.length !== 0 ? (r2.length > 1 && t2++, this.outputNodes.push(...r2)) : i2 ? o2++ : n2++;
}
this.stats = { inputNodeCount: e47, outputNodeCount: this.outputNodes.length, subdividedNodeCount: t2, removedSmallNodeCount: n2, removedInvalidNodeCount: o2, maxNodeDimension: this.maxNodeDimension, maxNodeRatio: this.maxNodeRatio, minNodeArea: this.minNodeArea }, this.solved = true;
}
visualize() {
return { rects: this.outputNodes.map((e47) => ({ center: e47.center, width: e47.width, height: e47.height, label: `${e47.capacityMeshNodeId}
${e47.width.toFixed(2)}x${e47.height.toFixed(2)}`, layer: `z${e47.availableZ.join(",")}`, fill: "rgba(0, 200, 255, 0.08)", stroke: "rgba(0, 120, 180, 0.5)" })) };
}
};
var CU = (e47) => {
const t2 = [...new Set(e47.filter((e48) => typeof e48 == "number" && Number.isInteger(e48) && e48 >= 0))].sort((e48, t3) => e48 - t3);
if (t2.length !== 0)
return `z${t2.join(",")}`;
};
var PU = (e47) => {
const t2 = [];
for (let n2 = 0;n2 < 31; n2++)
e47 & 1 << n2 && t2.push(n2);
return t2;
};
var MU = (e47) => typeof e47 == "object" && e47 !== null;
var wU = (e47) => MU(e47) ? { ...e47 } : e47 === undefined ? {} : { value: e47 };
var NU = (e47, t2) => {
const n2 = e47.topology.regionMetadata?.[t2];
if (MU(n2)) {
if (typeof n2.serializedRegionId == "string")
return n2.serializedRegionId;
if (typeof n2.regionId == "string")
return n2.regionId;
if (typeof n2.capacityMeshNodeId == "string")
return n2.capacityMeshNodeId;
}
return `region-${t2}`;
};
var TU = (e47, t2) => {
const n2 = e47.topology.portMetadata?.[t2];
if (MU(n2)) {
if (typeof n2.serializedPortId == "string")
return n2.serializedPortId;
if (typeof n2.portId == "string")
return (o2 = n2.portId).includes("::") ? o2.slice(0, o2.indexOf("::")) : o2;
}
var o2;
return `port-${t2}`;
};
var RU = (e47, t2) => {
const n2 = e47.problem.routeMetadata?.[t2];
return MU(n2) && typeof n2.connectionId == "string" ? n2.connectionId : `route-${t2}`;
};
var EU = (e47, t2) => {
const n2 = wU(e47.topology.regionMetadata?.[t2]);
if (MU(n2.center) || (n2.center = { x: e47.topology.regionCenterX[t2], y: e47.topology.regionCenterY[t2] }), typeof n2.width != "number" && (n2.width = e47.topology.regionWidth[t2]), typeof n2.height != "number" && (n2.height = e47.topology.regionHeight[t2]), !Array.isArray(n2.availableZ)) {
const o2 = e47.topology.regionAvailableZMask?.[t2] ?? 0;
o2 !== 0 && (n2.availableZ = PU(o2));
}
return n2.layer = CU(Array.isArray(n2.availableZ) ? n2.availableZ : []) ?? CU((e47.topology.regionIncidentPorts[t2] ?? []).map((t3) => e47.topology.portZ[t3])) ?? "z0", n2;
};
var AU = (e47, t2) => {
const n2 = wU(e47.topology.portMetadata?.[t2]);
return typeof n2.x != "number" && (n2.x = e47.topology.portX[t2]), typeof n2.y != "number" && (n2.y = e47.topology.portY[t2]), typeof n2.z != "number" && (n2.z = e47.topology.portZ[t2]), n2.layer = CU([e47.topology.portZ[t2]]) ?? "z0", n2;
};
var OU = (e47, t2, n2) => {
const o2 = (e47.topology.incidentPortRegion[t2] ?? []).find((e48) => e48 !== n2);
if (o2 === undefined)
throw new Error(`Port ${t2} is not incident to a region outside route region ${n2}`);
return o2;
};
var kU = (e47, t2, n2) => {
const { orderedPortIds: o2, orderedRegionIds: i2 } = ((e48, t3, n3) => {
if (n3.length === 0)
throw new Error(`Route ${t3} has no solved segments`);
const o3 = e48.problem.routeStartPort[t3], i3 = e48.problem.routeEndPort[t3], r3 = o3 === i3, s3 = new Map;
n3.forEach((e49, t4) => {
const n4 = { ...e49, segmentIndex: t4 }, o4 = s3.get(e49.fromPortId) ?? [];
o4.push(n4), s3.set(e49.fromPortId, o4);
const i4 = s3.get(e49.toPortId) ?? [];
i4.push(n4), s3.set(e49.toPortId, i4);
});
const a3 = [o3], c3 = [], l3 = (e49, t4, o4) => {
if (e49 === i3 && (!r3 || t4.size === n3.length))
return true;
for (const h3 of s3.get(e49) ?? []) {
if (t4.has(h3.segmentIndex))
continue;
const s4 = h3.fromPortId === e49 ? h3.toPortId : h3.fromPortId, d2 = r3 && s4 === i3 && t4.size + 1 === n3.length;
if (o4.has(s4) && !d2)
continue;
t4.add(h3.segmentIndex);
const u2 = !o4.has(s4);
if (u2 && o4.add(s4), c3.push(h3.regionId), a3.push(s4), l3(s4, t4, o4))
return true;
a3.pop(), c3.pop(), u2 && o4.delete(s4), t4.delete(h3.segmentIndex);
}
return false;
};
if (!l3(o3, new Set, new Set([o3])))
throw new Error(`Route ${t3} is not a single ordered path from ${o3} to ${i3}`);
return { orderedPortIds: a3, orderedRegionIds: c3 };
})(e47, t2, n2), r2 = i2[0], s2 = i2[i2.length - 1];
if (r2 === undefined || s2 === undefined)
throw new Error(`Route ${t2} could not determine endpoint regions`);
const a2 = NU(e47, OU(e47, o2[0], r2)), c2 = NU(e47, OU(e47, o2[o2.length - 1], s2)), l2 = ((e48, t3, n3, o3) => {
const i3 = e48.problem.routeMetadata?.[t3];
return { connectionId: RU(e48, t3), startRegionId: (MU(i3) && typeof i3.startRegionId == "string" ? i3.startRegionId : undefined) ?? n3, endRegionId: (MU(i3) && typeof i3.endRegionId == "string" ? i3.endRegionId : undefined) ?? o3, mutuallyConnectedNetworkId: (MU(i3) && typeof i3.mutuallyConnectedNetworkId == "string" ? i3.mutuallyConnectedNetworkId : undefined) ?? `net-${e48.problem.routeNet[t3]}` };
})(e47, t2, a2, c2), h2 = o2.map((t3, n3) => {
const r3 = { portId: TU(e47, t3), g: n3, h: 0, f: n3, hops: n3, ripRequired: false, nextRegionId: n3 < i2.length ? NU(e47, i2[n3]) : l2.endRegionId };
return n3 > 0 && (r3.lastPortId = TU(e47, o2[n3 - 1]), r3.lastRegionId = NU(e47, i2[n3 - 1])), r3;
});
return { connection: l2, solvedRoute: { connection: l2, path: h2, requiredRip: false } };
};
var DU = (e47) => {
if (!e47.solved || e47.failed)
throw new Error("convertToSerializedHyperGraph requires a solved, non-failed solver");
const { topology: t2 } = e47, n2 = ((e48) => {
const t3 = Array.from({ length: e48.problem.routeCount }, () => []);
return e48.state.regionSegments.forEach((e49, n3) => {
for (const [o3, i3, r3] of e49)
t3[o3].push({ regionId: n3, fromPortId: i3, toPortId: r3 });
}), t3;
})(e47), o2 = Array.from({ length: t2.regionCount }, (n3, o3) => {
const i3 = e47.state.regionSegments[o3].map(([t3, n4, o4]) => ({ regionPort1Id: TU(e47, n4), regionPort2Id: TU(e47, o4), connectionId: RU(e47, t3) }));
return { regionId: NU(e47, o3), pointIds: t2.regionIncidentPorts[o3].map((t3) => TU(e47, t3)), d: EU(e47, o3), ...i3.length > 0 && { assignments: i3 } };
}), i2 = Array.from({ length: t2.portCount }, (n3, o3) => {
const [i3, r3] = t2.incidentPortRegion[o3] ?? [];
if (i3 === undefined || r3 === undefined)
throw new Error(`Port ${o3} is missing incident regions`);
return { portId: TU(e47, o3), region1Id: NU(e47, i3), region2Id: NU(e47, r3), d: AU(e47, o3) };
}), r2 = n2.map((t3, n3) => kU(e47, n3, t3));
return { regions: o2, ports: i2, connections: r2.map(({ connection: e48 }) => e48), solvedRoutes: r2.map(({ solvedRoute: e48 }) => e48) };
};
var LU = 0.3;
var zU = (e47) => e47 > 0 && !(e47 & e47 - 1);
var BU = (e47, t2, n2, o2, i2, r2 = 0, s2 = 0.3, a2 = 0) => (2 * t2 + 1 * n2 + 1 * o2) * (s2 + 0.15) ** 2 * (1 + i2 / 5) / e47 + (zU(r2) ? 10 * t2 : 0) + a2 * (i2 / FU(r2)) ** 2 * 0.1 ** 2 / e47;
var FU = (e47) => {
if (e47 === 0)
return 2;
let t2 = e47 >>> 0, n2 = 0;
for (;t2 !== 0; )
n2 += 1 & t2, t2 >>>= 1;
return n2;
};
var jU = (e47, t2) => {
const { netIds: n2, lesserAngles: o2, greaterAngles: i2, layerMasks: r2 } = e47, { netId: s2, lesserAngle: a2, greaterAngle: c2, layerMask: l2 } = t2;
let h2 = 0, d2 = 0;
for (let e48 = 0;e48 < n2.length; e48++) {
if (s2 === n2[e48])
continue;
(a2 < o2[e48] && o2[e48] < c2) !== (a2 < i2[e48] && i2[e48] < c2) && ((l2 & r2[e48]) !== 0 ? h2++ : d2++);
}
t2.sameLayerIntersectionCount = h2, t2.crossingLayerIntersectionCount = d2;
};
var $U = (e47, t2, n2) => {
const o2 = e47.routeStartPort[t2], i2 = e47.routeEndPort[t2], r2 = new Map;
for (const { fromPortId: e48, toPortId: t3 } of n2) {
const n3 = r2.get(e48) ?? new Set;
n3.add(t3), r2.set(e48, n3);
const o3 = r2.get(t3) ?? new Set;
o3.add(e48), r2.set(t3, o3);
}
const s2 = new Set, a2 = [o2];
for (;a2.length > 0; ) {
const e48 = a2.pop();
if (!s2.has(e48)) {
s2.add(e48);
for (const t3 of r2.get(e48) ?? [])
a2.push(t3);
}
}
if (!s2.has(i2))
throw new Error(`Initial assignments for route ${t2} do not connect ${o2} to ${i2}`);
if (n2.some(({ fromPortId: e48, toPortId: t3 }) => !s2.has(e48) || !s2.has(t3)))
throw new Error(`Initial assignments for route ${t2} contain disconnected segments`);
};
var YU = ({ topology: e47, problem: t2, state: n2, routeSuccessCountByRouteId: o2, appendSegmentToRegionCache: i2 }) => {
const r2 = t2.initialAssignments ?? [];
if (r2.length === 0)
return;
const s2 = new Map;
for (const n3 of r2) {
const { routeId: o3, regionId: i3, fromPortId: r3, toPortId: a3 } = n3;
if (!Number.isInteger(o3) || o3 < 0 || o3 >= t2.routeCount)
throw new Error(`Initial assignment references invalid route ${o3}`);
if (!Number.isInteger(i3) || i3 < 0 || i3 >= e47.regionCount)
throw new Error(`Initial assignment references invalid region ${i3}`);
for (const t3 of [r3, a3]) {
if (!Number.isInteger(t3) || t3 < 0 || t3 >= e47.portCount)
throw new Error(`Initial assignment references invalid port ${t3}`);
if (!e47.incidentPortRegion[t3]?.includes(i3))
throw new Error(`Initial assignment port ${t3} is not incident to region ${i3}`);
}
const c2 = s2.get(o3) ?? [];
c2.push(n3), s2.set(o3, c2);
}
for (const [e48, n3] of s2)
$U(t2, e48, n3);
const a2 = new Set(s2.keys());
for (const { routeId: e48, regionId: o3, fromPortId: s3, toPortId: a3 } of r2) {
const r3 = t2.routeNet[e48];
for (const e49 of [s3, a3]) {
const t3 = n2.portAssignment[e49];
if (t3 !== -1 && t3 !== r3)
throw new Error(`Initial assignment port ${e49} is assigned to multiple nets`);
n2.portAssignment[e49] = r3;
}
n2.currentRouteNetId = r3, n2.regionSegments[o3].push([e48, s3, a3]), i2(o3, s3, a3);
}
n2.currentRouteNetId = undefined, n2.unroutedRoutes = n2.unroutedRoutes.filter((e48) => !a2.has(e48));
for (const e48 of a2)
o2[e48] = 1;
return { initialAssignmentCount: r2.length, initiallyRoutedRouteCount: a2.size };
};
var XU = class {
constructor(e47, t2) {
this.items = e47, this.compare = t2;
}
items;
compare;
get length() {
return this.items.length;
}
toArray() {
return [...this.items];
}
clear() {
this.items.length = 0;
}
queue(e47) {
this.items.push(e47), this.siftUp(this.items.length - 1);
}
dequeue() {
const e47 = this.items[0];
if (e47 === undefined)
return;
const t2 = this.items.pop();
return this.items.length > 0 && (this.items[0] = t2, this.siftDown(0)), e47;
}
siftUp(e47) {
let t2 = e47;
for (;t2 > 0; ) {
const e48 = t2 - 1 >> 1, n2 = this.items[e48], o2 = this.items[t2];
if (this.compare(n2, o2) <= 0)
return;
this.items[e48] = o2, this.items[t2] = n2, t2 = e48;
}
}
siftDown(e47) {
let t2 = e47;
const n2 = this.items.length;
for (;; ) {
const e48 = 2 * t2 + 1;
if (e48 >= n2)
return;
const o2 = e48 + 1;
let i2 = e48;
o2 < n2 && this.compare(this.items[o2], this.items[e48]) < 0 && (i2 = o2);
const r2 = this.items[t2], s2 = this.items[i2];
if (this.compare(r2, s2) <= 0)
return;
this.items[t2] = s2, this.items[i2] = r2, t2 = i2;
}
}
};
var WU = (e47, t2) => {
const n2 = [...e47], o2 = ((e48) => {
let t3 = e48 >>> 0;
return () => {
t3 += 1831565813;
let e49 = t3;
return e49 = Math.imul(e49 ^ e49 >>> 15, 1 | e49), e49 ^= e49 + Math.imul(e49 ^ e49 >>> 7, 61 | e49), ((e49 ^ e49 >>> 14) >>> 0) / 4294967296;
};
})(t2);
for (let e48 = n2.length - 1;e48 > 0; e48--) {
const t3 = Math.floor(o2() * (e48 + 1));
[n2[e48], n2[t3]] = [n2[t3], n2[e48]];
}
return n2;
};
var VU = (e47, t2) => e47.routeMetadata?.[t2];
var HU = (e47) => e47?.simpleRouteConnection?.pointsToConnect?.map(({ pointId: e48 }) => typeof e48 == "string" ? e48 : null).filter((e48) => e48 !== null) ?? [];
var GU = (e47, t2) => {
const n2 = VU(e47, t2)?.connectionId;
return typeof n2 == "string" ? n2 : `route-${t2}`;
};
var UU = (e47, t2, n2) => {
const o2 = e47.portEndpointNetIds[n2];
if (!o2)
return false;
for (const e48 of o2)
if (e48 !== t2)
return true;
return false;
};
var ZU = (e47, t2, n2) => {
const o2 = e47.regionNetId[n2];
return o2 !== -1 && o2 !== t2;
};
var qU = (e47) => [...new Set(e47.routeIds)].filter((t2) => !((e48, t3) => {
const { topology: n2, problem: o2, problemSetup: i2, portAssignment: r2, maxPrecheckHops: s2 } = e48, a2 = o2.routeNet[t3], c2 = o2.routeStartPort[t3], l2 = o2.routeEndPort[t3];
if (c2 === l2)
return true;
const h2 = e48.getStartingNextRegionId(t3, c2);
if (h2 === undefined)
return false;
const d2 = [{ portId: c2, nextRegionId: h2 }], u2 = new Set([c2 * n2.regionCount + h2]);
for (let e49 = 0;e49 < d2.length; e49++) {
const t4 = d2[e49];
if (!ZU(o2, a2, t4.nextRegionId))
for (const e50 of n2.regionIncidentPorts[t4.nextRegionId] ?? []) {
const c3 = r2[e50];
if (UU(i2, a2, e50))
continue;
if (e50 === l2) {
if (c3 !== -1 && c3 !== a2)
continue;
return true;
}
if (e50 === t4.portId)
continue;
if (c3 !== -1 && c3 !== a2)
continue;
if (o2.portSectionMask[e50] === 0)
continue;
const h3 = n2.incidentPortRegion[e50] ?? [], p2 = h3[0] === t4.nextRegionId ? h3[1] : h3[0];
if (p2 === undefined || ZU(o2, a2, p2))
continue;
const m2 = e50 * n2.regionCount + p2;
if (!u2.has(m2)) {
if (u2.size >= s2)
return true;
u2.add(m2), d2.push({ portId: e50, nextRegionId: p2 });
}
}
}
return false;
})(e47, t2)).map((t2) => e47.getRouteSummary(t2));
var JU = (e47) => {
const t2 = new Array(e47);
for (let n2 = 0;n2 < e47; n2++)
t2[n2] = n2;
return t2;
};
var QU = "rgba(220, 38, 38, 0.98)";
var KU = "rgba(220, 38, 38, 0.18)";
var eZ = (...e47) => e47.filter((e48) => Boolean(e48)).join(`
`);
var tZ = (e47, t2) => {
const n2 = 0.005 * e47.topology.portZ[t2];
return { x: e47.topology.portX[t2] + n2, y: e47.topology.portY[t2] + n2 };
};
var nZ = (e47, t2) => CU([e47.topology.portZ[t2]]) ?? "z0";
var oZ = (e47, t2) => {
const n2 = e47.topology.portMetadata?.[t2];
return `port: ${n2?.serializedPortId ?? n2?.portId ?? `port-${t2}`}`;
};
var iZ = (e47, t2) => `z: ${e47.topology.portZ[t2]}`;
var rZ = (e47, t2) => ((e48, t3, n2) => {
const o2 = e48.topology.portZ[t3], i2 = e48.topology.portZ[n2];
return o2 === i2 ? `z: ${o2}` : `z: ${o2} -> ${i2}`;
})(e47, e47.problem.routeStartPort[t2], e47.problem.routeEndPort[t2]);
var sZ = (e47, t2) => `net: ${e47.problem.routeNet[t2]}`;
var aZ = 0.05;
var cZ = { r: 255, g: 64, b: 64, a: 0.72 };
var lZ = "rgba(220, 38, 38, 0.98)";
var hZ = "rgba(220, 38, 38, 0.12)";
var dZ = "10 6";
var uZ = (...e47) => e47.filter((e48) => Boolean(e48)).join(`
`);
var pZ = (e47) => Math.min(1, Math.max(0, e47));
var mZ = (e47, t2, n2) => Math.round(e47 + (t2 - e47) * n2);
var gZ = ({ r: e47, g: t2, b: n2, a: o2 }) => `rgba(${e47}, ${t2}, ${n2}, ${o2})`;
var fZ = (e47, t2) => {
const n2 = e47.problem.routeMetadata?.[t2];
return n2?.connectionId ?? n2?.mutuallyConnectedNetworkId ?? `route-${t2}`;
};
var _Z = (e47) => typeof e47.centerRouteId == "number";
var yZ = (e47, t2) => _Z(e47) ? t2 === e47.centerRouteId ? 1 : 0.5 : 1;
var bZ = (e47, t2) => {
const n2 = e47.match(/^(rgba|hsla)\((.*),\s*([0-9]*\.?[0-9]+)\)$/);
if (!n2)
return e47;
const [, o2, i2, r2] = n2, s2 = pZ(Number(r2) * t2);
return `${o2}(${i2}, ${Number(s2.toFixed(3))})`;
};
var xZ = (e47, t2, n2 = 0.8) => ((e48, t3, n3 = 0.8) => {
const o2 = `${e48.problem.routeNet[t3]}:${fZ(e48, t3)}`;
let i2 = 0;
for (let e49 = 0;e49 < o2.length; e49++)
i2 = 17777 * o2.charCodeAt(e49) + ((i2 << 5) - i2);
return `hsla(${Math.abs(i2) % 360}, 70%, 50%, ${n3})`;
})(e47, t2, n2 * yZ(e47, t2));
var vZ = (e47, t2) => `net: ${e47.problem.routeNet[t2]}`;
var IZ = (e47, t2) => {
const n2 = e47.topology.regionMetadata?.[t2], o2 = n2?.polygon;
if (Array.isArray(o2) && o2.length >= 3) {
const e48 = o2.map((e49) => e49.x), t3 = o2.map((e49) => e49.y);
return { minX: Math.min(...e48), maxX: Math.max(...e48), minY: Math.min(...t3), maxY: Math.max(...t3) };
}
const i2 = n2?.bounds;
if (i2 && typeof i2.minX == "number" && typeof i2.maxX == "number" && typeof i2.minY == "number" && typeof i2.maxY == "number")
return i2;
const r2 = e47.topology.regionWidth[t2], s2 = e47.topology.regionHeight[t2], a2 = e47.topology.regionCenterX[t2], c2 = e47.topology.regionCenterY[t2];
return { minX: a2 - r2 / 2, maxX: a2 + r2 / 2, minY: c2 - s2 / 2, maxY: c2 + s2 / 2 };
};
var SZ = (e47, t2) => ({ x: e47.topology.regionCenterX[t2], y: e47.topology.regionCenterY[t2] });
var CZ = (e47, t2) => {
const n2 = e47.topology.regionMetadata?.[t2], o2 = Array.isArray(n2?.availableZ) ? n2.availableZ.filter((e48) => typeof e48 == "number" && Number.isInteger(e48) && e48 >= 0) : [];
if (o2.length > 0)
return CU(o2) ?? "z0";
const i2 = PU(e47.topology.regionAvailableZMask?.[t2] ?? 0);
if (i2.length > 0)
return CU(i2) ?? "z0";
const r2 = [...new Set((e47.topology.regionIncidentPorts[t2] ?? []).map((t3) => e47.topology.portZ[t3]))].sort((e48, t3) => e48 - t3);
return CU(r2) ?? "z0";
};
var PZ = (e47, t2) => {
const n2 = e47.state.regionIntersectionCaches[t2], o2 = n2?.existingRegionCost ?? 0, i2 = e47.state.regionCongestionCost[t2] ?? 0, r2 = e47.problem.regionNetId[t2];
return uZ(`region: region-${t2}`, `net: ${r2 === -1 ? "free" : `${r2}`}`, e47.getAdditionalRegionLabel(t2), `cost: ${o2.toFixed(3)}`, `congestion: ${i2.toFixed(3)}`, `same layer X: ${n2?.existingSameLayerIntersections ?? 0}`, `trans X: ${n2?.existingCrossingLayerIntersections ?? 0}`, `entry exit X: ${n2?.existingEntryExitLayerChanges ?? 0}`);
};
var MZ = (e47, t2) => {
const n2 = e47.topology.regionMetadata?.[t2];
return n2?.isConnectionRegion ? { r: 255, g: 100, b: 255, a: 0.6 } : n2?.isThroughJumper ? { r: 100, g: 200, b: 100, a: 0.5 } : n2?.isPad ? { r: 255, g: 200, b: 100, a: 0.5 } : n2?.layer === "bottom" ? { r: 52, g: 152, b: 219, a: 0.08 } : { r: 200, g: 200, b: 255, a: 0.1 };
};
var wZ = (e47, t2) => {
const n2 = MZ(e47, t2), o2 = pZ(e47.state.regionIntersectionCaches[t2]?.existingRegionCost ?? 0);
return gZ((r2 = cZ, s2 = o2 ** 0.8, { r: mZ((i2 = n2).r, r2.r, s2), g: mZ(i2.g, r2.g, s2), b: mZ(i2.b, r2.b, s2), a: Number((i2.a + (r2.a - i2.a) * s2).toFixed(3)) }));
var i2, r2, s2;
};
var NZ = (e47, t2) => {
const n2 = ((e48, t3) => ({ x: e48.topology.portX[t3], y: e48.topology.portY[t3] }))(e47, t2), o2 = 0.005 * e47.topology.portZ[t2];
return { x: n2.x + o2, y: n2.y + o2 };
};
var TZ = NZ;
var RZ = (e47, t2) => CU([e47.topology.portZ[t2]]) ?? "z0";
var EZ = (e47, t2) => {
const n2 = e47.topology.portMetadata?.[t2];
return `port: ${n2?.serializedPortId ?? n2?.portId ?? `port-${t2}`}`;
};
var AZ = (e47, t2, n2) => {
if (n2 !== undefined)
return `net: ${e47.problem.routeNet[n2]}`;
const o2 = e47.state.portAssignment[t2];
if (o2 >= 0)
return `net: ${o2}`;
const i2 = new Set;
for (let n3 = 0;n3 < e47.problem.routeCount; n3++)
e47.problem.routeStartPort[n3] !== t2 && e47.problem.routeEndPort[n3] !== t2 || i2.add(e47.problem.routeNet[n3]);
return i2.size !== 0 ? `net: ${Array.from(i2).sort((e48, t3) => e48 - t3).join(", ")}` : undefined;
};
var OZ = (e47, t2) => `z: ${e47.topology.portZ[t2]}`;
var kZ = (e47, t2, n2) => {
const o2 = e47.topology.portZ[t2], i2 = e47.topology.portZ[n2];
return o2 === i2 ? `z: ${o2}` : `z: ${o2} -> ${i2}`;
};
var DZ = (e47, t2) => kZ(e47, e47.problem.routeStartPort[t2], e47.problem.routeEndPort[t2]);
var LZ = (e47, t2, n2) => uZ(EZ(e47, t2), ((e48, t3) => {
const n3 = e48.topology.incidentPortRegion[t3]?.[0], o2 = e48.topology.incidentPortRegion[t3]?.[1];
return `connects: region-${n3 ?? "?"} <-> region-${o2 ?? "?"}`;
})(e47, t2), AZ(e47, t2, n2));
var zZ = (e47, t2, n2, o2) => {
const i2 = e47.topology.portZ[n2];
return i2 !== e47.topology.portZ[o2] ? { strokeColor: bZ("rgba(22, 160, 133, 0.95)", yZ(e47, t2)), strokeDash: "2 4 2" } : i2 > 0 ? { strokeColor: bZ("rgba(52, 152, 219, 0.95)", yZ(e47, t2)), strokeDash: "3 2" } : { strokeColor: xZ(e47, t2) };
};
var BZ = (e47, t2) => {
for (let n2 = 0;n2 < e47.state.regionSegments.length; n2++) {
const o2 = e47.state.regionSegments[n2] ?? [];
for (const [i2, r2, s2] of o2)
t2.lines.push({ points: [NZ(e47, r2), NZ(e47, s2)], label: uZ(`route: ${fZ(e47, i2)}`, `region: region-${n2}`, kZ(e47, r2, s2)), layer: RZ(e47, r2), ...zZ(e47, i2, r2, s2) });
}
};
var FZ = (e47, t2) => {
const n2 = new Set;
for (let o2 = 0;o2 < e47.state.regionSegments.length; o2++) {
const i2 = e47.state.regionSegments[o2] ?? [];
for (const [o3, r2, s2] of i2)
for (const i3 of [r2, s2]) {
const r3 = `${o3}:${i3}`;
if (n2.has(r3))
continue;
n2.add(r3);
const s3 = NZ(e47, i3);
t2.points.push({ x: s3.x, y: s3.y, color: xZ(e47, o3, 1), layer: RZ(e47, i3), label: uZ(`route: ${fZ(e47, o3)}`, EZ(e47, i3), AZ(e47, i3, o3), OZ(e47, i3)) });
}
}
};
var jZ = (e47, t2) => {
for (let n2 = 0;n2 < e47.problem.routeCount; n2++)
if (e47.problem.routeStartPort[n2] === t2 || e47.problem.routeEndPort[n2] === t2)
return true;
return false;
};
var $Z = (e47, t2, n2) => {
const o2 = ((e48, t3) => {
const n3 = new Set;
for (let o3 = 0;o3 < t3.length; o3++)
if (t3[o3] === 1)
for (const t4 of e48.topology.incidentPortRegion[o3] ?? [])
n3.add(t4);
return n3;
})(e47, n2), i2 = "rgba(245, 158, 11, 0.95)", r2 = "rgba(245, 158, 11, 0.08)";
for (const n3 of o2) {
const o3 = e47.topology.regionMetadata?.[n3], s2 = o3?.polygon, a2 = IZ(e47, n3), c2 = SZ(e47, n3), l2 = a2.maxX - a2.minX, h2 = a2.maxY - a2.minY, d2 = CZ(e47, n3), u2 = uZ("section region", PZ(e47, n3));
Array.isArray(s2) && s2.length >= 3 ? t2.polygons.push({ points: s2, fill: r2, stroke: i2, strokeWidth: 2, layer: d2, label: u2 }) : t2.rects.push({ center: c2, width: Math.max(l2 - aZ, 0.05), height: Math.max(h2 - aZ, 0.05), fill: r2, stroke: i2, layer: d2, label: u2 });
}
for (let o3 = 0;o3 < n2.length; o3++)
n2[o3] === 1 && t2.circles.push({ center: TZ(e47, o3), radius: 0.07, fill: "rgba(251, 191, 36, 0.18)", stroke: i2, layer: RZ(e47, o3), label: uZ(LZ(e47, o3), OZ(e47, o3), "section port") });
};
var YZ = (e47, t2 = {}) => {
const n2 = { arrows: [], circles: [], infiniteLines: [], lines: [], points: [], polygons: [], rects: [], texts: [], title: "Tiny HyperGraph", coordinateSystem: "cartesian" }, o2 = ((e48, t3) => {
if (!t3?.highlightSectionMask)
return;
const n3 = t3.sectionPortMask ?? e48.problem.portSectionMask;
if (n3.length !== e48.topology.portCount)
return;
let o3 = 0, i3 = 0;
for (let e49 = 0;e49 < n3.length; e49++)
n3[e49] === 1 ? o3 += 1 : i3 += 1;
return o3 !== 0 && i3 !== 0 ? n3 : undefined;
})(e47, t2), i2 = ((e48) => {
const t3 = e48.getStaticallyUnroutableRoutes();
if (t3.length !== 0)
return new Set(t3.map((e49) => e49.routeId));
})(e47);
for (let t3 = 0;t3 < e47.topology.regionCount; t3++) {
const o3 = e47.topology.regionMetadata?.[t3], i3 = o3?.polygon, r3 = IZ(e47, t3), s3 = SZ(e47, t3), a2 = r3.maxX - r3.minX, c2 = r3.maxY - r3.minY, l2 = CZ(e47, t3), h2 = gZ(MZ(e47, t3));
Array.isArray(i3) && i3.length >= 3 ? n2.polygons.push({ points: i3, fill: h2, layer: l2 }) : n2.rects.push({ center: s3, width: Math.max(a2 - aZ, 0.05), height: Math.max(c2 - aZ, 0.05), fill: wZ(e47, t3), layer: l2, label: PZ(e47, t3) });
}
if (((e48, t3, n3) => {
for (let o3 = 0;o3 < e48.problem.routeCount; o3++) {
if (n3 && !n3.has(o3))
continue;
const i3 = e48.problem.routeStartPort[o3], r3 = e48.problem.routeEndPort[o3], s3 = NZ(e48, i3), a2 = NZ(e48, r3), c2 = xZ(e48, o3), l2 = fZ(e48, o3), h2 = vZ(e48, o3);
t3.points.push({ x: s3.x, y: s3.y, color: c2, layer: RZ(e48, i3), label: uZ(`route: ${l2}`, h2, "endpoint: start", EZ(e48, i3), OZ(e48, i3)) }), t3.points.push({ x: a2.x, y: a2.y, color: c2, layer: RZ(e48, r3), label: uZ(`route: ${l2}`, h2, "endpoint: end", EZ(e48, r3), OZ(e48, r3)) });
}
})(e47, n2, i2), e47.iterations === 0) {
for (const e48 of n2.polygons)
e48.stroke = "rgba(128, 128, 128, 0.5)";
for (const e48 of n2.rects)
e48.stroke = "rgba(128, 128, 128, 0.5)";
}
if (e47.iterations === 0) {
for (let i3 = 0;i3 < e47.topology.portCount; i3++) {
const r3 = o2?.[i3] === 1;
t2.showOnlySectionPortsOnIdle && !r3 || n2.circles.push({ center: TZ(e47, i3), radius: 0.05, fill: e47.topology.portZ[i3] > 0 ? "rgba(52, 152, 219, 0.55)" : "rgba(128, 128, 128, 0.5)", layer: RZ(e47, i3), label: uZ(LZ(e47, i3), OZ(e47, i3)) });
}
if (i2)
((e48, t3) => {
for (const n3 of e48.getStaticallyUnroutableRoutes()) {
const { routeId: o3, connectionId: i3, startPortId: r3, endPortId: s3 } = n3, a2 = tZ(e48, r3), c2 = tZ(e48, s3), l2 = eZ(`static reachability failed: ${i3}`, sZ(e48, o3), n3.startRegionId ? `startRegionId: ${n3.startRegionId}` : undefined, n3.endRegionId ? `endRegionId: ${n3.endRegionId}` : undefined, n3.pointIds.length >= 2 ? `points: ${n3.pointIds.join(" -> ")}` : undefined, rZ(e48, o3));
t3.lines.push({ points: [a2, c2], strokeColor: QU, strokeDash: "8 4", label: l2 }), t3.circles.push({ center: a2, radius: 0.12, fill: KU, stroke: QU, layer: nZ(e48, r3), label: eZ(l2, "endpoint: start", oZ(e48, r3), iZ(e48, r3)) }), t3.circles.push({ center: c2, radius: 0.12, fill: KU, stroke: QU, layer: nZ(e48, s3), label: eZ(l2, "endpoint: end", oZ(e48, s3), iZ(e48, s3)) });
}
})(e47, n2);
else {
const o3 = new Set;
for (const t3 of e47.state.regionSegments)
for (const [e48] of t3)
o3.add(e48);
if (o3.size > 0 && (BZ(e47, n2), FZ(e47, n2)), t2.showInitialRouteHints !== false) {
const t3 = new Set(e47.state.unroutedRoutes);
e47.state.currentRouteId !== undefined && t3.add(e47.state.currentRouteId), ((e48, t4, n3) => {
for (let o4 = 0;o4 < e48.problem.routeCount; o4++) {
if (n3 && !n3.has(o4))
continue;
const i3 = e48.problem.routeStartPort[o4], r3 = e48.problem.routeEndPort[o4], s3 = NZ(e48, i3), a2 = NZ(e48, r3), c2 = { x: (s3.x + a2.x) / 2, y: (s3.y + a2.y) / 2 };
t4.lines.push({ points: [s3, a2], strokeColor: xZ(e48, o4), strokeDash: "3 3", layer: RZ(e48, i3), label: uZ(fZ(e48, o4), DZ(e48, o4)) }), t4.points.push({ x: c2.x, y: c2.y, color: xZ(e48, o4, 1), layer: RZ(e48, i3), label: uZ(fZ(e48, o4), DZ(e48, o4)) });
}
})(e47, n2, t3);
}
}
} else
BZ(e47, n2), FZ(e47, n2), ((e48) => _Z(e48) && e48.showUnassignedPortsInVisualization === true)(e47) && ((e48, t3) => {
for (let n3 = 0;n3 < e48.topology.portCount; n3++)
e48.state.portAssignment[n3] >= 0 || jZ(e48, n3) || t3.circles.push({ center: TZ(e48, n3), radius: 0.04, fill: e48.topology.portZ[n3] > 0 ? "rgba(52, 152, 219, 0.2)" : "rgba(128, 128, 128, 0.2)", stroke: e48.topology.portZ[n3] > 0 ? "rgba(52, 152, 219, 0.6)" : "rgba(128, 128, 128, 0.6)", layer: RZ(e48, n3), label: uZ(LZ(e48, n3), OZ(e48, n3), "state: unassigned") });
})(e47, n2), _Z(e47) || (((e48, t3) => {
const n3 = e48.state.currentRouteId;
if (n3 === undefined || e48.solved)
return;
const o3 = e48.problem.routeStartPort[n3], i3 = e48.problem.routeEndPort[n3], r3 = NZ(e48, o3), s3 = NZ(e48, i3), a2 = xZ(e48, n3), c2 = fZ(e48, n3);
t3.lines.push({ points: [r3, s3], strokeColor: a2, strokeDash: "10 5", label: uZ(c2, DZ(e48, n3)) });
})(e47, n2), ((e48, t3) => {
if (e48.solved)
return;
const n3 = e48.state.currentRouteId, o3 = e48.state.candidateQueue.toArray().sort((e49, t4) => e49.f - t4.f).slice(0, 10);
for (let i4 = 0;i4 < o3.length; i4++) {
const r4 = o3[i4], s4 = NZ(e48, r4.portId), a2 = i4 === 0;
t3.points.push({ x: s4.x, y: s4.y, color: a2 ? "green" : "rgba(128, 128, 128, 0.25)", layer: RZ(e48, r4.portId), label: uZ(LZ(e48, r4.portId, n3), OZ(e48, r4.portId), `g: ${r4.g.toFixed(2)}`, `h: ${r4.h.toFixed(2)}`, `f: ${r4.f.toFixed(2)}`) });
}
const i3 = o3[0];
if (!i3)
return;
const r3 = [];
let s3 = i3;
for (;s3; )
r3.unshift(NZ(e48, s3.portId)), s3 = s3.prevCandidate;
r3.length > 1 && t3.lines.push({ points: r3, strokeColor: n3 !== undefined ? xZ(e48, n3) : "rgba(0, 160, 120, 0.9)" });
})(e47, n2));
o2 && $Z(e47, n2, o2), ((e48, t3) => {
if (e48.failed)
for (const n3 of e48.getNeverSuccessfullyRoutedRoutes()) {
const { routeId: o3, connectionId: i3, attempts: r3, startPortId: s3, endPortId: a2 } = n3, c2 = vZ(e48, o3), l2 = TZ(e48, s3), h2 = TZ(e48, a2), d2 = uZ(`never routed: ${i3}`, `attempts: ${r3}`, c2, n3.startRegionId ? `startRegionId: ${n3.startRegionId}` : undefined, n3.endRegionId ? `endRegionId: ${n3.endRegionId}` : undefined);
t3.lines.push({ points: [{ x: 0, y: 0 }, { x: l2.x, y: l2.y }], strokeColor: lZ, strokeDash: dZ, layer: RZ(e48, s3), label: uZ(d2, "origin guide", "endpoint: start") }), t3.circles.push({ center: l2, radius: 1, fill: hZ, stroke: lZ, layer: RZ(e48, s3), label: uZ(d2, "endpoint: start", EZ(e48, s3), OZ(e48, s3)) }), t3.lines.push({ points: [{ x: 0, y: 0 }, { x: h2.x, y: h2.y }], strokeColor: lZ, strokeDash: dZ, layer: RZ(e48, a2), label: uZ(d2, "origin guide", "endpoint: end") }), t3.circles.push({ center: h2, radius: 1, fill: hZ, stroke: lZ, layer: RZ(e48, a2), label: uZ(d2, "endpoint: end", EZ(e48, a2), OZ(e48, a2)) });
}
})(e47, n2);
const r2 = e47.state.unroutedRoutes.length + (e47.state.currentRouteId === undefined ? 0 : 1), s2 = o2 ? o2.reduce((e48, t3) => e48 + Number(t3 === 1), 0) : 0;
return n2.title = ["Tiny HyperGraph", `iter=${e47.iterations}`, `pending=${r2}`, o2 ? `sectionPorts=${s2}` : undefined, i2 ? `staticReachabilityFailed=${i2.size}` : undefined, e47.failed ? "failed" : e47.solved ? "solved" : "running"].filter(Boolean).join(" | "), n2;
};
var XZ = () => ({ 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 });
var WZ = (e47) => ({ netIds: new Int32Array(e47.netIds), lesserAngles: new Int32Array(e47.lesserAngles), greaterAngles: new Int32Array(e47.greaterAngles), layerMasks: new Int32Array(e47.layerMasks), existingCrossingLayerIntersections: e47.existingCrossingLayerIntersections, existingSameLayerIntersections: e47.existingSameLayerIntersections, existingEntryExitLayerChanges: e47.existingEntryExitLayerChanges, existingRegionCost: e47.existingRegionCost, existingSegmentCount: e47.existingSegmentCount });
var VZ = (e47) => {
return { portAssignment: new Int32Array(e47.portAssignment), regionSegments: (t2 = e47.regionSegments, t2.map((e48) => e48.map(([e49, t3, n2]) => [e49, t3, n2]))), regionIntersectionCaches: e47.regionIntersectionCaches.map(WZ), regionCongestionCost: new Float64Array(e47.regionCongestionCost), ripCount: e47.ripCount };
var t2;
};
var HZ = (e47, t2) => {
t2 && (t2.minViaPadDiameter !== undefined && (e47.minViaPadDiameter = t2.minViaPadDiameter), t2.DISTANCE_TO_COST !== undefined && (e47.DISTANCE_TO_COST = t2.DISTANCE_TO_COST), t2.RIP_THRESHOLD_START !== undefined && (e47.RIP_THRESHOLD_START = t2.RIP_THRESHOLD_START), t2.RIP_THRESHOLD_END !== undefined && (e47.RIP_THRESHOLD_END = t2.RIP_THRESHOLD_END), t2.RIP_THRESHOLD_RAMP_ATTEMPTS !== undefined && (e47.RIP_THRESHOLD_RAMP_ATTEMPTS = t2.RIP_THRESHOLD_RAMP_ATTEMPTS), t2.RIP_CONGESTION_REGION_COST_FACTOR !== undefined && (e47.RIP_CONGESTION_REGION_COST_FACTOR = t2.RIP_CONGESTION_REGION_COST_FACTOR), t2.TRACE_DENSITY_COST_FACTOR !== undefined && (e47.TRACE_DENSITY_COST_FACTOR = Math.max(0, t2.TRACE_DENSITY_COST_FACTOR)), t2.USE_LAZY_ROUTE_HEURISTIC !== undefined && (e47.USE_LAZY_ROUTE_HEURISTIC = t2.USE_LAZY_ROUTE_HEURISTIC), t2.USE_SPARSE_CANDIDATE_STORAGE !== undefined && (e47.USE_SPARSE_CANDIDATE_STORAGE = t2.USE_SPARSE_CANDIDATE_STORAGE), t2.MAX_ITERATIONS !== undefined && (e47.MAX_ITERATIONS = t2.MAX_ITERATIONS), t2.VERBOSE !== undefined && (e47.VERBOSE = t2.VERBOSE), t2.STATIC_REACHABILITY_PRECHECK !== undefined && (e47.STATIC_REACHABILITY_PRECHECK = t2.STATIC_REACHABILITY_PRECHECK), t2.STATIC_REACHABILITY_PRECHECK_MAX_HOPS !== undefined && (e47.STATIC_REACHABILITY_PRECHECK_MAX_HOPS = t2.STATIC_REACHABILITY_PRECHECK_MAX_HOPS), t2.ACCEPT_BEST_SOLUTION_ON_TIMEOUT !== undefined && (e47.ACCEPT_BEST_SOLUTION_ON_TIMEOUT = t2.ACCEPT_BEST_SOLUTION_ON_TIMEOUT), t2.GREEDY_FINAL_ROUTE_ITERS !== undefined && (e47.GREEDY_FINAL_ROUTE_ITERS = t2.GREEDY_FINAL_ROUTE_ITERS), t2.PARTIAL_RIP_ENABLED !== undefined && (e47.PARTIAL_RIP_ENABLED = t2.PARTIAL_RIP_ENABLED), t2.PARTIAL_RIP_MIN_ROUTE_COUNT !== undefined && (e47.PARTIAL_RIP_MIN_ROUTE_COUNT = t2.PARTIAL_RIP_MIN_ROUTE_COUNT), t2.PARTIAL_RIP_MAX_ROUTE_COUNT !== undefined && (e47.PARTIAL_RIP_MAX_ROUTE_COUNT = t2.PARTIAL_RIP_MAX_ROUTE_COUNT), t2.PARTIAL_RIP_MAX_DISTANCE !== undefined && (e47.PARTIAL_RIP_MAX_DISTANCE = t2.PARTIAL_RIP_MAX_DISTANCE), t2.PARTIAL_RIP_QUALITY_MAX_DISTANCE !== undefined && (e47.PARTIAL_RIP_QUALITY_MAX_DISTANCE = t2.PARTIAL_RIP_QUALITY_MAX_DISTANCE), t2.PARTIAL_RIP_MAX_ATTEMPTS !== undefined && (e47.PARTIAL_RIP_MAX_ATTEMPTS = t2.PARTIAL_RIP_MAX_ATTEMPTS), t2.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS !== undefined && (e47.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS = t2.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS), t2.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT !== undefined && (e47.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT = t2.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT), t2.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO !== undefined && (e47.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO = t2.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO), t2.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO !== undefined && (e47.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO = t2.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO), t2.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO !== undefined && (e47.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO = t2.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO), t2.OUTSIDE_IN_ROUTING !== undefined && (e47.OUTSIDE_IN_ROUTING = t2.OUTSIDE_IN_ROUTING), t2.OUTSIDE_IN_MAX_DISTANCE !== undefined && (e47.OUTSIDE_IN_MAX_DISTANCE = t2.OUTSIDE_IN_MAX_DISTANCE));
};
var GZ = (e47) => ({ minViaPadDiameter: e47.minViaPadDiameter, DISTANCE_TO_COST: e47.DISTANCE_TO_COST, RIP_THRESHOLD_START: e47.RIP_THRESHOLD_START, RIP_THRESHOLD_END: e47.RIP_THRESHOLD_END, RIP_THRESHOLD_RAMP_ATTEMPTS: e47.RIP_THRESHOLD_RAMP_ATTEMPTS, RIP_CONGESTION_REGION_COST_FACTOR: e47.RIP_CONGESTION_REGION_COST_FACTOR, TRACE_DENSITY_COST_FACTOR: e47.TRACE_DENSITY_COST_FACTOR, USE_LAZY_ROUTE_HEURISTIC: e47.USE_LAZY_ROUTE_HEURISTIC, USE_SPARSE_CANDIDATE_STORAGE: e47.USE_SPARSE_CANDIDATE_STORAGE, MAX_ITERATIONS: e47.MAX_ITERATIONS, VERBOSE: e47.VERBOSE, STATIC_REACHABILITY_PRECHECK: e47.STATIC_REACHABILITY_PRECHECK, STATIC_REACHABILITY_PRECHECK_MAX_HOPS: e47.STATIC_REACHABILITY_PRECHECK_MAX_HOPS, ACCEPT_BEST_SOLUTION_ON_TIMEOUT: e47.ACCEPT_BEST_SOLUTION_ON_TIMEOUT, GREEDY_FINAL_ROUTE_ITERS: e47.GREEDY_FINAL_ROUTE_ITERS, PARTIAL_RIP_ENABLED: e47.PARTIAL_RIP_ENABLED, PARTIAL_RIP_MIN_ROUTE_COUNT: e47.PARTIAL_RIP_MIN_ROUTE_COUNT, PARTIAL_RIP_MAX_ROUTE_COUNT: e47.PARTIAL_RIP_MAX_ROUTE_COUNT, PARTIAL_RIP_MAX_DISTANCE: e47.PARTIAL_RIP_MAX_DISTANCE, PARTIAL_RIP_QUALITY_MAX_DISTANCE: e47.PARTIAL_RIP_QUALITY_MAX_DISTANCE, PARTIAL_RIP_MAX_ATTEMPTS: e47.PARTIAL_RIP_MAX_ATTEMPTS, PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS: e47.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS, PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT: e47.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT, PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO: e47.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO, PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO: e47.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO, PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO: e47.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO, OUTSIDE_IN_ROUTING: e47.OUTSIDE_IN_ROUTING, OUTSIDE_IN_MAX_DISTANCE: e47.OUTSIDE_IN_MAX_DISTANCE });
var UZ = (e47, t2) => e47.f - t2.f;
var ZZ = class e47 extends De {
constructor(e48, t2, n2) {
super(), this.topology = e48, this.problem = t2, HZ(this, n2);
let o2 = 1;
const i2 = new Int32Array(e48.portCount).fill(-1), r2 = new Int32Array(e48.portCount).fill(-1);
for (let t3 = 0;t3 < e48.portCount; t3++) {
const n3 = e48.incidentPortRegion[t3] ?? [];
n3.length > o2 && (o2 = n3.length), i2[t3] = n3[0] ?? -1, r2[t3] = n3[1] ?? -1;
}
this.candidateHopSlotStride = o2, this.candidateFirstRegionByPortId = i2, this.candidateSecondRegionByPortId = r2;
const s2 = e48.portCount * o2;
this.candidateHopCapacity = s2, this.state = { portAssignment: new Int32Array(e48.portCount).fill(-1), regionSegments: Array.from({ length: e48.regionCount }, () => []), regionIntersectionCaches: Array.from({ length: e48.regionCount }, () => XZ()), currentRouteId: undefined, currentRouteNetId: undefined, unroutedRoutes: JU(t2.routeCount), candidateQueue: new XU([], UZ), candidateBestCostByHopId: this.USE_SPARSE_CANDIDATE_STORAGE ? new Map : new Float64Array(s2), candidateBestCostGenerationByHopId: this.USE_SPARSE_CANDIDATE_STORAGE ? new Map : new Uint32Array(s2), candidateBestCostGeneration: 1, goalPortId: -1, ripCount: 0, regionCongestionCost: new Float64Array(e48.regionCount).fill(0) }, this.routeAttemptCountByRouteId = new Uint32Array(t2.routeCount), this.routeSuccessCountByRouteId = new Uint32Array(t2.routeCount);
const a2 = YU({ topology: e48, problem: t2, state: this.state, routeSuccessCountByRouteId: this.routeSuccessCountByRouteId, appendSegmentToRegionCache: (e49, t3, n3) => this.appendSegmentToRegionCache(e49, t3, n3) });
a2 && (this.stats = { ...this.stats, ...a2 });
}
topology;
problem;
state;
candidateHopSlotStride;
candidateHopCapacity;
candidateFirstRegionByPortId;
candidateSecondRegionByPortId;
candidateOverflowBestCost;
_problemSetup;
routeAttemptCountByRouteId;
routeSuccessCountByRouteId;
bestSolvedStateSnapshot;
bestSolvedStateSummary;
hasLoggedNeverSuccessfullyRoutedRoutes = false;
staticallyUnroutableRoutes = [];
segmentGeometryScratch = { netId: 0, lesserAngle: 0, greaterAngle: 0, layerMask: 0, entryExitLayerChanges: 0, sameLayerIntersectionCount: 0, crossingLayerIntersectionCount: 0 };
ADD_SEGMENT_DISTANCE_TO_G = false;
costAwareFinalReripBudget = 0;
DISTANCE_TO_COST = 0.05;
minViaPadDiameter = LU;
RIP_THRESHOLD_START = 0.05;
RIP_THRESHOLD_END = 0.8;
RIP_THRESHOLD_RAMP_ATTEMPTS = 50;
RIP_CONGESTION_REGION_COST_FACTOR = 0.1;
TRACE_DENSITY_COST_FACTOR = 0;
USE_LAZY_ROUTE_HEURISTIC = false;
USE_SPARSE_CANDIDATE_STORAGE = false;
MAX_ITERATIONS = 1e6;
VERBOSE = false;
STATIC_REACHABILITY_PRECHECK = true;
STATIC_REACHABILITY_PRECHECK_MAX_HOPS = 16;
ACCEPT_BEST_SOLUTION_ON_TIMEOUT = true;
GREEDY_FINAL_ROUTE_ITERS = 4;
PARTIAL_RIP_ENABLED = false;
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 = 0.2;
PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO = 0.1;
OUTSIDE_IN_ROUTING = false;
OUTSIDE_IN_MAX_DISTANCE = 24;
resetForProblem(t2) {
if (this.constructor !== e47)
throw new Error("TinyHyperGraphSolver.resetForProblem cannot reset subclass routing state");
this.problem = t2, this._problemSetup = undefined, this.state.portAssignment.fill(-1);
for (const e48 of this.state.regionSegments)
e48.length = 0;
this.state.regionIntersectionCaches.fill(XZ()), this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.unroutedRoutes = JU(t2.routeCount), this.state.candidateQueue.clear(), this.state.candidateBestCostGeneration = 1, this.state.candidateBestCostByHopId instanceof Map ? this.state.candidateBestCostByHopId.clear() : this.state.candidateBestCostByHopId.fill(0), this.state.candidateBestCostGenerationByHopId instanceof Map ? this.state.candidateBestCostGenerationByHopId.clear() : this.state.candidateBestCostGenerationByHopId.fill(0), this.state.goalPortId = -1, this.state.ripCount = 0, this.state.regionCongestionCost.fill(0), this.routeAttemptCountByRouteId = new Uint32Array(t2.routeCount), this.routeSuccessCountByRouteId = new Uint32Array(t2.routeCount), this.bestSolvedStateSnapshot = undefined, this.bestSolvedStateSummary = undefined, this.hasLoggedNeverSuccessfullyRoutedRoutes = false, this.staticallyUnroutableRoutes = [], this.candidateOverflowBestCost?.clear(), this.solved = false, this.failed = false, this.iterations = 0, this.progress = 0, this.error = null, this.activeSubSolver = undefined, this.failedSubSolvers = undefined, this.timeToSolve = undefined, this.stats = {}, this._setupDone = false;
const n2 = YU({ topology: this.topology, problem: t2, state: this.state, routeSuccessCountByRouteId: this.routeSuccessCountByRouteId, appendSegmentToRegionCache: (e48, t3, n3) => this.appendSegmentToRegionCache(e48, t3, n3) });
n2 && (this.stats = { ...this.stats, ...n2 });
}
get problemSetup() {
return this._problemSetup || (this._problemSetup = this.computeProblemSetup()), this._problemSetup;
}
computeProblemSetup() {
const { topology: e48, problem: t2 } = this, n2 = this.USE_LAZY_ROUTE_HEURISTIC ? undefined : new Float64Array(e48.portCount * t2.routeCount), o2 = e48.portX, i2 = e48.portY, r2 = [], s2 = new Int32Array(e48.portCount).fill(-1), a2 = (e49, t3) => {
const n3 = r2[e49] ?? new Set;
n3.add(t3), r2[e49] = n3;
const o3 = s2[e49];
o3 === -1 ? s2[e49] = t3 : o3 !== t3 && (s2[e49] = -2);
};
for (let r3 = 0;r3 < t2.routeCount; r3++) {
const s3 = t2.routeNet[r3];
if (a2(t2.routeStartPort[r3], s3), a2(t2.routeEndPort[r3], s3), n2) {
const s4 = t2.routeEndPort[r3], a3 = o2[s4], c2 = i2[s4];
for (let s5 = 0;s5 < e48.portCount; s5++) {
const e49 = o2[s5] - a3, l2 = i2[s5] - c2;
n2[s5 * t2.routeCount + r3] = Math.sqrt(e49 * e49 + l2 * l2) * this.DISTANCE_TO_COST;
}
}
}
return { portHCostToEndOfRoute: n2, portEndpointNetIds: r2, portEndpointReservationNetId: s2 };
}
_setup() {
if (this.problemSetup, this.STATIC_REACHABILITY_PRECHECK) {
const e48 = qU({ 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: (e49, t2) => this.getStartingNextRegionId(e49, t2), getRouteSummary: (e49) => this.getRouteSummary(e49) });
this.staticallyUnroutableRoutes = e48, e48.length > 0 && (this.failed = true, this.error = ((e49) => {
const t2 = e49.slice(0, 5).map((e50) => {
const t3 = e50.pointIds.length >= 2 ? `${e50.pointIds[0]}->${e50.pointIds[1]}` : `${e50.startPortId}->${e50.endPortId}`;
return `${e50.connectionId} (${t3})`;
}).join(", "), n2 = e49.length - 5;
return ["Static reachability precheck failed:", `${e49.length} route(s) have no legal path under the current reservation and start-region rules`, n2 > 0 ? `${t2}, +${n2} more` : t2].join(" ");
})(e48), this.stats = { ...this.stats, staticallyUnroutableRouteCount: e48.length });
}
}
_step() {
const { problem: e48, topology: t2, state: n2 } = this;
if (n2.currentRouteId === undefined) {
if (n2.unroutedRoutes.length === 0)
return void this.onAllRoutesRouted();
n2.currentRouteId = n2.unroutedRoutes.shift(), n2.currentRouteNetId = e48.routeNet[n2.currentRouteId], this.routeAttemptCountByRouteId[n2.currentRouteId] += 1, this.resetCandidateBestCosts();
const t3 = this.getRouteStartPortId(n2.currentRouteId);
n2.candidateQueue.clear();
const o3 = this.getStartingNextRegionId(n2.currentRouteId, t3);
if (o3 === undefined)
return this.failed = true, void (this.error = `Start port ${t3} has no incident regions`);
const i3 = this.getHopId(t3, o3);
this.setCandidateBestCost(i3, 0), n2.candidateQueue.queue({ hopId: i3, nextRegionId: o3, portId: t3, f: 0, g: 0, h: 0 }), n2.goalPortId = this.getRouteEndPortId(n2.currentRouteId);
}
const o2 = n2.candidateQueue.dequeue();
if (!o2)
return void this.onOutOfCandidates();
const i2 = o2.hopId ?? this.getHopId(o2.portId, o2.nextRegionId);
if (o2.g > this.getCandidateBestCost(i2))
return;
if (this.isRegionReservedForDifferentNet(o2.nextRegionId))
return;
const r2 = t2.regionIncidentPorts[o2.nextRegionId];
for (const i3 of r2) {
if (i3 === n2.goalPortId) {
const e49 = n2.portAssignment[i3];
if (this.isPortReservedForDifferentNet(i3))
continue;
if (e49 !== -1 && e49 !== n2.currentRouteNetId)
continue;
return void this.onPathFound(o2);
}
if (i3 === o2.portId)
continue;
if (e48.portSectionMask[i3] === 0)
continue;
const r3 = t2.incidentPortRegion[i3][0] === o2.nextRegionId ? t2.incidentPortRegion[i3][1] : t2.incidentPortRegion[i3][0];
if (r3 === undefined)
continue;
const s2 = this.getHopId(i3, r3);
if ((n2.candidateQueue.isClosedHopId ? n2.candidateQueue.isClosedHopId(s2) : n2.candidateQueue.isClosedHop?.(i3, r3)) === true)
continue;
const a2 = n2.portAssignment[i3];
if (this.isPortReservedForDifferentNet(i3))
continue;
if (a2 !== -1 && a2 !== n2.currentRouteNetId)
continue;
if (this.isRegionReservedForDifferentNet(r3))
continue;
const c2 = this.getCandidateBestCost(s2);
if (o2.g >= c2)
continue;
let l2, h2 = o2.g + n2.regionCongestionCost[o2.nextRegionId] + (e48.portPenalty?.[i3] ?? 0);
if (this.ADD_SEGMENT_DISTANCE_TO_G) {
const e49 = t2.portX[o2.portId] - t2.portX[i3], n3 = t2.portY[o2.portId] - t2.portY[i3];
l2 = Math.sqrt(e49 * e49 + n3 * n3), h2 += l2 * this.DISTANCE_TO_COST;
}
if (h2 >= c2)
continue;
const d2 = this.computeG(o2, i3, c2, l2);
if (!Number.isFinite(d2) || d2 >= c2)
continue;
const u2 = this.computeH(i3), p2 = { hopId: s2, prevRegionId: o2.nextRegionId, nextRegionId: r3, portId: i3, g: d2, h: u2, f: d2 + u2, prevCandidate: o2 };
if (i3 === n2.goalPortId)
return void this.onPathFound(p2);
this.setCandidateBestCost(s2, d2), n2.candidateQueue.queue(p2);
}
}
resetCandidateBestCosts() {
const { state: e48 } = this;
if (this.candidateOverflowBestCost?.clear(), e48.candidateBestCostGeneration === 4294967295)
return e48.candidateBestCostByHopId instanceof Map && e48.candidateBestCostByHopId.clear(), e48.candidateBestCostGenerationByHopId instanceof Map ? e48.candidateBestCostGenerationByHopId.clear() : e48.candidateBestCostGenerationByHopId.fill(0), void (e48.candidateBestCostGeneration = 1);
e48.candidateBestCostGeneration += 1;
}
getCandidateBestCost(e48) {
if (e48 < 0)
return this.candidateOverflowBestCost?.get(e48) ?? Number.POSITIVE_INFINITY;
const { state: t2 } = this, n2 = t2.candidateBestCostGenerationByHopId;
return (n2 instanceof Map ? n2.get(e48) : n2[e48]) === t2.candidateBestCostGeneration ? t2.candidateBestCostByHopId instanceof Map ? t2.candidateBestCostByHopId.get(e48) : t2.candidateBestCostByHopId[e48] : Number.POSITIVE_INFINITY;
}
setCandidateBestCost(e48, t2) {
if (e48 < 0)
return this.candidateOverflowBestCost || (this.candidateOverflowBestCost = new Map), void this.candidateOverflowBestCost.set(e48, t2);
const { state: n2 } = this;
n2.candidateBestCostGenerationByHopId instanceof Map ? n2.candidateBestCostGenerationByHopId.set(e48, n2.candidateBestCostGeneration) : n2.candidateBestCostGenerationByHopId[e48] = n2.candidateBestCostGeneration, n2.candidateBestCostByHopId instanceof Map ? n2.candidateBestCostByHopId.set(e48, t2) : n2.candidateBestCostByHopId[e48] = t2;
}
getHopId(e48, t2) {
const n2 = e48 * this.candidateHopSlotStride;
if (this.candidateFirstRegionByPortId[e48] === t2)
return n2;
if (this.candidateSecondRegionByPortId[e48] === t2)
return n2 + 1;
const o2 = this.topology.incidentPortRegion[e48];
for (let e49 = 2;e49 < (o2?.length ?? 0); e49++)
if (o2[e49] === t2)
return n2 + e49;
return -(e48 * this.topology.regionCount + t2) - 1;
}
getStartingNextRegionId(e48, t2) {
const n2 = this.topology.incidentPortRegion[t2] ?? [], o2 = this.problem.routeNet[e48];
return n2.find((e49) => this.problem.regionNetId[e49] === -1) ?? n2.find((e49) => this.problem.regionNetId[e49] === o2) ?? n2[0];
}
getRouteStartPortId(e48) {
return this.problem.routeStartPort[e48];
}
getRouteEndPortId(e48) {
return this.problem.routeEndPort[e48];
}
isPortReservedForDifferentNet(e48) {
const t2 = this.problemSetup.portEndpointReservationNetId[e48] ?? -1;
return t2 === -2 || t2 !== -1 && t2 !== this.state.currentRouteNetId;
}
isRegionReservedForDifferentNet(e48) {
const t2 = this.problem.regionNetId[e48];
return t2 !== -1 && t2 !== this.state.currentRouteNetId;
}
isKnownSingleLayerRegion(e48) {
const t2 = this.topology.regionAvailableZMask?.[e48] ?? 0;
return zU(t2);
}
computeRegionCostForRegion(e48, t2, n2, o2, i2) {
return ((e49, t3, n3, o3, i3, r2, s2 = 0, a2 = 0.3, c2 = 0) => BU(e49 * t3, n3, o3, i3, r2, s2, a2, c2))(this.topology.regionWidth[e48], this.topology.regionHeight[e48], t2, n2, o2, i2, this.topology.regionAvailableZMask?.[e48] ?? 0, this.minViaPadDiameter, this.TRACE_DENSITY_COST_FACTOR);
}
populateSegmentGeometryScratch(e48, t2, n2) {
const { state: o2, topology: i2 } = this, r2 = this.segmentGeometryScratch, s2 = this.candidateFirstRegionByPortId[t2] === e48 || this.candidateSecondRegionByPortId[t2] !== e48 ? i2.portAngleForRegion1[t2] : i2.portAngleForRegion2?.[t2] ?? i2.portAngleForRegion1[t2], a2 = this.candidateFirstRegionByPortId[n2] === e48 || this.candidateSecondRegionByPortId[n2] !== e48 ? i2.portAngleForRegion1[n2] : i2.portAngleForRegion2?.[n2] ?? i2.portAngleForRegion1[n2], c2 = i2.portZ[t2], l2 = i2.portZ[n2];
return r2.lesserAngle = s2 < a2 ? s2 : a2, r2.greaterAngle = s2 < a2 ? a2 : s2, r2.layerMask = 1 << c2 | 1 << l2, r2.entryExitLayerChanges = c2 !== l2 ? 1 : 0, r2.netId = o2.currentRouteNetId, r2;
}
appendSegmentToRegionCache(e48, t2, n2) {
const { state: o2 } = this, i2 = o2.regionIntersectionCaches[e48], r2 = this.populateSegmentGeometryScratch(e48, t2, n2);
jU(i2, r2);
const { sameLayerIntersectionCount: s2, crossingLayerIntersectionCount: a2, entryExitLayerChanges: c2 } = r2, l2 = i2.netIds.length + 1, h2 = new Int32Array(l2);
h2.set(i2.netIds), h2[l2 - 1] = o2.currentRouteNetId;
const d2 = new Int32Array(l2);
d2.set(i2.lesserAngles), d2[l2 - 1] = r2.lesserAngle;
const u2 = new Int32Array(l2);
u2.set(i2.greaterAngles), u2[l2 - 1] = r2.greaterAngle;
const p2 = new Int32Array(l2);
p2.set(i2.layerMasks), p2[l2 - 1] = r2.layerMask;
const m2 = i2.existingSameLayerIntersections + s2, g2 = i2.existingCrossingLayerIntersections + a2, f2 = i2.existingEntryExitLayerChanges + c2, _2 = d2.length;
o2.regionIntersectionCaches[e48] = { netIds: h2, lesserAngles: d2, greaterAngles: u2, layerMasks: p2, existingSameLayerIntersections: m2, existingCrossingLayerIntersections: g2, existingEntryExitLayerChanges: f2, existingSegmentCount: _2, existingRegionCost: this.computeRegionCostForRegion(e48, m2, g2, f2, _2) };
}
getSolvedPathSegments(e48) {
const { state: t2 } = this, n2 = [];
let o2 = e48;
for (;o2; )
n2.unshift(o2), o2 = o2.prevCandidate;
const i2 = [];
for (let e49 = 1;e49 < n2.length; e49++)
i2.push({ regionId: n2[e49 - 1].nextRegionId, fromPortId: n2[e49 - 1].portId, toPortId: n2[e49].portId });
const r2 = n2[n2.length - 1];
return r2 && r2.portId !== t2.goalPortId && i2.push({ regionId: r2.nextRegionId, fromPortId: r2.portId, toPortId: t2.goalPortId }), i2;
}
resetRoutingStateForRerip() {
const { topology: e48, problem: t2, state: n2 } = this;
n2.portAssignment.fill(-1), n2.regionSegments = Array.from({ length: e48.regionCount }, () => []), n2.regionIntersectionCaches = Array.from({ length: e48.regionCount }, () => XZ()), n2.currentRouteNetId = undefined, n2.currentRouteId = undefined, n2.unroutedRoutes = WU(JU(t2.routeCount), n2.ripCount), n2.candidateQueue.clear(), this.resetCandidateBestCosts(), n2.goalPortId = -1;
}
getMaxRegionCost() {
const { topology: e48, state: t2 } = this;
let n2 = 0;
for (let o2 = 0;o2 < e48.regionCount; o2++) {
const e49 = t2.regionIntersectionCaches[o2]?.existingRegionCost ?? 0;
n2 = Math.max(n2, e49);
}
return n2;
}
getRouteMetadata(e48) {
return this.problem.routeMetadata?.[e48];
}
getRouteConnectionId(e48) {
const t2 = this.getRouteMetadata(e48)?.connectionId;
return typeof t2 == "string" ? t2 : `route-${e48}`;
}
getRouteSummary(e48) {
return (({ problem: e49, routeId: t2, getRouteMetadata: n2, getRouteConnectionId: o2 }) => {
const i2 = n2?.(t2) ?? VU(e49, t2);
return { routeId: t2, connectionId: o2?.(t2) ?? GU(e49, t2), startPortId: e49.routeStartPort[t2], endPortId: e49.routeEndPort[t2], startRegionId: typeof i2?.startRegionId == "string" ? i2.startRegionId : undefined, endRegionId: typeof i2?.endRegionId == "string" ? i2.endRegionId : undefined, pointIds: HU(i2) };
})({ problem: this.problem, routeId: e48, getRouteMetadata: (e49) => this.getRouteMetadata(e49), getRouteConnectionId: (e49) => this.getRouteConnectionId(e49) });
}
getAdditionalRegionLabel(e48) {}
getNeverSuccessfullyRoutedRoutes() {
const e48 = [];
for (let t2 = 0;t2 < this.problem.routeCount; t2++) {
const n2 = this.routeAttemptCountByRouteId[t2];
n2 === 0 || this.routeSuccessCountByRouteId[t2] > 0 || e48.push({ ...this.getRouteSummary(t2), attempts: n2 });
}
return e48;
}
getStaticallyUnroutableRoutes() {
return this.staticallyUnroutableRoutes;
}
logNeverSuccessfullyRoutedRoutes() {
if (!this.VERBOSE || this.hasLoggedNeverSuccessfullyRoutedRoutes)
return;
const e48 = this.getNeverSuccessfullyRoutedRoutes();
if (this.hasLoggedNeverSuccessfullyRoutedRoutes = true, e48.length !== 0) {
console.log(["[TinyHyperGraphSolver:never-routed-summary]", `count=${e48.length}`].join(" "));
for (const t2 of e48) {
const e49 = t2.pointIds.length >= 2 ? `${t2.pointIds[0]}->${t2.pointIds[1]}` : "unknown";
console.log(["[TinyHyperGraphSolver:never-routed]", `routeId=${t2.routeId}`, `connectionId=${t2.connectionId}`, `attempts=${t2.attempts}`, `pointPath=${e49}`, `startRegionId=${t2.startRegionId ?? "unknown"}`, `endRegionId=${t2.endRegionId ?? "unknown"}`].join(" "));
}
}
}
logRipEvent(e48, t2, n2 = {}) {
this.VERBOSE && console.log(["[TinyHyperGraphSolver:rip]", `ripCount=${this.state.ripCount}`, `maxRegionCostBeforeRip=${t2.toFixed(3)}`, `reason=${e48}`, ...Object.entries(n2).map(([e49, t3]) => `${e49}=${typeof t3 == "number" ? Number.isInteger(t3) ? String(t3) : t3.toFixed(3) : t3}`)].join(" "));
}
compareRegionCostSummaries(e48, t2) {
return e48.maxRegionCost !== t2.maxRegionCost ? e48.maxRegionCost - t2.maxRegionCost : e48.totalRegionCost - t2.totalRegionCost;
}
captureBestSolvedState(e48) {
this.bestSolvedStateSummary && this.compareRegionCostSummaries(e48, this.bestSolvedStateSummary) >= 0 || this.replaceBestSolvedState(e48);
}
replaceBestSolvedState(e48) {
this.bestSolvedStateSummary = e48, this.bestSolvedStateSnapshot = VZ({ 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 e48 = VZ(this.bestSolvedStateSnapshot);
this.state.portAssignment = e48.portAssignment, this.state.regionSegments = e48.regionSegments, this.state.regionIntersectionCaches = e48.regionIntersectionCaches, this.state.regionCongestionCost = e48.regionCongestionCost, this.state.ripCount = e48.ripCount, this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.unroutedRoutes = [], this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.state.goalPortId = -1;
}
getRemainingRouteIdsForGreedyFinalRoute() {
const e48 = new Set(this.state.unroutedRoutes);
return this.state.currentRouteId !== undefined && e48.add(this.state.currentRouteId), [...e48];
}
applySnapshotToGreedyFinalRouteSolver(e48, t2, n2) {
const o2 = VZ(t2);
e48.state.portAssignment = o2.portAssignment, e48.state.regionSegments = o2.regionSegments, e48.state.regionIntersectionCaches = o2.regionIntersectionCaches, e48.state.regionCongestionCost = o2.regionCongestionCost, e48.state.ripCount = 0, e48.state.currentRouteId = undefined, e48.state.currentRouteNetId = undefined, e48.state.unroutedRoutes = [...n2], e48.state.candidateQueue.clear(), e48.resetCandidateBestCosts(), e48.state.goalPortId = -1;
}
summarizeSolvedState(e48) {
let t2 = 0, n2 = 0;
for (const o2 of e48.state.regionIntersectionCaches) {
const e49 = o2.existingRegionCost;
t2 = Math.max(t2, e49), n2 += e49;
}
return { maxRegionCost: t2, totalRegionCost: n2 };
}
createGreedyFinalRouteSolver(e48, t2) {
return new qZ(this.topology, this.problem, e48);
}
tryGreedyFinalRouteAcceptance() {
const e48 = Math.max(0, Math.floor(this.GREEDY_FINAL_ROUTE_ITERS));
if (e48 === 0)
return false;
const t2 = this.getRemainingRouteIdsForGreedyFinalRoute();
if (t2.length === 0)
return false;
const n2 = VZ({ portAssignment: this.state.portAssignment, regionSegments: this.state.regionSegments, regionIntersectionCaches: this.state.regionIntersectionCaches, regionCongestionCost: this.state.regionCongestionCost, ripCount: this.state.ripCount });
let o2 = 50000;
for (let i2 = this.state.ripCount < this.costAwareFinalReripBudget ? -1 : 0;i2 < e48; i2++) {
const e49 = i2 <= 0 ? t2 : WU(t2, this.state.ripCount + i2), r2 = this.createGreedyFinalRouteSolver({ ...GZ(this), ACCEPT_BEST_SOLUTION_ON_TIMEOUT: false, GREEDY_FINAL_ROUTE_ITERS: 0, MAX_ITERATIONS: 50000, RIP_THRESHOLD_RAMP_ATTEMPTS: 0, STATIC_REACHABILITY_PRECHECK: false, OUTSIDE_IN_ROUTING: false, PARTIAL_RIP_ENABLED: false }, i2);
if (o2 = r2.MAX_ITERATIONS, this.applySnapshotToGreedyFinalRouteSolver(r2, n2, e49), r2.solve(), r2.solved && !r2.failed)
return this.bestSolvedStateSnapshot = VZ({ portAssignment: r2.state.portAssignment, regionSegments: r2.state.regionSegments, regionIntersectionCaches: r2.state.regionIntersectionCaches, regionCongestionCost: r2.state.regionCongestionCost, ripCount: r2.state.ripCount }), this.bestSolvedStateSummary = this.summarizeSolvedState(r2), this.restoreBestSolvedState(), this.stats = { ...this.stats, acceptedGreedyFinalRouteOnTimeout: true, greedyFinalRouteIter: Math.max(0, i2), finalRoutingStrategy: i2 < 0 ? "congestion-aware" : "greedy", greedyFinalRouteRemainingRouteCount: t2.length, greedyFinalRouteMaxIterations: o2, neverSuccessfullyRoutedRouteCount: 0, maxRegionCost: this.bestSolvedStateSummary.maxRegionCost, totalRegionCost: this.bestSolvedStateSummary.totalRegionCost, bestMaxRegionCost: this.bestSolvedStateSummary.maxRegionCost, bestTotalRegionCost: this.bestSolvedStateSummary.totalRegionCost }, this.solved = true, this.failed = false, this.error = null, true;
}
return this.stats = { ...this.stats, greedyFinalRouteAttemptCount: e48, greedyFinalRouteRemainingRouteCount: t2.length, greedyFinalRouteMaxIterations: o2 }, false;
}
onAllRoutesRouted() {
const { topology: e48, state: t2 } = this, n2 = this.RIP_THRESHOLD_RAMP_ATTEMPTS <= 0 ? 1 : Math.min(1, t2.ripCount / this.RIP_THRESHOLD_RAMP_ATTEMPTS), o2 = this.RIP_THRESHOLD_START + (this.RIP_THRESHOLD_END - this.RIP_THRESHOLD_START) * n2, i2 = [], r2 = new Float64Array(e48.regionCount);
let s2 = 0, a2 = 0;
for (let n3 = 0;n3 < e48.regionCount; n3++) {
const e49 = t2.regionIntersectionCaches[n3]?.existingRegionCost ?? 0;
r2[n3] = e49, s2 = Math.max(s2, e49), a2 += e49, e49 > o2 && i2.push(n3);
}
const c2 = { maxRegionCost: s2, totalRegionCost: a2 }, l2 = i2.length === 0 || t2.ripCount >= this.RIP_THRESHOLD_RAMP_ATTEMPTS;
if (l2 ? (!this.bestSolvedStateSummary || this.compareRegionCostSummaries(c2, this.bestSolvedStateSummary) < 0) && (this.bestSolvedStateSummary = c2) : this.captureBestSolvedState(c2), this.stats = { ...this.stats, currentRipThreshold: o2, hotRegionCount: i2.length, maxRegionCost: s2, totalRegionCost: a2, bestMaxRegionCost: this.bestSolvedStateSummary?.maxRegionCost, bestTotalRegionCost: this.bestSolvedStateSummary?.totalRegionCost, ripCount: t2.ripCount }, l2)
this.solved = true;
else {
for (let n3 = 0;n3 < e48.regionCount; n3++)
t2.regionCongestionCost[n3] += r2[n3] * this.RIP_CONGESTION_REGION_COST_FACTOR;
t2.ripCount += 1, this.resetRoutingStateForRerip(), this.stats = { ...this.stats, ripCount: t2.ripCount, maxRegionCostBeforeRip: s2, reripRegionCount: i2.length }, this.logRipEvent("hot_regions", s2, { hotRegionCount: i2.length, currentRipThreshold: o2 });
}
}
onOutOfCandidates() {
const { topology: e48, state: t2 } = this, n2 = t2.currentRouteId, o2 = this.getMaxRegionCost();
for (let n3 = 0;n3 < e48.regionCount; n3++) {
const e49 = t2.regionIntersectionCaches[n3]?.existingRegionCost ?? 0;
t2.regionCongestionCost[n3] += e49 * this.RIP_CONGESTION_REGION_COST_FACTOR;
}
t2.ripCount += 1, this.resetRoutingStateForRerip(), this.stats = { ...this.stats, ripCount: t2.ripCount, maxRegionCost: o2, maxRegionCostBeforeRip: o2, reripReason: "out_of_candidates" }, this.logRipEvent("out_of_candidates", o2, { ...n2 === undefined ? {} : { routeId: n2, connectionId: this.getRouteConnectionId(n2) } });
}
onPathFound(e48) {
const { state: t2 } = this, n2 = t2.currentRouteId;
if (n2 === undefined)
return;
this.routeSuccessCountByRouteId[n2] += 1;
const o2 = this.getSolvedPathSegments(e48);
for (const { regionId: e49, fromPortId: i2, toPortId: r2 } of o2)
t2.regionSegments[e49].push([n2, i2, r2]), t2.portAssignment[i2] = t2.currentRouteNetId, t2.portAssignment[r2] = t2.currentRouteNetId, this.appendSegmentToRegionCache(e49, i2, r2);
t2.candidateQueue.clear(), t2.currentRouteNetId = undefined, t2.currentRouteId = undefined;
}
computeG(e48, t2, n2 = Number.POSITIVE_INFINITY, o2) {
const { state: i2, topology: r2 } = this, s2 = e48.nextRegionId, a2 = i2.regionIntersectionCaches[s2], c2 = i2.regionCongestionCost[s2], l2 = this.problem.portPenalty?.[t2] ?? 0;
let h2 = 0;
if (this.ADD_SEGMENT_DISTANCE_TO_G) {
let n3 = o2;
if (n3 === undefined) {
const o3 = r2.portX[e48.portId] - r2.portX[t2], i3 = r2.portY[e48.portId] - r2.portY[t2];
n3 = Math.sqrt(o3 * o3 + i3 * i3);
}
h2 = n3 * this.DISTANCE_TO_COST;
}
if (e48.g + c2 + l2 + h2 > n2 + 0.000000001)
return Number.POSITIVE_INFINITY;
let d2 = 0, u2 = 0, p2 = r2.portZ[e48.portId] !== r2.portZ[t2] ? 1 : 0;
if (a2.existingSegmentCount > 0) {
const n3 = this.populateSegmentGeometryScratch(s2, e48.portId, t2);
jU(a2, n3), d2 = n3.sameLayerIntersectionCount, u2 = n3.crossingLayerIntersectionCount, p2 = n3.entryExitLayerChanges;
}
if (d2 > 0 && this.isKnownSingleLayerRegion(s2))
return Number.POSITIVE_INFINITY;
const m2 = this.computeRegionCostForRegion(s2, a2.existingSameLayerIntersections + d2, a2.existingCrossingLayerIntersections + u2, a2.existingEntryExitLayerChanges + p2, a2.existingSegmentCount + 1) - a2.existingRegionCost;
return e48.g + m2 + c2 + l2 + h2;
}
tryFinalAcceptance() {
const e48 = this.getNeverSuccessfullyRoutedRoutes();
if (this.stats = { ...this.stats, neverSuccessfullyRoutedRouteCount: e48.length }, this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT && this.bestSolvedStateSnapshot && this.bestSolvedStateSummary)
return this.restoreBestSolvedState(), this.stats = { ...this.stats, acceptedBestSolutionOnTimeout: true, maxRegionCost: this.bestSolvedStateSummary.maxRegionCost, totalRegionCost: this.bestSolvedStateSummary.totalRegionCost, bestMaxRegionCost: this.bestSolvedStateSummary.maxRegionCost, bestTotalRegionCost: this.bestSolvedStateSummary.totalRegionCost }, this.solved = true, this.failed = false, void (this.error = null);
this.ACCEPT_BEST_SOLUTION_ON_TIMEOUT && this.tryGreedyFinalRouteAcceptance() || this.logNeverSuccessfullyRoutedRoutes();
}
computeH(e48) {
const t2 = this.problemSetup.portHCostToEndOfRoute;
if (t2)
return t2[e48 * this.problem.routeCount + this.state.currentRouteId];
const n2 = this.getRouteEndPortId(this.state.currentRouteId), o2 = this.topology.portX[e48] - this.topology.portX[n2], i2 = this.topology.portY[e48] - this.topology.portY[n2];
return Math.sqrt(o2 * o2 + i2 * i2) * this.DISTANCE_TO_COST;
}
visualize() {
return YZ(this);
}
getOutput() {
return DU(this);
}
};
var qZ = class extends ZZ {
computeG(e48, t2) {
return e48.g;
}
};
var JZ = class {
constructor(e48, t2) {
this.regionCount = e48, this.compactHopIndex = t2, t2 && (this.hopStateGeneration = new Uint32Array(t2.hopCapacity), this.hopIndexOrClosed = new Int32Array(t2.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 && (this.currentHopStateGeneration === 4294967295 ? (this.hopStateGeneration.fill(0), this.currentHopStateGeneration = 1) : this.currentHopStateGeneration += 1);
}
isClosedHop(e48, t2) {
return this.isClosedHopId(this.getHopIdFromValues(e48, t2));
}
isClosedHopId(e48) {
return this.isHopClosed(e48);
}
queue(e48) {
const t2 = this.getHopId(e48);
if (this.isHopClosed(t2))
return;
const n2 = this.getQueuedHopIndex(t2);
if (n2 !== undefined) {
const t3 = this.items[n2];
if (e48.g >= t3.g)
return;
return this.items[n2] = e48, void (e48.f <= t3.f ? this.siftUp(n2) : this.siftDown(n2));
}
const o2 = this.items.length;
this.items.push(e48), this.siftUp(o2);
}
dequeue() {
const e48 = this.items[0];
if (!e48)
return;
const t2 = this.getHopId(e48);
this.closeHop(t2);
const n2 = this.items.pop();
return this.items.length > 0 && (this.items[0] = n2, this.siftDown(0)), e48;
}
getHopId(e48) {
if (e48.hopId !== undefined)
return e48.hopId;
const t2 = this.getHopIdFromValues(e48.portId, e48.nextRegionId);
return e48.hopId = t2, t2;
}
getHopIdFromValues(e48, t2) {
const n2 = this.compactHopIndex;
if (!n2)
return e48 * this.regionCount + t2;
const o2 = e48 * n2.hopSlotStride;
if (n2.firstRegionByPortId[e48] === t2)
return o2;
if (n2.secondRegionByPortId[e48] === t2)
return o2 + 1;
const i2 = n2.incidentPortRegion[e48];
for (let e49 = 2;e49 < (i2?.length ?? 0); e49++)
if (i2[e49] === t2)
return o2 + e49;
return -(e48 * this.regionCount + t2) - 1;
}
getQueuedHopIndex(e48) {
if (e48 >= 0 && this.hopStateGeneration) {
if (this.hopStateGeneration[e48] !== this.currentHopStateGeneration)
return;
const t2 = this.hopIndexOrClosed[e48];
return t2 >= 0 ? t2 : undefined;
}
return this.indexByHopId.get(e48);
}
isHopClosed(e48) {
return e48 >= 0 && this.hopStateGeneration ? this.hopStateGeneration[e48] === this.currentHopStateGeneration && this.hopIndexOrClosed[e48] === -1 : this.closedHopIds.has(e48);
}
setQueuedHopIndex(e48, t2) {
if (e48 >= 0 && this.hopStateGeneration)
return this.hopStateGeneration[e48] = this.currentHopStateGeneration, void (this.hopIndexOrClosed[e48] = t2);
this.indexByHopId.set(e48, t2);
}
closeHop(e48) {
if (e48 >= 0 && this.hopStateGeneration)
return this.hopStateGeneration[e48] = this.currentHopStateGeneration, void (this.hopIndexOrClosed[e48] = -1);
this.indexByHopId.delete(e48), this.closedHopIds.add(e48);
}
siftUp(e48) {
const t2 = this.items[e48];
let n2 = e48;
for (;n2 > 0; ) {
const e49 = n2 - 1 >> 1, o2 = this.items[e49];
if (o2.f <= t2.f)
break;
this.items[n2] = o2, this.setQueuedHopIndex(this.getHopId(o2), n2), n2 = e49;
}
this.items[n2] = t2, this.setQueuedHopIndex(this.getHopId(t2), n2);
}
siftDown(e48) {
const t2 = this.items[e48];
let n2 = e48;
for (;; ) {
const e49 = 2 * n2 + 1;
if (e49 >= this.items.length)
break;
const o2 = e49 + 1, i2 = o2 < this.items.length && this.items[o2].f < this.items[e49].f ? o2 : e49, r2 = this.items[i2];
if (t2.f <= r2.f)
break;
this.items[n2] = r2, this.setQueuedHopIndex(this.getHopId(r2), n2), n2 = i2;
}
this.items[n2] = t2, this.setQueuedHopIndex(this.getHopId(t2), n2);
}
};
var QZ = class extends ZZ {
constructor(e48, t2, n2) {
super(e48, t2, n2), this.ADD_SEGMENT_DISTANCE_TO_G = true;
}
_setup() {
super._setup(), this.state.candidateQueue = new JZ(this.topology.regionCount, { hopCapacity: this.candidateHopCapacity, hopSlotStride: this.candidateHopSlotStride, firstRegionByPortId: this.candidateFirstRegionByPortId, secondRegionByPortId: this.candidateSecondRegionByPortId, incidentPortRegion: this.topology.incidentPortRegion });
}
onPathFound(e48) {
const t2 = this.state.goalPortId;
if (e48.portId === t2)
return void super.onPathFound(e48);
const n2 = this.computeG(e48, t2);
if (!Number.isFinite(n2))
return;
const o2 = this.getHopId(t2, e48.nextRegionId);
n2 >= this.getCandidateBestCost(o2) || (this.setCandidateBestCost(o2, n2), this.state.candidateQueue.queue({ hopId: o2, prevRegionId: e48.nextRegionId, nextRegionId: e48.nextRegionId, portId: t2, g: n2, h: 0, f: n2, prevCandidate: e48 }));
}
};
var KZ = new Set;
var eq = class extends QZ {
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 = false;
useComplexityAwareSelection = false;
constructor(e48, t2, n2) {
super(e48, t2, n2), n2?.PARTIAL_RIP_ENABLED === undefined && (this.PARTIAL_RIP_ENABLED = true), n2?.OUTSIDE_IN_ROUTING === undefined && (this.OUTSIDE_IN_ROUTING = true), this.PARTIAL_RIP_ENABLED && n2?.PARTIAL_RIP_MAX_ATTEMPTS === undefined && (this.PARTIAL_RIP_MAX_ATTEMPTS = 10), (t2.routeCount < Math.max(0, this.PARTIAL_RIP_MIN_ROUTE_COUNT) || t2.routeCount > Math.max(0, this.PARTIAL_RIP_MAX_ROUTE_COUNT)) && (this.PARTIAL_RIP_ENABLED = false, this.OUTSIDE_IN_ROUTING = false), this.useComplexityAwareSelection = t2.routeCount >= Math.max(0, this.PARTIAL_RIP_COMPLEXITY_SELECTION_MIN_ROUTE_COUNT);
}
getRouteStartPortId(e48) {
return this.PARTIAL_RIP_ENABLED ? this.partialRipRoutePlans.get(e48)?.activeStartPortId ?? super.getRouteStartPortId(e48) : super.getRouteStartPortId(e48);
}
getRouteEndPortId(e48) {
return this.PARTIAL_RIP_ENABLED ? this.partialRipRoutePlans.get(e48)?.activeEndPortId ?? super.getRouteEndPortId(e48) : super.getRouteEndPortId(e48);
}
getStartingNextRegionId(e48, t2) {
if (!this.PARTIAL_RIP_ENABLED)
return super.getStartingNextRegionId(e48, t2);
const n2 = this.partialRipRoutePlans.get(e48);
return n2 && n2.activeStartPortId === t2 ? n2.forcedStartRegionId : super.getStartingNextRegionId(e48, t2);
}
getEndingNextRegionId(e48, t2) {
const n2 = this.partialRipRoutePlans.get(e48);
return n2 && n2.activeEndPortId === t2 ? n2.forcedEndRegionId : super.getStartingNextRegionId(e48, t2);
}
computeH(e48) {
if (!this.PARTIAL_RIP_ENABLED)
return super.computeH(e48);
const t2 = this.state.currentRouteId;
if (t2 === undefined || !this.partialRipRoutePlans.has(t2))
return super.computeH(e48);
const n2 = this.getRouteEndPortId(t2), o2 = this.topology.portX[e48] - this.topology.portX[n2], i2 = this.topology.portY[e48] - this.topology.portY[n2];
return Math.sqrt(o2 * o2 + i2 * i2) * this.DISTANCE_TO_COST;
}
onPathFound(e48) {
if (!this.PARTIAL_RIP_ENABLED && !this.OUTSIDE_IN_ROUTING)
return void super.onPathFound(e48);
const t2 = this.state.currentRouteId, n2 = t2 !== undefined && this.outsideInRouteSearch?.routeId === t2;
super.onPathFound(e48), t2 !== undefined && this.state.currentRouteId === undefined && (this.partialRipRoutePlans.delete(t2), n2 && (this.outsideInCompletedRouteCount += 1), this.oneSidedFallbackRouteId === t2 && (this.oneSidedFallbackRouteId = undefined)), this.outsideInRouteSearch = undefined, this.publishOutsideInStats();
}
resetRoutingStateForRerip() {
this.PARTIAL_RIP_ENABLED || this.OUTSIDE_IN_ROUTING ? (this.partialRipRoutePlans.clear(), this.outsideInRouteSearch = undefined, this.oneSidedFallbackRouteId = undefined, super.resetRoutingStateForRerip()) : super.resetRoutingStateForRerip();
}
clearPartialRipPlans(e48) {
for (const t2 of e48)
this.partialRipRoutePlans.delete(t2);
}
getRouteIdsPreferredForPreservation() {
return KZ;
}
getCommittedRouteSegments(e48) {
const t2 = [];
for (let n3 = 0;n3 < this.state.regionSegments.length; n3++)
for (const [o3, i3, r3] of this.state.regionSegments[n3] ?? [])
o3 === e48 && t2.push({ segmentIndex: t2.length, regionId: n3, fromPortId: i3, toPortId: r3 });
if (t2.length === 0)
return;
const n2 = new Map;
for (const e49 of t2)
for (const t3 of [e49.fromPortId, e49.toPortId]) {
const o3 = n2.get(t3) ?? [];
o3.push(e49.segmentIndex), n2.set(t3, o3);
}
const o2 = this.problem.routeEndPort[e48], i2 = [], r2 = new Set, s2 = new Set([this.problem.routeStartPort[e48]]), a2 = (e49) => {
if (e49 === o2)
return true;
for (const o3 of n2.get(e49) ?? []) {
if (r2.has(o3))
continue;
const n3 = t2[o3], c2 = n3.fromPortId === e49 ? n3.toPortId : n3.fromPortId;
if (!s2.has(c2)) {
if (r2.add(o3), s2.add(c2), i2.push({ regionId: n3.regionId, fromPortId: e49, toPortId: c2 }), a2(c2))
return true;
i2.pop(), s2.delete(c2), r2.delete(o3);
}
}
return false;
};
return a2(this.problem.routeStartPort[e48]) && r2.size === t2.length ? i2 : undefined;
}
getSegmentDistance(e48) {
const t2 = this.topology.portX[e48.fromPortId] - this.topology.portX[e48.toPortId], n2 = this.topology.portY[e48.fromPortId] - this.topology.portY[e48.toPortId];
return Math.sqrt(t2 * t2 + n2 * n2);
}
getPartialRipWindow(e48, t2, n2) {
let o2, i2 = Number.NEGATIVE_INFINITY;
for (let r3 = 0;r3 < e48.length; r3++) {
const s3 = e48[r3];
if (!t2.has(s3.regionId))
continue;
const a3 = n2[s3.regionId] ?? 0;
a3 > i2 && (i2 = a3, o2 = r3);
}
if (o2 === undefined)
return;
const r2 = Math.max(0, this.partialRipWindowDistance ?? this.PARTIAL_RIP_MAX_DISTANCE);
let s2 = o2, a2 = o2, c2 = this.getSegmentDistance(e48[o2]) / 2, l2 = c2;
for (;s2 > 0; ) {
const t3 = this.getSegmentDistance(e48[s2 - 1]);
if (c2 + t3 > r2)
break;
s2 -= 1, c2 += t3;
}
for (;a2 + 1 < e48.length; ) {
const t3 = this.getSegmentDistance(e48[a2 + 1]);
if (l2 + t3 > r2)
break;
a2 += 1, l2 += t3;
}
return { startIndex: s2, endIndex: a2 };
}
appendRetainedSegment(e48, t2, n2) {
e48[n2.regionId].push([t2, n2.fromPortId, n2.toPortId]);
}
preparePartialRip(e48, t2) {
if (!this.PARTIAL_RIP_ENABLED || e48.length === 0)
return false;
const n2 = new Set(e48);
if (this.partialRipWindowDistance === undefined) {
let n3 = 0;
for (const o4 of e48)
n3 = Math.max(n3, t2[o4] ?? 0);
const o3 = Math.max(0, this.PARTIAL_RIP_MAX_DISTANCE), i3 = Math.max(o3, this.PARTIAL_RIP_QUALITY_MAX_DISTANCE ?? 2 * o3);
this.partialRipWindowDistance = n3 <= 1.5 * this.RIP_THRESHOLD_END ? i3 : o3;
}
const o2 = new Set;
for (const t3 of e48)
for (const [e49] of this.state.regionSegments[t3] ?? [])
o2.add(e49);
if (o2.size === 0)
return false;
const i2 = this.getRouteIdsPreferredForPreservation(), r2 = [...o2].some((e49) => !i2.has(e49)), s2 = Array.from({ length: this.topology.regionCount }, () => []), a2 = new Map;
let c2 = 0, l2 = 0;
for (let e49 = 0;e49 < this.problem.routeCount; e49++) {
const h2 = this.getCommittedRouteSegments(e49);
if (!h2)
return false;
if (!o2.has(e49) || r2 && i2.has(e49)) {
for (const t3 of h2)
this.appendRetainedSegment(s2, e49, t3), l2 += 1;
continue;
}
const d2 = this.getPartialRipWindow(h2, n2, t2);
if (!d2)
return false;
for (let t3 = 0;t3 < h2.length; t3++) {
const n3 = h2[t3];
t3 >= d2.startIndex && t3 <= d2.endIndex ? c2 += 1 : (this.appendRetainedSegment(s2, e49, n3), l2 += 1);
}
const u2 = h2[d2.startIndex], p2 = h2[d2.endIndex];
a2.set(e49, { routeId: e49, activeStartPortId: u2.fromPortId, activeEndPortId: p2.toPortId, forcedStartRegionId: u2.regionId, forcedEndRegionId: p2.regionId, rippedSegmentCount: d2.endIndex - d2.startIndex + 1, retainedSegmentCount: h2.length - (d2.endIndex - d2.startIndex + 1) });
}
return a2.size !== 0 && c2 !== 0 && (this.partialRipRoutePlans = a2, this.rebuildRetainedRoutingState(s2, [...a2.keys()]), this.partialRipCount += 1, this.partiallyRippedRouteCount += a2.size, this.partiallyRippedSegmentCount += c2, this.retainedPartialRipSegmentCount += l2, this.publishPartialRipStats(), true);
}
rebuildRetainedRoutingState(e48, t2) {
this.state.portAssignment.fill(-1), this.state.regionSegments = Array.from({ length: this.topology.regionCount }, () => []), this.state.regionIntersectionCaches = Array.from({ length: this.topology.regionCount }, () => XZ()), this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.unroutedRoutes = t2, this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.state.goalPortId = -1, this.outsideInRouteSearch = undefined, this.oneSidedFallbackRouteId = undefined;
for (let t3 = 0;t3 < e48.length; t3++)
for (const [n2, o2, i2] of e48[t3] ?? []) {
const e49 = this.problem.routeNet[n2];
this.state.currentRouteNetId = e49;
for (const t4 of [o2, i2]) {
const n3 = this.state.portAssignment[t4];
if (n3 !== -1 && n3 !== e49)
throw new Error(`OutsideInPartialRipTinyHyperGraphSolver: retained port ${t4} belongs to multiple nets`);
this.state.portAssignment[t4] = e49;
}
this.state.regionSegments[t3].push([n2, o2, i2]), this.appendSegmentToRegionCache(t3, o2, i2);
}
this.state.currentRouteNetId = undefined;
}
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(e48, t2, n2) {
const o2 = new XU([], (e49, t3) => e49.f === t3.f ? e49.g - t3.g : e49.f - t3.f), i2 = this.topology.portX[e48] - this.topology.portX[n2], r2 = this.topology.portY[e48] - this.topology.portY[n2], s2 = Math.sqrt(i2 * i2 + r2 * r2) * this.DISTANCE_TO_COST, a2 = { portId: e48, nextRegionId: t2, f: s2, g: 0, h: s2, travelDistance: 0 };
return o2.queue(a2), { queue: o2, bestCostByHopId: new Map([[this.getHopId(e48, t2), 0]]), settledByPortId: new Map, settledByRegionId: new Map, targetPortId: n2 };
}
startOutsideInRouteSearch(e48) {
const t2 = this.getRouteStartPortId(e48), n2 = this.getRouteEndPortId(e48), o2 = this.getStartingNextRegionId(e48, t2), i2 = this.getEndingNextRegionId(e48, n2);
return o2 !== undefined && i2 !== undefined && (this.state.goalPortId = n2, this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.outsideInRouteSearch = { routeId: e48, forward: this.createOutsideInFrontier(t2, o2, n2), reverse: this.createOutsideInFrontier(n2, i2, t2), expandForwardNext: true, distanceLimitHit: false, bestJoinedCost: Number.POSITIVE_INFINITY }, this.outsideInRouteCount += 1, this.publishOutsideInStats(), true);
}
dequeueFreshCandidate(e48) {
for (;e48.queue.length > 0; ) {
const t2 = e48.queue.dequeue(), n2 = this.getHopId(t2.portId, t2.nextRegionId);
if (t2.g <= (e48.bestCostByHopId.get(n2) ?? 1 / 0))
return t2;
}
}
recordSettledCandidate(e48, t2) {
const n2 = e48.settledByPortId.get(t2.portId);
(!n2 || t2.g < n2.g) && e48.settledByPortId.set(t2.portId, t2);
const o2 = e48.settledByRegionId.get(t2.nextRegionId) ?? [];
o2.push(t2), o2.sort((e49, t3) => e49.g - t3.g), o2.length > 16 && (o2.length = 16), e48.settledByRegionId.set(t2.nextRegionId, o2);
}
getCandidatePath(e48) {
const t2 = [];
let n2 = e48;
for (;n2; )
t2.push(n2), n2 = n2.prevCandidate;
return t2.reverse(), t2;
}
buildJoinedCandidate(e48, t2) {
const n2 = this.getCandidatePath(e48), o2 = this.getCandidatePath(t2), i2 = n2.map(({ portId: e49 }) => e49), r2 = n2.slice(0, -1).map(({ nextRegionId: e49 }) => e49);
if (e48.portId !== t2.portId) {
if (e48.nextRegionId !== t2.nextRegionId)
return;
const n3 = this.topology.portX[e48.portId] - this.topology.portX[t2.portId], o3 = this.topology.portY[e48.portId] - this.topology.portY[t2.portId], s3 = Math.sqrt(n3 * n3 + o3 * o3);
if (e48.travelDistance + t2.travelDistance + s3 > 2 * this.OUTSIDE_IN_MAX_DISTANCE)
return;
const a3 = this.computeG(e48, t2.portId);
if (!Number.isFinite(a3))
return;
r2.push(e48.nextRegionId), i2.push(t2.portId);
}
for (let e49 = o2.length - 2;e49 >= 0; e49--) {
const t3 = o2[e49];
r2.push(t3.nextRegionId), i2.push(t3.portId);
}
if (new Set(i2).size !== i2.length || r2.length + 1 !== i2.length)
return;
let s2 = { portId: i2[0], nextRegionId: r2[0], f: 0, g: 0, h: 0 };
for (let e49 = 1;e49 < i2.length; e49++)
s2 = { portId: i2[e49], prevRegionId: r2[e49 - 1], nextRegionId: r2[e49] ?? r2[e49 - 1], prevCandidate: s2, f: 0, g: 0, h: 0 };
const a2 = e48.portId === t2.portId ? 0 : this.computeG(e48, t2.portId) - e48.g;
return { candidate: s2, cost: e48.g + t2.g + a2 };
}
considerOutsideInJoins(e48, t2) {
const n2 = this.outsideInRouteSearch, o2 = t2 ? n2.reverse : n2.forward, i2 = (e49) => {
!e49 || e49.cost >= n2.bestJoinedCost || (n2.bestJoinedCandidate = e49.candidate, n2.bestJoinedCost = e49.cost, n2.remainingPostMeetingExpansions = 24);
}, r2 = o2.settledByPortId.get(e48.portId);
r2 && i2(t2 ? this.buildJoinedCandidate(e48, r2) : this.buildJoinedCandidate(r2, e48));
for (const n3 of o2.settledByRegionId.get(e48.nextRegionId) ?? [])
i2(t2 ? this.buildJoinedCandidate(e48, n3) : this.buildJoinedCandidate(n3, e48));
}
commitBestOutsideInJoin() {
const e48 = this.outsideInRouteSearch?.bestJoinedCandidate;
return !!e48 && (this.onPathFound(e48), true);
}
expandOutsideInFrontier(e48) {
const t2 = this.outsideInRouteSearch, n2 = e48 ? t2.forward : t2.reverse, o2 = this.dequeueFreshCandidate(n2);
if (!o2)
return false;
if (e48 ? this.outsideInForwardExpansionCount += 1 : this.outsideInReverseExpansionCount += 1, this.isRegionReservedForDifferentNet(o2.nextRegionId))
return true;
this.recordSettledCandidate(n2, o2), this.considerOutsideInJoins(o2, e48);
for (const e49 of this.topology.regionIncidentPorts[o2.nextRegionId] ?? []) {
if (e49 === o2.portId)
continue;
if (this.isPortReservedForDifferentNet(e49))
continue;
const i2 = this.state.portAssignment[e49];
if (i2 !== -1 && i2 !== this.state.currentRouteNetId)
continue;
if (e49 !== n2.targetPortId && this.problem.portSectionMask[e49] === 0)
continue;
const r2 = this.topology.portX[o2.portId] - this.topology.portX[e49], s2 = this.topology.portY[o2.portId] - this.topology.portY[e49], a2 = Math.sqrt(r2 * r2 + s2 * s2), c2 = o2.travelDistance + a2;
if (c2 > this.OUTSIDE_IN_MAX_DISTANCE) {
t2.distanceLimitHit = true, this.outsideInDistancePruneCount += 1;
continue;
}
const l2 = this.topology.incidentPortRegion[e49]?.[0] === o2.nextRegionId ? this.topology.incidentPortRegion[e49]?.[1] : this.topology.incidentPortRegion[e49]?.[0];
if (l2 === undefined || this.isRegionReservedForDifferentNet(l2))
continue;
const h2 = this.getHopId(e49, l2), d2 = n2.bestCostByHopId.get(h2) ?? 1 / 0;
if (o2.g >= d2)
continue;
const u2 = this.computeG(o2, e49, d2, a2);
if (!Number.isFinite(u2) || u2 >= d2)
continue;
n2.bestCostByHopId.set(h2, u2);
const p2 = this.topology.portX[e49] - this.topology.portX[n2.targetPortId], m2 = this.topology.portY[e49] - this.topology.portY[n2.targetPortId], g2 = Math.sqrt(p2 * p2 + m2 * m2) * this.DISTANCE_TO_COST;
n2.queue.queue({ portId: e49, prevRegionId: o2.nextRegionId, nextRegionId: l2, prevCandidate: o2, f: u2 + g2, g: u2, h: g2, travelDistance: c2 });
}
return true;
}
fallBackToOneSidedRouteSearch() {
const e48 = this.state.currentRouteId;
e48 !== undefined && (this.outsideInRouteSearch = undefined, this.outsideInFallbackRouteCount += 1, this.oneSidedFallbackRouteId = e48, this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.goalPortId = -1, this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.state.unroutedRoutes.unshift(e48), this.publishOutsideInStats());
}
_step() {
if (!this.OUTSIDE_IN_ROUTING)
return void super._step();
const e48 = this.state.currentRouteId ?? this.state.unroutedRoutes[0];
if (e48 !== undefined && !this.partialRipRoutePlans.has(e48))
return void super._step();
if (this.oneSidedFallbackRouteId !== undefined)
return void super._step();
if (this.state.currentRouteId === undefined) {
if (this.state.unroutedRoutes.length === 0)
return void this.onAllRoutesRouted();
const e49 = this.state.unroutedRoutes.shift();
if (this.state.currentRouteId = e49, this.state.currentRouteNetId = this.problem.routeNet[e49], this.routeAttemptCountByRouteId[e49] += 1, !this.startOutsideInRouteSearch(e49))
return this.failed = true, void (this.error = `Route ${e49} has an endpoint without an incident region`);
}
const t2 = this.outsideInRouteSearch;
if (!t2)
return;
let n2 = this.expandOutsideInFrontier(t2.expandForwardNext);
if (this.state.currentRouteId !== undefined && (n2 || (n2 = this.expandOutsideInFrontier(!t2.expandForwardNext), this.state.currentRouteId !== undefined)))
if (t2.expandForwardNext = !t2.expandForwardNext, t2.bestJoinedCandidate && (t2.remainingPostMeetingExpansions = (t2.remainingPostMeetingExpansions ?? 1) - 1, (t2.remainingPostMeetingExpansions ?? 0) <= 0))
this.commitBestOutsideInJoin();
else {
if (!n2 && t2.forward.queue.length === 0 && t2.reverse.queue.length === 0) {
if (this.commitBestOutsideInJoin())
return;
this.outsideInRouteSearch = undefined, t2.distanceLimitHit ? this.fallBackToOneSidedRouteSearch() : this.onOutOfCandidates();
}
this.publishOutsideInStats();
}
}
shouldReplaceBestSolvedState(e48) {
const t2 = this.bestSolvedRoundSummary;
if (!t2)
return true;
if (!this.useComplexityAwareSelection)
return this.compareRegionCostSummaries(e48, t2) < 0;
const n2 = this.partialRipQualityBaselineSummary;
if (!n2)
return this.compareRegionCostSummaries(e48, t2) < 0;
const o2 = this.firstCompletedRoundSummary ?? n2, i2 = o2.maxRegionCost * (1 + Math.max(0, this.PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO)), r2 = o2.totalRegionCost * (1 + Math.max(0, this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO)), s2 = e48.maxRegionCost <= i2 && e48.totalRegionCost <= r2;
return s2 !== (t2.maxRegionCost <= i2 && t2.totalRegionCost <= r2) ? s2 : s2 && e48.segmentCount !== t2.segmentCount ? e48.segmentCount < t2.segmentCount : this.compareRegionCostSummaries(e48, t2) < 0;
}
onAllRoutesRouted() {
if (!this.PARTIAL_RIP_ENABLED)
return void super.onAllRoutesRouted();
const { state: e48, topology: t2 } = this, n2 = Math.min(this.RIP_THRESHOLD_RAMP_ATTEMPTS, this.PARTIAL_RIP_MAX_ATTEMPTS), o2 = Math.max(0, this.RIP_THRESHOLD_RAMP_ATTEMPTS), i2 = o2 <= 0 ? 1 : Math.min(1, e48.ripCount / o2), r2 = this.RIP_THRESHOLD_START + (this.RIP_THRESHOLD_END - this.RIP_THRESHOLD_START) * i2, s2 = new Float64Array(t2.regionCount), a2 = [];
let c2 = 0, l2 = 0, h2 = 0, d2 = 0, u2 = 0;
for (let n3 = 0;n3 < t2.regionCount; n3++) {
const t3 = e48.regionIntersectionCaches[n3]?.existingRegionCost ?? 0;
s2[n3] = t3, c2 = Math.max(c2, t3), l2 += t3;
const o3 = e48.regionSegments[n3]?.length ?? 0;
h2 += o3, d2 = Math.max(d2, o3), u2 += o3 * o3, t3 > r2 && a2.push(n3);
}
const p2 = { maxRegionCost: c2, totalRegionCost: l2 }, m2 = { ...p2, ripCount: e48.ripCount, segmentCount: h2, maxRegionSegmentCount: d2, squaredRegionSegmentCount: u2 };
this.completedRoundSummaries.push(m2), this.firstCompletedRoundSummary ??= m2, this.partialRipQualityBaselineSummary === undefined && e48.ripCount >= Math.max(0, this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS) && (this.partialRipQualityBaselineSummary = m2);
this.shouldReplaceBestSolvedState(m2) && (this.replaceBestSolvedState(p2), this.bestSolvedRoundSummary = m2);
const g2 = this.firstCompletedRoundSummary, f2 = this.partialRipQualityBaselineSummary ?? g2, _2 = Math.max(0, this.PARTIAL_RIP_TARGET_MAX_COST_IMPROVEMENT_RATIO), y2 = Math.max(0, this.PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO), b2 = f2.maxRegionCost * (1 - _2), x2 = f2.totalRegionCost * (1 + y2), v2 = this.useComplexityAwareSelection && e48.ripCount > f2.ripCount && _2 > 0 && c2 <= b2 && l2 <= x2 && h2 <= f2.segmentCount;
if (v2 && (this.partialRipTargetReached = true), this.stats = { ...this.stats, currentRipThreshold: r2, hotRegionCount: a2.length, maxRegionCost: c2, totalRegionCost: l2, bestMaxRegionCost: this.bestSolvedStateSummary?.maxRegionCost, bestTotalRegionCost: this.bestSolvedStateSummary?.totalRegionCost, ripCount: e48.ripCount, completedRoundSummaries: this.completedRoundSummaries.map((e49) => ({ ...e49 })), firstMaxRegionCost: g2.maxRegionCost, firstTotalRegionCost: g2.totalRegionCost, firstSegmentCount: g2.segmentCount, firstMaxRegionSegmentCount: g2.maxRegionSegmentCount, firstSquaredRegionSegmentCount: g2.squaredRegionSegmentCount, partialRipQualityBaselineRipCount: f2.ripCount, partialRipQualityBaselineMaxRegionCost: f2.maxRegionCost, partialRipQualityBaselineTotalRegionCost: f2.totalRegionCost, partialRipQualityBaselineSegmentCount: f2.segmentCount, partialRipQualityBaselineMaxRegionSegmentCount: f2.maxRegionSegmentCount, partialRipQualityBaselineSquaredRegionSegmentCount: f2.squaredRegionSegmentCount, bestSolvedSegmentCount: this.bestSolvedRoundSummary?.segmentCount, bestSolvedMaxRegionSegmentCount: this.bestSolvedRoundSummary?.maxRegionSegmentCount, bestSolvedSquaredRegionSegmentCount: this.bestSolvedRoundSummary?.squaredRegionSegmentCount, partialRipTargetMaxRegionCost: b2, partialRipMaxTargetTotalRegionCost: x2, 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(), a2.length === 0 || v2 || e48.ripCount >= n2)
return this.restoreBestSolvedState(), void (this.solved = true);
for (let n3 = 0;n3 < t2.regionCount; n3++)
e48.regionCongestionCost[n3] += s2[n3] * this.RIP_CONGESTION_REGION_COST_FACTOR;
const I2 = e48.ripCount < Math.max(0, this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS);
e48.ripCount += 1;
const S2 = !I2 && this.preparePartialRip(a2, s2);
S2 || this.resetRoutingStateForRerip();
const C2 = I2 ? "warmup_full" : S2 ? "partial" : "full_fallback";
this.stats = { ...this.stats, ripCount: e48.ripCount, maxRegionCostBeforeRip: c2, reripRegionCount: a2.length, reripMode: C2, partialRipWarmupFullRipAttempts: this.PARTIAL_RIP_WARMUP_FULL_RIP_ATTEMPTS }, this.logRipEvent("hot_regions", c2, { hotRegionCount: a2.length, currentRipThreshold: r2, reripMode: C2, partialRouteCount: S2 ? this.partialRipRoutePlans.size : 0 });
}
};
var tq = (e48) => {
const t2 = typeof e48.d?.netId == "number" ? e48.d.netId : typeof e48.d?.NetId == "number" ? e48.d.NetId : undefined;
return Number.isFinite(t2) ? t2 : undefined;
};
var nq = (e48) => {
const t2 = new Set;
for (const n3 of e48.connections ?? [])
t2.add(n3.startRegionId), t2.add(n3.endRegionId);
const n2 = new Set(e48.regions.filter((e49) => ((e50) => {
if (e50.d?._containsObstacle !== true)
return false;
const t3 = tq(e50);
return t3 === undefined || t3 === -1;
})(e49) && !t2.has(e49.regionId)).map((e49) => e49.regionId));
if (n2.size === 0)
return e48;
const o2 = e48.ports.filter((e49) => !n2.has(e49.region1Id) && !n2.has(e49.region2Id)), i2 = (e48.connections ?? []).find((e49) => n2.has(e49.startRegionId) || n2.has(e49.endRegionId));
if (i2)
throw new Error(`Connection "${i2.connectionId}" references full-obstacle region`);
return { ...e48, regions: e48.regions.filter((e49) => !n2.has(e49.regionId)), ports: o2 };
};
var oq = (e48) => {
const t2 = e48.d?.bounds;
if (t2)
return t2;
const n2 = e48.d?.center, o2 = e48.d?.width, i2 = e48.d?.height;
return n2 && typeof n2.x == "number" && typeof n2.y == "number" && typeof o2 == "number" && typeof i2 == "number" ? { minX: n2.x - o2 / 2, maxX: n2.x + o2 / 2, minY: n2.y - i2 / 2, maxY: n2.y + i2 / 2 } : { minX: 0, maxX: 0, minY: 0, maxY: 0 };
};
var iq = (e48) => Number(e48.d?.x ?? 0);
var rq = (e48) => Number(e48.d?.y ?? 0);
var sq = (e48, t2) => {
if (!t2)
return 0;
const n2 = oq(t2), o2 = iq(e48), i2 = rq(e48), r2 = n2.minX <= o2 && o2 <= n2.maxX, s2 = n2.minY <= i2 && i2 <= n2.maxY;
if (s2 && o2 >= n2.maxX) {
const e49 = Math.max(n2.maxY - n2.minY, 0.000000001), t3 = (i2 - n2.minY) / e49;
return Math.round(9000 * t3);
}
if (r2 && i2 >= n2.maxY) {
const e49 = Math.max(n2.maxX - n2.minX, 0.000000001), t3 = (n2.maxX - o2) / e49;
return 9000 + Math.round(9000 * t3);
}
if (s2 && o2 <= n2.minX) {
const e49 = Math.max(n2.maxY - n2.minY, 0.000000001), t3 = (n2.maxY - i2) / e49;
return 18000 + Math.round(9000 * t3);
}
if (r2 && i2 <= n2.minY) {
const e49 = Math.max(n2.maxX - n2.minX, 0.000000001), t3 = (o2 - n2.minX) / e49;
return 27000 + Math.round(9000 * t3);
}
const a2 = Math.abs(o2 - n2.minX), c2 = Math.abs(o2 - n2.maxX), l2 = Math.abs(i2 - n2.minY), h2 = Math.abs(i2 - n2.maxY), d2 = Math.min(a2, c2, l2, h2), u2 = Math.max(n2.maxX - n2.minX, 0.000000001), p2 = Math.max(n2.maxY - n2.minY, 0.000000001);
if (d2 === c2) {
const e49 = (i2 - n2.minY) / p2;
return Math.round(9000 * e49);
}
if (d2 === h2) {
const e49 = (n2.maxX - o2) / u2;
return 9000 + Math.round(9000 * e49);
}
if (d2 === a2) {
const e49 = (n2.maxY - i2) / p2;
return 18000 + Math.round(9000 * e49);
}
const m2 = (o2 - n2.minX) / u2;
return 27000 + Math.round(9000 * m2);
};
var aq = (e48, t2) => {
if (!e48)
return;
return [...e48.pointIds].sort((e49, n2) => {
const o2 = t2.get(e49), i2 = t2.get(n2), r2 = Number(o2?.d?.distToCentermostPortOnZ ?? Number.POSITIVE_INFINITY), s2 = Number(i2?.d?.distToCentermostPortOnZ ?? Number.POSITIVE_INFINITY);
if (r2 !== s2)
return r2 - s2;
const a2 = Number(o2?.d?.z ?? 0), c2 = Number(i2?.d?.z ?? 0);
return a2 !== c2 ? a2 - c2 : e49.localeCompare(n2);
})[0];
};
var cq = (e48) => {
const t2 = nq(e48), n2 = new Map, o2 = new Map, i2 = new Map, r2 = new Map((t2.solvedRoutes ?? []).map((e49) => [e49.connection.connectionId, e49]));
t2.regions.forEach((e49, t3) => {
n2.set(e49.regionId, t3);
}), t2.ports.forEach((e49, t3) => {
o2.set(e49.portId, t3), i2.set(e49.portId, e49);
});
const s2 = t2.regions.length, a2 = t2.ports.length, c2 = t2.regions.map((e49) => e49.pointIds.map((e50) => o2.get(e50)).filter((e50) => e50 !== undefined)), l2 = Array.from({ length: a2 }, () => []), h2 = new Float64Array(s2), d2 = new Float64Array(s2), u2 = new Float64Array(s2), p2 = new Float64Array(s2), m2 = new Int32Array(s2), g2 = new Int32Array(s2).fill(-1), f2 = new Int8Array(s2);
t2.regions.forEach((e49, t3) => {
const n3 = ((e50) => {
const t4 = oq(e50), n4 = typeof e50.d?.width == "number" ? e50.d.width : t4.maxX - t4.minX, o4 = typeof e50.d?.height == "number" ? e50.d.height : t4.maxY - t4.minY;
return { centerX: typeof e50.d?.center?.x == "number" ? e50.d.center.x : (t4.minX + t4.maxX) / 2, centerY: typeof e50.d?.center?.y == "number" ? e50.d.center.y : (t4.minY + t4.maxY) / 2, width: n4, height: o4 };
})(e49);
h2[t3] = n3.width, d2[t3] = n3.height, u2[t3] = n3.centerX, p2[t3] = n3.centerY, m2[t3] = ((e50) => {
const t4 = e50.d?.availableZ;
if (!Array.isArray(t4))
return 0;
let n4 = 0;
for (const e51 of t4)
!Number.isInteger(e51) || e51 < 0 || e51 >= 31 || (n4 |= 1 << e51);
return n4;
})(e49);
const o3 = tq(e49);
o3 !== undefined && (g2[t3] = o3, f2[t3] = 1);
});
const _2 = new Int32Array(a2), y2 = new Int32Array(a2), b2 = new Float64Array(a2), x2 = new Float64Array(a2), v2 = new Int32Array(a2);
t2.ports.forEach((e49, o3) => {
const i3 = n2.get(e49.region1Id), r3 = n2.get(e49.region2Id);
if (i3 === undefined || r3 === undefined)
throw new Error(`Port "${e49.portId}" references missing regions "${e49.region1Id}" or "${e49.region2Id}"`);
l2[o3] = [i3, r3], b2[o3] = iq(e49), x2[o3] = rq(e49), v2[o3] = ((e50) => {
const t3 = Number(e50.d?.z ?? 0);
return Number.isFinite(t3) ? t3 : 0;
})(e49), _2[o3] = sq(e49, t2.regions[i3]), y2[o3] = sq(e49, t2.regions[r3]);
});
const I2 = t2.regions.map((e49, t3) => ((e50, t4) => {
const n3 = e50.d && typeof e50.d == "object" && !Array.isArray(e50.d) ? { ...e50.d } : { value: e50.d };
return n3.layer = t4, Object.defineProperty(n3, "serializedRegionId", { value: e50.regionId, enumerable: false, configurable: true, writable: true }), n3;
})(e49, ((e50) => CU(PU(m2[e50])) ?? CU((c2[e50] ?? []).map((e51) => v2[e51])) ?? "z0")(t3))), S2 = t2.ports.map((e49, t3) => ((e50, t4) => {
const n3 = e50.d && typeof e50.d == "object" && !Array.isArray(e50.d) ? { ...e50.d } : { value: e50.d };
return n3.layer = t4, Object.defineProperty(n3, "serializedPortId", { value: e50.portId, enumerable: false, configurable: true, writable: true }), n3;
})(e49, CU([v2[t3]]) ?? "z0")), C2 = t2.connections ?? [], P2 = new Map;
let M2 = 0;
const w2 = (e49) => {
const t3 = e49.mutuallyConnectedNetworkId ?? e49.connectionId;
let n3 = P2.get(t3);
return n3 === undefined && (n3 = M2++, P2.set(t3, n3)), n3;
}, N2 = Array.from({ length: s2 }, () => new Set), T2 = (e49, t3) => {
const o3 = n2.get(e49);
if (o3 === undefined)
throw new Error(`Connection references missing region "${e49}"`);
N2[o3].add(t3);
};
C2.forEach((e49) => {
const t3 = w2(e49);
T2(e49.startRegionId, t3), T2(e49.endRegionId, t3);
}), N2.forEach((e49, t3) => {
f2[t3] !== 1 && e49.size === 1 && (g2[t3] = [...e49][0]);
});
const R2 = C2.map((e49) => {
const n3 = r2.get(e49.connectionId), o3 = ((e50, t3) => e50.ports.filter((e51) => e51.region1Id === t3.startRegionId && e51.region2Id === t3.endRegionId || e51.region2Id === t3.startRegionId && e51.region1Id === t3.endRegionId).map((e51) => e51.portId))(t2, e49);
return { connection: e49, solvedRoute: n3, sharedPortIds: o3 };
}).filter(({ solvedRoute: e49, sharedPortIds: t3 }) => t3.length === 0 || (e49?.path.length ?? 0) > 1), E2 = R2.length, A2 = new Map(R2.map(({ connection: e49 }, t3) => [e49.connectionId, t3])), O2 = new Int8Array(a2).fill(1), k2 = new Int32Array(E2), D2 = new Int32Array(E2), L2 = new Int32Array(E2);
R2.forEach(({ connection: e49, solvedRoute: n3 }, r3) => {
const s3 = aq(t2.regions.find((t3) => t3.regionId === e49.startRegionId), i2), a3 = aq(t2.regions.find((t3) => t3.regionId === e49.endRegionId), i2), c3 = n3?.path[0]?.portId ?? s3, l3 = n3?.path[n3.path.length - 1]?.portId ?? a3, h3 = c3 !== undefined ? o2.get(c3) : undefined, d3 = l3 !== undefined ? o2.get(l3) : undefined;
if (h3 === undefined || d3 === undefined)
throw new Error(`Connection "${e49.connectionId}" could not be mapped to route endpoints`);
k2[r3] = h3, D2[r3] = d3, L2[r3] = w2(e49);
});
const z2 = { portCount: a2, regionCount: s2, regionIncidentPorts: c2, incidentPortRegion: l2, regionWidth: h2, regionHeight: d2, regionCenterX: u2, regionCenterY: p2, regionAvailableZMask: m2, regionMetadata: I2, portAngleForRegion1: _2, portAngleForRegion2: y2, portX: b2, portY: x2, portZ: v2, portMetadata: S2 }, B2 = t2.regions.flatMap((e49, t3) => (e49.assignments ?? []).map((n3) => {
const i3 = A2.get(n3.connectionId);
if (i3 === undefined)
throw new Error(`Region "${e49.regionId}" assignment references unknown routable connection "${n3.connectionId}"`);
const r3 = o2.get(n3.regionPort1Id), s3 = o2.get(n3.regionPort2Id);
if (r3 === undefined || s3 === undefined)
throw new Error(`Region "${e49.regionId}" assignment references missing port "${r3 === undefined ? n3.regionPort1Id : n3.regionPort2Id}"`);
if (!c2[t3]?.includes(r3) || !c2[t3]?.includes(s3))
throw new Error(`Region "${e49.regionId}" assignment ports must both belong to the region`);
return { routeId: i3, regionId: t3, fromPortId: r3, toPortId: s3 };
})), F2 = Float64Array.from(t2.ports, (e49) => {
const t3 = Number(e49.d?.tinyHypergraphPortPenalty ?? 0);
return Number.isFinite(t3) && t3 > 0 ? t3 : 0;
}), j2 = F2.some((e49) => e49 > 0), $2 = { routeCount: E2, portSectionMask: O2, routeMetadata: R2.map(({ connection: e49 }) => e49), routeStartPort: k2, routeEndPort: D2, routeNet: L2, regionNetId: g2, ...B2.length > 0 && { initialAssignments: B2 }, ...j2 && { portPenalty: F2 } }, Y = [], X2 = [];
for (const { solvedRoute: e49 } of R2) {
if (!e49) {
Y.push([]), X2.push([]);
continue;
}
const t3 = [], i3 = [];
for (let r3 = 1;r3 < e49.path.length; r3++) {
const s3 = e49.path[r3 - 1], a3 = e49.path[r3], c3 = s3?.portId, l3 = a3?.portId, h3 = c3 !== undefined ? o2.get(c3) : undefined, d3 = l3 !== undefined ? o2.get(l3) : undefined;
if (h3 === undefined || d3 === undefined)
continue;
const u3 = typeof s3?.nextRegionId == "string" ? s3.nextRegionId : typeof a3?.lastRegionId == "string" ? a3.lastRegionId : undefined;
t3.push([h3, d3]), i3.push(u3 !== undefined ? n2.get(u3) : undefined);
}
Y.push(t3), X2.push(i3);
}
return { topology: z2, problem: $2, solution: { solvedRoutePathSegments: Y, solvedRoutePathRegionIds: X2 } };
};
var lq = (e48) => typeof e48 == "object" && e48 !== null;
var hq = (e48) => Array.isArray(e48) ? e48.map((e49) => hq(e49)) : lq(e48) ? Object.fromEntries(Object.entries(e48).map(([e49, t2]) => [e49, hq(t2)])) : e48;
var dq = (e48) => lq(e48) ? { ...e48 } : e48 === undefined ? {} : { value: e48 };
var uq = (e48, t2 = 0) => typeof e48 == "number" && Number.isFinite(e48) ? e48 : t2;
var pq = (e48) => ({ x: uq(e48.d?.x), y: uq(e48.d?.y) });
var mq = (e48) => [e48.region1Id, e48.region2Id].sort().join("\x00");
var gq = (e48, t2) => Math.hypot(e48.x - t2.x, e48.y - t2.y);
var fq = (e48) => {
const t2 = Math.hypot(e48.x, e48.y);
if (!(t2 <= 0.000000001))
return { x: e48.x / t2, y: e48.y / t2 };
};
var _q = (e48) => {
const t2 = e48?.d?.center;
if (lq(t2))
return { x: uq(t2.x), y: uq(t2.y) };
const n2 = ((e49) => {
const t3 = e49?.d?.bounds;
if (lq(t3) && typeof t3.minX == "number" && typeof t3.maxX == "number" && typeof t3.minY == "number" && typeof t3.maxY == "number")
return { minX: t3.minX, maxX: t3.maxX, minY: t3.minY, maxY: t3.maxY };
const n3 = e49?.d?.center, o2 = uq(e49?.d?.width), i2 = uq(e49?.d?.height);
if (lq(n3)) {
const e50 = uq(n3.x), t4 = uq(n3.y);
return { minX: e50 - o2 / 2, maxX: e50 + o2 / 2, minY: t4 - i2 / 2, maxY: t4 + i2 / 2 };
}
return { minX: 0, maxX: 0, minY: 0, maxY: 0 };
})(e48);
return { x: (n2.minX + n2.maxX) / 2, y: (n2.minY + n2.maxY) / 2 };
};
var yq = (e48, t2) => {
const n2 = pq(e48);
let o2, i2 = Number.POSITIVE_INFINITY;
for (const r2 of t2) {
if (r2.portId === e48.portId)
continue;
const t3 = gq(n2, pq(r2));
t3 <= 0.000000001 || t3 >= i2 || (o2 = r2, i2 = t3);
}
return o2;
};
var bq = (e48, t2, n2) => {
const o2 = pq(e48);
if (t2) {
const e49 = pq(t2), n3 = fq({ x: o2.x - e49.x, y: o2.y - e49.y });
if (n3)
return n3;
}
return ((e49, t3) => {
const n3 = _q(t3.get(e49.region1Id)), o3 = _q(t3.get(e49.region2Id));
return fq({ x: -(o3.y - n3.y), y: o3.x - n3.x }) ?? { x: 1, y: 0 };
})(e48, n2);
};
var xq = (e48, t2, n2) => {
const o2 = `${e48}::dup${t2}`;
if (!n2.has(o2))
return n2.add(o2), o2;
for (let e49 = 2;; e49++) {
const t3 = `${o2}-${e49}`;
if (!n2.has(t3))
return n2.add(t3), t3;
}
};
var vq = (e48, t2, n2) => {
const o2 = e48.indexOf(t2);
o2 !== -1 ? e48.splice(o2 + 1, 0, ...n2) : e48.push(...n2);
};
var Iq = (e48, t2) => {
const n2 = e48.portMetadata?.[t2];
if (lq(n2)) {
if (typeof n2.serializedPortId == "string")
return n2.serializedPortId;
if (typeof n2.portId == "string")
return n2.portId;
}
return `port-${t2}`;
};
var Sq = (e48, t2) => ({ routeCount: 1, portSectionMask: e48.portSectionMask, routeMetadata: e48.routeMetadata === undefined ? undefined : [e48.routeMetadata[t2]], routeStartPort: Int32Array.from([e48.routeStartPort[t2]]), routeEndPort: Int32Array.from([e48.routeEndPort[t2]]), routeNet: Int32Array.from([e48.routeNet[t2]]), regionNetId: e48.regionNetId, portPenalty: e48.portPenalty });
var Cq = (e48) => {
const t2 = new Set;
for (const n2 of e48.state.regionSegments)
for (const [, e49, o2] of n2)
t2.add(e49), t2.add(o2);
return t2.size === 0 && e48.problem.routeCount === 1 && (t2.add(e48.problem.routeStartPort[0]), t2.add(e48.problem.routeEndPort[0])), t2;
};
var Pq = class extends De {
constructor(e48, t2 = {}) {
super(), this.serializedHyperGraph = e48, this.options = t2;
}
serializedHyperGraph;
options;
revisedSerializedHyperGraph;
report = { portUseCounts: {}, duplicatedPorts: [] };
getDuplicatePortProximity() {
return this.options.duplicatePortProximity ?? 0.05;
}
getIndividualRouteSolveOptions() {
return { RIP_THRESHOLD_RAMP_ATTEMPTS: 0, STATIC_REACHABILITY_PRECHECK: false, ...this.options.routeSolveOptions };
}
getPortUseCounts() {
const { topology: e48, problem: t2 } = cq(this.serializedHyperGraph);
this.options.useSerializedPortPenalties === false && (t2.portPenalty = undefined);
const n2 = new Map;
let o2;
for (let i2 = 0;i2 < t2.routeCount; i2++) {
const r2 = Sq(t2, i2);
if (o2 ? o2.resetForProblem(r2) : o2 = new ZZ(e48, r2, this.getIndividualRouteSolveOptions()), o2.solve(), !o2.solved || o2.failed)
throw new Error(`Route ${i2} could not be solved independently: ${o2.error ?? "unknown error"}`);
for (const t3 of Cq(o2)) {
const o3 = Iq(e48, t3);
n2.set(o3, (n2.get(o3) ?? 0) + 1);
}
}
return n2;
}
duplicateCongestedPorts(e48) {
const t2 = this.getDuplicatePortProximity();
if (!(t2 > 0))
throw new Error("duplicatePortProximity must be greater than zero");
const { solvedRoutes: n2, ...o2 } = this.serializedHyperGraph, i2 = this.serializedHyperGraph.regions.map((e49) => ({ ...e49, pointIds: [...e49.pointIds], d: hq(e49.d) })), r2 = this.serializedHyperGraph.ports.map((e49) => ({ ...e49, d: hq(e49.d) })), s2 = new Map(i2.map((e49) => [e49.regionId, e49])), a2 = new Map(r2.map((e49) => [e49.portId, e49])), c2 = ((e49) => {
const t3 = new Map;
for (const n3 of e49) {
const e50 = mq(n3), o3 = t3.get(e50);
o3 ? o3.push(n3) : t3.set(e50, [n3]);
}
return t3;
})(this.serializedHyperGraph.ports), l2 = new Set(r2.map((e49) => e49.portId)), h2 = [];
for (const [n3, o3] of [...e48.entries()].sort(([e49], [t3]) => e49.localeCompare(t3))) {
if (o3 <= 1)
continue;
const e49 = a2.get(n3);
if (!e49)
continue;
const i3 = o3 - 1, d2 = c2.get(mq(e49));
if (!d2)
throw new Error(`No boundary ports found for "${n3}"`);
const u2 = yq(e49, d2), p2 = bq(e49, u2, s2), m2 = pq(e49), g2 = [];
for (let s3 = 1;s3 <= i3; s3++) {
const a3 = xq(n3, s3, l2), c3 = t2 * s3 / (i3 + 1), h3 = dq(hq(e49.d));
h3.x = m2.x + p2.x * c3, h3.y = m2.y + p2.y * c3, h3.duplicatedFromPortId = n3, h3.duplicateIndex = s3, h3.duplicatePortUseCount = o3, h3.duplicatePortProximity = t2, h3.repairReason = "congested-port", r2.push({ ...e49, portId: a3, d: h3 }), g2.push(a3);
}
for (const t3 of [e49.region1Id, e49.region2Id]) {
const e50 = s2.get(t3);
e50 && vq(e50.pointIds, n3, g2);
}
h2.push({ sourcePortId: n3, duplicatePortIds: g2, useCount: o3 });
}
return this.report = { portUseCounts: Object.fromEntries([...e48.entries()].sort()), duplicatedPorts: h2 }, { ...o2, regions: i2, ports: r2, connections: this.serializedHyperGraph.connections === undefined ? undefined : hq(this.serializedHyperGraph.connections) };
}
_setup() {
try {
const e48 = this.getPortUseCounts();
this.revisedSerializedHyperGraph = this.duplicateCongestedPorts(e48), this.stats = { ...this.stats, duplicateSourcePortCount: this.report.duplicatedPorts.length, duplicatedPortCount: this.report.duplicatedPorts.reduce((e49, t2) => e49 + t2.duplicatePortIds.length, 0) }, this.solved = true;
} catch (e48) {
this.failed = true, this.error = e48 instanceof Error ? e48.message : String(e48);
}
}
_step() {
this.failed || (this.solved = true);
}
getOutput() {
if (!this.revisedSerializedHyperGraph || this.failed)
throw new Error("DuplicateCongestedPortSolver does not have a repaired topology output");
return this.revisedSerializedHyperGraph;
}
};
var Mq = (e48, t2) => {
const n2 = e48.owners.size - t2.owners.size;
if (n2 !== 0)
return n2;
const o2 = e48.distance - t2.distance;
return o2 !== 0 ? o2 : e48.queueOrder - t2.queueOrder;
};
var wq = class {
heap = [];
push(e48) {
this.heap.push(e48);
let t2 = this.heap.length - 1;
for (;t2 > 0; ) {
const e49 = Math.floor((t2 - 1) / 2);
if (Mq(this.heap[e49], this.heap[t2]) <= 0)
break;
[this.heap[e49], this.heap[t2]] = [this.heap[t2], this.heap[e49]], t2 = e49;
}
}
pop() {
const e48 = this.heap[0], t2 = this.heap.pop();
if (!e48 || !t2)
return null;
if (this.heap.length === 0)
return e48;
this.heap[0] = t2;
let n2 = 0;
for (;; ) {
const e49 = 2 * n2 + 1, t3 = e49 + 1;
let o2 = n2;
if (e49 < this.heap.length && Mq(this.heap[e49], this.heap[o2]) < 0 && (o2 = e49), t3 < this.heap.length && Mq(this.heap[t3], this.heap[o2]) < 0 && (o2 = t3), o2 === n2)
break;
[this.heap[n2], this.heap[o2]] = [this.heap[o2], this.heap[n2]], n2 = o2;
}
return e48;
}
};
var Nq = (e48, t2, n2) => {
if (e48 === t2)
return true;
if (e48.size > t2.size + n2.length)
return false;
for (const o2 of e48)
if (!t2.has(o2) && !n2.includes(o2))
return false;
return true;
};
var Tq = (e48, t2) => !(e48.distance > t2.distance) && ((e49, t3) => {
if (e49.size > t3.size)
return false;
for (const n2 of e49)
if (!t3.has(n2))
return false;
return true;
})(e48.owners, t2.owners);
var Rq = (e48, t2) => {
const n2 = [], o2 = [];
let i2 = e48;
for (;i2 !== null; )
n2.push(i2.state), i2.incomingHop !== null && o2.push(i2.incomingHop), i2 = i2.parent;
return n2.reverse(), o2.reverse(), { found: true, states: n2, hops: o2, owners: new Set(e48.owners), distance: e48.distance, expandedLabelCount: t2 };
};
var Eq = (e48) => {
for (;; ) {
const t2 = e48.pop();
if (t2 === null)
return null;
if (t2.active)
return t2;
}
};
var Aq = (e48, t2) => {
HZ(e48, t2), t2 && (t2.MAX_RIPS !== undefined && (e48.MAX_RIPS = t2.MAX_RIPS), t2.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT !== undefined && (e48.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT = t2.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT), t2.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST !== undefined && (e48.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST = t2.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST));
};
var Oq = (e48) => e48.map((e49) => e49.map(([e50, t2, n2]) => [e50, t2, n2]));
var kq = (e48) => ({ netIds: new Int32Array(e48.netIds), lesserAngles: new Int32Array(e48.lesserAngles), greaterAngles: new Int32Array(e48.greaterAngles), layerMasks: new Int32Array(e48.layerMasks), existingCrossingLayerIntersections: e48.existingCrossingLayerIntersections, existingSameLayerIntersections: e48.existingSameLayerIntersections, existingEntryExitLayerChanges: e48.existingEntryExitLayerChanges, existingRegionCost: e48.existingRegionCost, existingSegmentCount: e48.existingSegmentCount });
var Dq = (e48) => ({ portAssignment: new Int32Array(e48.portAssignment), regionSegments: Oq(e48.regionSegments), regionIntersectionCaches: e48.regionIntersectionCaches.map(kq) });
var Lq = (e48, t2) => {
const n2 = Dq(t2);
e48.state.portAssignment = n2.portAssignment, e48.state.regionSegments = n2.regionSegments, e48.state.regionIntersectionCaches = n2.regionIntersectionCaches;
};
var zq = (e48) => {
let t2 = 0, n2 = 0;
for (let o2 = 0;o2 < e48.length; o2++) {
const i2 = e48[o2]?.existingRegionCost ?? 0;
t2 = Math.max(t2, i2), n2 += i2;
}
return { maxRegionCost: t2, totalRegionCost: n2 };
};
var Bq = (e48, t2) => e48.maxRegionCost !== t2.maxRegionCost ? e48.maxRegionCost - t2.maxRegionCost : e48.totalRegionCost - t2.totalRegionCost;
var Fq = (e48, t2, n2) => {
const o2 = e48.incidentPortRegion[t2] ?? [], i2 = e48.incidentPortRegion[n2] ?? [], r2 = o2.find((e49) => i2.includes(e49));
if (r2 === undefined)
throw new Error(`Ports ${t2} and ${n2} do not share a region`);
return r2;
};
var jq = (e48, t2, n2, o2) => {
const i2 = n2.solvedRoutePathSegments[o2] ?? [], r2 = n2.solvedRoutePathRegionIds?.[o2] ?? [], s2 = t2.routeStartPort[o2], a2 = t2.routeEndPort[o2];
if (i2.length === 0) {
if (s2 === a2)
return { orderedPortIds: [s2], orderedRegionIds: [] };
throw new Error(`Route ${o2} does not have an existing solved path`);
}
const c2 = new Map;
i2.forEach(([e49, t3], n3) => {
const o3 = { segmentIndex: n3, fromPortId: e49, toPortId: t3, regionId: r2[n3] }, i3 = c2.get(e49) ?? [];
i3.push(o3), c2.set(e49, i3);
const s3 = c2.get(t3) ?? [];
s3.push(o3), c2.set(t3, s3);
});
const l2 = [s2], h2 = [], d2 = new Set;
let u2, p2 = s2;
for (;p2 !== a2 || d2.size < i2.length; ) {
const t3 = (c2.get(p2) ?? []).filter(({ segmentIndex: e49, fromPortId: t4, toPortId: n4 }) => {
if (d2.has(e49))
return false;
const o3 = t4 === p2 ? n4 : t4, r4 = o3 === a2 && d2.size + 1 === i2.length;
return o3 !== u2 || r4;
}), n3 = p2 === a2 && d2.size === 0 && t3.length === 2 || t3.length === 1 ? t3[0] : undefined;
if (!n3)
throw new Error(`Route ${o2} is not a single ordered path from ${s2} to ${a2}`);
const r3 = n3.fromPortId === p2 ? n3.toPortId : n3.fromPortId;
d2.add(n3.segmentIndex), h2.push(n3.regionId ?? Fq(e48, n3.fromPortId, n3.toPortId)), l2.push(r3), u2 = p2, p2 = r3;
}
if (d2.size !== i2.length)
throw new Error(`Route ${o2} contains disconnected solved segments`);
return { orderedPortIds: l2, orderedRegionIds: h2 };
};
var $q = (e48, t2, n2, o2) => {
const i2 = new ZZ(e48, t2, o2);
return ((e49, t3) => {
e49.state.portAssignment.fill(-1), e49.state.regionSegments = Array.from({ length: e49.topology.regionCount }, () => []), e49.state.regionIntersectionCaches = Array.from({ length: e49.topology.regionCount }, () => XZ()), e49.state.currentRouteId = undefined, e49.state.currentRouteNetId = undefined, e49.state.unroutedRoutes = [], e49.state.candidateQueue.clear(), e49.resetCandidateBestCosts(), e49.state.goalPortId = -1, e49.state.ripCount = 0, e49.state.regionCongestionCost.fill(0);
for (let n3 = 0;n3 < t3.length; n3++)
for (const [o3, i3, r2] of t3[n3] ?? [])
e49.state.currentRouteNetId = e49.problem.routeNet[o3], e49.state.regionSegments[n3].push([o3, i3, r2]), e49.state.portAssignment[i3] = e49.state.currentRouteNetId, e49.state.portAssignment[r2] = e49.state.currentRouteNetId, e49.appendSegmentToRegionCache(n3, i3, r2);
e49.state.currentRouteId = undefined, e49.state.currentRouteNetId = undefined, e49.solved = true, e49.failed = false, e49.error = null;
})(i2, n2), i2;
};
var Yq = (e48, t2, n2) => {
const o2 = new Int32Array(t2.routeStartPort), i2 = new Int32Array(t2.routeEndPort), r2 = Array.from({ length: t2.routeCount }, (e49, t3) => ({ routeId: t3, fixedSegments: [] })), s2 = [];
for (let a2 = 0;a2 < t2.routeCount; a2++) {
const c2 = r2[a2], { orderedPortIds: l2, orderedRegionIds: h2 } = jq(e48, t2, n2, a2), d2 = [];
let u2;
for (let e49 = 0;e49 < l2.length; e49++) {
const n3 = l2[e49], o3 = t2.portSectionMask[n3] === 1;
o3 && u2 === undefined ? u2 = e49 : o3 || u2 === undefined || (d2.push({ startIndex: u2, endIndex: e49 - 1 }), u2 = undefined);
}
if (u2 !== undefined && d2.push({ startIndex: u2, endIndex: l2.length - 1 }), d2.length === 0) {
for (let e49 = 1;e49 < l2.length; e49++)
c2.fixedSegments.push({ regionId: h2[e49 - 1], fromPortId: l2[e49 - 1], toPortId: l2[e49] });
continue;
}
if (d2.length > 1)
throw new Error(`Route ${a2} enters the section multiple times; only one contiguous section span is currently supported`);
const p2 = d2[0], m2 = Math.max(0, p2.startIndex - 1), g2 = Math.min(l2.length - 1, p2.endIndex + 1);
if (g2 <= m2)
throw new Error(`Route ${a2} does not have a valid section span`);
for (let e49 = 1;e49 <= m2; e49++)
c2.fixedSegments.push({ regionId: h2[e49 - 1], fromPortId: l2[e49 - 1], toPortId: l2[e49] });
for (let e49 = g2 + 1;e49 < l2.length; e49++)
c2.fixedSegments.push({ regionId: h2[e49 - 1], fromPortId: l2[e49 - 1], toPortId: l2[e49] });
c2.activeStartPortId = l2[m2], c2.activeEndPortId = l2[g2], c2.forcedStartRegionId = h2[m2], o2[a2] = c2.activeStartPortId, i2[a2] = c2.activeEndPortId, s2.push(a2);
}
return { sectionProblem: { routeCount: t2.routeCount, portSectionMask: new Int8Array(t2.portSectionMask), routeMetadata: t2.routeMetadata, routeStartPort: o2, routeEndPort: i2, routeNet: new Int32Array(t2.routeNet), regionNetId: new Int32Array(t2.regionNetId), portPenalty: t2.portPenalty === undefined ? undefined : new Float64Array(t2.portPenalty) }, routePlans: r2, activeRouteIds: s2 };
};
var Xq = (e48, t2, n2) => Yq(e48, t2, n2).activeRouteIds;
var Wq = class extends ZZ {
constructor(e48, t2, n2, o2, i2, r2, s2, a2) {
super(e48, t2, a2), this.routePlans = n2, this.activeRouteIds = o2, this.mutableRegionIds = i2, this.immutableRegionSummary = r2, this.baselineSummary = s2, Aq(this, a2), this.state.unroutedRoutes = [...o2], this.applyFixedSegments(), this.fixedSnapshot = Dq({ 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 e48 of this.routePlans)
for (const { regionId: t2, fromPortId: n2, toPortId: o2 } of e48.fixedSegments)
this.state.currentRouteNetId = this.problem.routeNet[e48.routeId], this.state.regionSegments[t2].push([e48.routeId, n2, o2]), this.state.portAssignment[n2] = this.state.currentRouteNetId, this.state.portAssignment[o2] = this.state.currentRouteNetId, this.appendSegmentToRegionCache(t2, n2, o2);
this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined;
}
captureBestState(e48) {
this.bestSummary && Bq(e48, this.bestSummary) >= 0 || (this.bestSummary = e48, this.bestSnapshot = Dq({ portAssignment: this.state.portAssignment, regionSegments: this.state.regionSegments, regionIntersectionCaches: this.state.regionIntersectionCaches }));
}
restoreBestState() {
this.bestSnapshot && (Lq(this, this.bestSnapshot), this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.unroutedRoutes = [], this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.state.goalPortId = -1);
}
getStartingNextRegionId(e48, t2) {
const n2 = this.routePlans[e48]?.forcedStartRegionId;
return n2 !== undefined ? n2 : super.getStartingNextRegionId(e48, t2);
}
resetRoutingStateForRerip() {
if (!this.fixedSnapshot)
return super.resetRoutingStateForRerip(), this.state.unroutedRoutes = WU([...this.activeRouteIds], this.state.ripCount), void this.applyFixedSegments();
Lq(this, this.fixedSnapshot), this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.unroutedRoutes = WU([...this.activeRouteIds], this.state.ripCount), this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.state.goalPortId = -1;
}
onAllRoutesRouted() {
const { state: e48 } = this, t2 = Math.min(this.MAX_RIPS, this.RIP_THRESHOLD_RAMP_ATTEMPTS), n2 = t2 <= 0 ? 1 : Math.min(1, e48.ripCount / t2), o2 = this.RIP_THRESHOLD_START + (this.RIP_THRESHOLD_END - this.RIP_THRESHOLD_START) * n2, i2 = [], r2 = new Float64Array(this.mutableRegionIds.length);
let s2 = 0, a2 = 0;
for (let t3 = 0;t3 < this.mutableRegionIds.length; t3++) {
const n3 = this.mutableRegionIds[t3], c3 = e48.regionIntersectionCaches[n3]?.existingRegionCost ?? 0;
r2[t3] = c3, s2 = Math.max(s2, c3), a2 += c3, c3 > o2 && i2.push(n3);
}
const c2 = Math.max(this.immutableRegionSummary.maxRegionCost, s2), l2 = this.immutableRegionSummary.totalRegionCost + a2;
this.captureBestState({ maxRegionCost: c2, totalRegionCost: l2 });
const h2 = this.bestSummary ?? { maxRegionCost: c2, totalRegionCost: l2 };
if (h2.maxRegionCost < this.previousBestMaxRegionCost - Number.EPSILON ? (this.previousBestMaxRegionCost = h2.maxRegionCost, this.ripsSinceBestMaxRegionCostImprovement = 0) : this.ripsSinceBestMaxRegionCostImprovement += 1, this.baselineBeatRipCount === undefined && h2.maxRegionCost < this.baselineSummary.maxRegionCost - Number.EPSILON && (this.baselineBeatRipCount = e48.ripCount), this.stats = { ...this.stats, activeRouteCount: this.activeRouteIds.length, currentRipThreshold: o2, hotRegionCount: i2.length, maxRegionCost: c2, totalRegionCost: l2, bestMaxRegionCost: h2.maxRegionCost, bestTotalRegionCost: h2.totalRegionCost, ripCount: e48.ripCount }, i2.length === 0 || e48.ripCount >= t2 || this.ripsSinceBestMaxRegionCostImprovement >= this.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT || this.baselineBeatRipCount !== undefined && e48.ripCount - this.baselineBeatRipCount >= this.EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST)
return this.restoreBestState(), void (this.solved = true);
for (let t3 = 0;t3 < this.mutableRegionIds.length; t3++) {
const n3 = this.mutableRegionIds[t3];
e48.regionCongestionCost[n3] += r2[t3] * this.RIP_CONGESTION_REGION_COST_FACTOR;
}
e48.ripCount += 1, this.resetRoutingStateForRerip(), this.stats = { ...this.stats, ripCount: e48.ripCount, reripRegionCount: i2.length };
}
onOutOfCandidates() {
const { state: e48 } = this;
for (const t2 of this.mutableRegionIds) {
const n2 = e48.regionIntersectionCaches[t2]?.existingRegionCost ?? 0;
e48.regionCongestionCost[t2] += n2 * this.RIP_CONGESTION_REGION_COST_FACTOR;
}
e48.ripCount += 1, this.resetRoutingStateForRerip(), this.stats = { ...this.stats, ripCount: e48.ripCount, reripReason: "out_of_candidates" };
}
tryFinalAcceptance() {
if (this.bestSnapshot)
return this.restoreBestState(), void (this.solved = true);
this.fixedSnapshot && Lq(this, this.fixedSnapshot), this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.unroutedRoutes = [...this.activeRouteIds], this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.state.goalPortId = -1, this.stats = { ...this.stats, acceptedFixedSectionStateOnTimeout: true }, this.solved = true;
}
visualize() {
return YZ(this, { highlightSectionMask: true, showInitialRouteHints: false, showOnlySectionPortsOnIdle: true });
}
};
var Vq = class extends De {
constructor(e48, t2, n2, o2) {
super(), this.topology = e48, this.problem = t2, this.initialSolution = n2, Aq(this, o2), this.baselineSolver = ((e49, t3, n3, o3) => {
const i2 = Array.from({ length: e49.regionCount }, () => []);
for (let o4 = 0;o4 < t3.routeCount; o4++) {
const { orderedPortIds: r2, orderedRegionIds: s2 } = jq(e49, t3, n3, o4);
for (let e50 = 1;e50 < r2.length; e50++) {
const t4 = r2[e50 - 1], n4 = r2[e50];
i2[s2[e50 - 1]].push([o4, t4, n4]);
}
}
return $q(e49, t3, i2, o3);
})(e48, t2, n2, GZ(this)), this.baselineSummary = zq(this.baselineSolver.state.regionIntersectionCaches), this.sectionRegionIds = ((e49, t3) => {
const n3 = new Set;
for (let o3 = 0;o3 < t3.portSectionMask.length; o3++)
if (t3.portSectionMask[o3] === 1)
for (const t4 of e49.incidentPortRegion[o3] ?? [])
n3.add(t4);
return [...n3];
})(e48, t2), this.sectionBaselineSummary = ((e49, t3) => {
let n3 = 0, o3 = 0;
for (const i2 of t3) {
const t4 = e49[i2]?.existingRegionCost ?? 0;
n3 = Math.max(n3, t4), o3 += t4;
}
return { maxRegionCost: n3, totalRegionCost: o3 };
})(this.baselineSolver.state.regionIntersectionCaches, this.sectionRegionIds), this.outsideSectionBaselineSummary = ((e49, t3) => {
const n3 = new Set(t3);
let o3 = 0, i2 = 0;
for (let t4 = 0;t4 < e49.length; t4++) {
if (n3.has(t4))
continue;
const r2 = e49[t4]?.existingRegionCost ?? 0;
o3 = Math.max(o3, r2), i2 += r2;
}
return { maxRegionCost: o3, totalRegionCost: i2 };
})(this.baselineSolver.state.regionIntersectionCaches, this.sectionRegionIds), this.applySectionRipPolicy();
}
topology;
problem;
initialSolution;
baselineSolver;
baselineSummary;
sectionBaselineSummary;
outsideSectionBaselineSummary;
sectionRegionIds;
optimizedSolver;
sectionSolver;
activeRouteIds = [];
DISTANCE_TO_COST = 0.05;
minViaPadDiameter = LU;
VERBOSE = false;
RIP_THRESHOLD_START = 0.05;
RIP_THRESHOLD_END = 0.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 = 0.1;
MAX_ITERATIONS = 1e6;
STATIC_REACHABILITY_PRECHECK = false;
STATIC_REACHABILITY_PRECHECK_MAX_HOPS = 16;
ACCEPT_BEST_SOLUTION_ON_TIMEOUT = true;
GREEDY_FINAL_ROUTE_ITERS = 4;
applySectionRipPolicy() {
this.RIP_THRESHOLD_START = 0.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: e48, routePlans: t2, activeRouteIds: n2 } = Yq(this.topology, this.problem, this.initialSolution);
if (this.activeRouteIds = n2, n2.length === 0)
return this.optimizedSolver = this.baselineSolver, this.stats = { ...this.stats, activeRouteCount: 0, initialMaxRegionCost: this.baselineSummary.maxRegionCost, finalMaxRegionCost: this.baselineSummary.maxRegionCost, optimized: false }, void (this.solved = true);
var o2;
this.sectionSolver = new Wq(this.topology, e48, t2, n2, this.sectionRegionIds, this.outsideSectionBaselineSummary, this.baselineSummary, { ...GZ(o2 = this), MAX_RIPS: o2.MAX_RIPS, MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT: o2.MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT, EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST: o2.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 = true);
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: false, sectionSearchFailedFallbackToBaseline: true, sectionSearchError: this.sectionSolver.error }, void (this.solved = true);
if (!this.sectionSolver.solved)
return;
const e48 = $q(this.topology, this.problem, Oq(this.sectionSolver.state.regionSegments), GZ(this)), t2 = zq(e48.state.regionIntersectionCaches), n2 = Bq(t2, this.baselineSummary) < 0;
this.optimizedSolver = n2 ? e48 : this.baselineSolver;
const o2 = n2 ? t2 : this.baselineSummary;
this.stats = { ...this.stats, initialMaxRegionCost: this.baselineSummary.maxRegionCost, initialTotalRegionCost: this.baselineSummary.totalRegionCost, candidateMaxRegionCost: t2.maxRegionCost, candidateTotalRegionCost: t2.totalRegionCost, finalMaxRegionCost: o2.maxRegionCost, finalTotalRegionCost: o2.totalRegionCost, optimized: n2 }, this.solved = true;
}
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: false, sectionSolverTimeoutFallbackToBaseline: true }, this.solved = true, this.failed = false, 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 ? YZ(this.optimizedSolver, { highlightSectionMask: true }) : this.sectionSolver ? this.sectionSolver.visualize() : YZ(this.baselineSolver, { highlightSectionMask: true, showInitialRouteHints: false, showOnlySectionPortsOnIdle: true });
}
getOutput() {
return this.getSolvedSolver().getOutput();
}
};
var Hq = ["self-touch", "onehop-all", "onehop-touch", "twohop-all", "twohop-touch"];
var Gq = { "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 };
var Uq = (e48, t2) => {
const n2 = new Set(t2);
for (const o2 of t2)
for (const t3 of e48.regionIncidentPorts[o2] ?? [])
for (const o3 of e48.incidentPortRegion[t3] ?? [])
n2.add(o3);
return [...n2];
};
var Zq = (e48, t2, n2) => {
let o2 = [...new Set(t2)];
for (let t3 = 0;t3 < n2; t3 += 1)
o2 = Uq(e48, o2);
return o2;
};
var qq = (e48, t2, n2) => t2.flatMap((t3) => n2.map((n3) => ((e49, t4, n4) => ({ label: `hot-${t4}-${n4}`, family: n4, regionIds: Zq(e49, [t4], Gq[n4]), portSelectionRule: n4.endsWith("-all") ? "all-incident-regions-selected" : "touches-selected-region" }))(e48, t3, n3)));
var Jq = { RIP_THRESHOLD_RAMP_ATTEMPTS: 5 };
var Qq = { DISTANCE_TO_COST: 0.05, RIP_THRESHOLD_RAMP_ATTEMPTS: 16, RIP_CONGESTION_REGION_COST_FACTOR: 0.1, MAX_ITERATIONS: 50000, MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT: 6, EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST: Number.POSITIVE_INFINITY };
var Kq = (e48) => e48.state.regionIntersectionCaches.reduce((e49, t2) => Math.max(e49, t2.existingRegionCost), 0);
var eJ = (e48, t2) => {
const n2 = cq(e48), o2 = new Vq(n2.topology, n2.problem, n2.solution, t2);
return Kq(o2.baselineSolver);
};
var tJ = (e48, t2, n2) => {
const o2 = new Set(t2);
return Int8Array.from({ length: e48.portCount }, (t3, i2) => {
const r2 = e48.incidentPortRegion[i2] ?? [];
return n2 === "touches-selected-region" ? r2.some((e49) => o2.has(e49)) ? 1 : 0 : r2.length > 0 && r2.every((e49) => o2.has(e49)) ? 1 : 0;
});
};
var nJ = (e48, t2) => ({ routeCount: e48.routeCount, portSectionMask: t2, routeMetadata: e48.routeMetadata, routeStartPort: new Int32Array(e48.routeStartPort), routeEndPort: new Int32Array(e48.routeEndPort), routeNet: new Int32Array(e48.routeNet), regionNetId: new Int32Array(e48.regionNetId), portPenalty: e48.portPenalty === undefined ? undefined : new Float64Array(e48.portPenalty) });
var oJ = (e48, t2, n2, o2, i2, r2) => {
const s2 = performance.now(), a2 = performance.now(), c2 = new Vq(t2, n2, o2, r2), l2 = Kq(c2.baselineSolver), h2 = performance.now() - a2;
let d2, u2, p2 = l2, m2 = new Int8Array(t2.portCount), g2 = 0, f2 = 0, _2 = 0, y2 = 0, b2 = 0, x2 = 0, v2 = 0;
const I2 = new Set, S2 = i2?.maxHotRegions ?? r2.MAX_HOT_REGIONS ?? 2;
for (const s3 of ((e49, t3, n3, o3) => {
const i3 = e49.state.regionIntersectionCaches.map((e50, t4) => ({ regionId: t4, regionCost: e50.existingRegionCost })).filter(({ regionCost: e50 }) => e50 > 0).sort((e50, t4) => t4.regionCost - e50.regionCost).slice(0, n3).map(({ regionId: e50 }) => e50);
return qq(t3, i3, o3);
})(e48, t2, S2, i2?.candidateFamilies ?? [...Hq])) {
const e49 = nJ(n2, tJ(t2, s3.regionIds, s3.portSelectionRule));
g2 += 1;
const i3 = e49.portSectionMask.join(",");
if (I2.has(i3))
_2 += 1;
else {
I2.add(i3);
try {
const n3 = performance.now(), i4 = Xq(t2, e49, o2);
if (y2 += performance.now() - n3, i4.length === 0)
continue;
f2 += 1;
const a3 = performance.now(), c3 = new Vq(t2, e49, o2, r2);
b2 += performance.now() - a3;
const l3 = performance.now();
if (c3.solve(), x2 += performance.now() - l3, c3.failed || !c3.solved)
continue;
if (Number(c3.stats.finalMaxRegionCost ?? Kq(c3.getSolvedSolver())) < p2 - 0.000000001) {
const t3 = performance.now(), n4 = eJ(c3.getOutput(), r2);
v2 += performance.now() - t3, n4 < p2 - 0.000000001 && (p2 = n4, m2 = new Int8Array(e49.portSectionMask), d2 = s3.label, u2 = s3.family);
}
} catch {}
}
}
return { portSectionMask: m2, baselineMaxRegionCost: l2, finalMaxRegionCost: p2, generatedCandidateCount: g2, candidateCount: f2, duplicateCandidateCount: _2, totalMs: performance.now() - s2, baselineEvaluationMs: h2, candidateEligibilityMs: y2, candidateInitMs: b2, candidateSolveMs: x2, candidateReplayScoreMs: v2, winningCandidateLabel: d2, winningCandidateFamily: u2 };
};
var iJ = class extends ze {
initialVisualizationSolver;
selectedSectionMask;
selectedSectionCandidateLabel;
selectedSectionCandidateFamily;
constructor(e48) {
super(e48), this.MAX_ITERATIONS = 200000;
}
loadHyperGraph(e48) {
return cq(e48);
}
getSolveGraphOptions() {
return { ...Jq, ...this.inputProblem.minViaPadDiameter === undefined ? {} : { minViaPadDiameter: this.inputProblem.minViaPadDiameter }, ...this.inputProblem.solveGraphOptions };
}
getSectionSolverOptions() {
return { ...Qq, ...this.inputProblem.minViaPadDiameter === undefined ? {} : { minViaPadDiameter: this.inputProblem.minViaPadDiameter }, ...this.inputProblem.sectionSolverOptions };
}
pipelineDef = [{ solverName: "solveGraph", solverClass: ZZ, getConstructorParams: (e48) => {
const { topology: t2, problem: n2 } = e48.loadHyperGraph(e48.inputProblem.serializedHyperGraph);
return [t2, n2, e48.getSolveGraphOptions()];
} }, { solverName: "optimizeSection", solverClass: Vq, getConstructorParams: (e48) => e48.getSectionStageParams() }];
getSectionStageParams() {
const e48 = this.getStageOutput("solveGraph");
if (!e48)
throw new Error("solveGraph did not produce a solved serialized hypergraph");
const t2 = this.getSolver("solveGraph");
if (!t2)
throw new Error("solveGraph solver is unavailable");
const n2 = this.getSectionSolverOptions(), { topology: o2, problem: i2, solution: r2 } = this.loadHyperGraph(e48), s2 = this.inputProblem.createSectionMask ? this.inputProblem.createSectionMask({ serializedHyperGraph: this.inputProblem.serializedHyperGraph, solvedSerializedHyperGraph: e48, solvedSolver: t2, topology: o2, problem: i2, solution: r2 }) : (() => {
const e49 = oJ(t2, o2, i2, r2, this.inputProblem.sectionSearchConfig, n2);
return this.selectedSectionCandidateLabel = e49.winningCandidateLabel, this.selectedSectionCandidateFamily = e49.winningCandidateFamily, this.stats = { ...this.stats, sectionSearchGeneratedCandidateCount: e49.generatedCandidateCount, sectionSearchCandidateCount: e49.candidateCount, sectionSearchDuplicateCandidateCount: e49.duplicateCandidateCount, sectionSearchBaselineMaxRegionCost: e49.baselineMaxRegionCost, sectionSearchFinalMaxRegionCost: e49.finalMaxRegionCost, sectionSearchDelta: e49.baselineMaxRegionCost - e49.finalMaxRegionCost, selectedSectionCandidateLabel: e49.winningCandidateLabel ?? null, selectedSectionCandidateFamily: e49.winningCandidateFamily ?? null, sectionSearchMs: e49.totalMs, sectionSearchBaselineEvaluationMs: e49.baselineEvaluationMs, sectionSearchCandidateEligibilityMs: e49.candidateEligibilityMs, sectionSearchCandidateInitMs: e49.candidateInitMs, sectionSearchCandidateSolveMs: e49.candidateSolveMs, sectionSearchCandidateReplayScoreMs: e49.candidateReplayScoreMs }, e49.portSectionMask;
})();
return this.selectedSectionMask = new Int8Array(s2), i2.portSectionMask = new Int8Array(s2), this.stats = { ...this.stats, sectionMaskPortCount: [...s2].filter((e49) => e49 === 1).length }, [o2, i2, r2, n2];
}
getInitialVisualizationSolver() {
if (!this.initialVisualizationSolver) {
const { topology: e48, problem: t2 } = this.loadHyperGraph(this.inputProblem.serializedHyperGraph);
this.initialVisualizationSolver = new ZZ(e48, t2, this.getSolveGraphOptions());
}
return this.initialVisualizationSolver;
}
initialVisualize() {
return this.getInitialVisualizationSolver().visualize();
}
visualize() {
return this.iterations === 0 ? this.initialVisualize() ?? super.visualize() : super.visualize();
}
getOutput() {
return this.getStageOutput("optimizeSection") ?? this.getStageOutput("solveGraph") ?? null;
}
tryFinalAcceptance() {
this.getStageOutput("solveGraph") && (this.stats = { ...this.stats, acceptedSolveGraphOutputOnSectionPipelineTimeout: true }, this.activeSubSolver = undefined, this.solved = true, this.failed = false, this.error = null);
}
};
var rJ = class extends eq {
costAwareFinalReripBudget = 8;
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(e48, t2, n2) {
super(e48, t2, n2);
}
getSelectiveReripStats() {
return { ...this.selectiveReripStats, failedOwnerPairs: this.selectiveReripStats.failedOwnerPairs.map((e48) => ({ ...e48 })), lastDirectOwnerRouteIds: [...this.selectiveReripStats.lastDirectOwnerRouteIds], lastRepeatedOwnerRouteIds: [...this.selectiveReripStats.lastRepeatedOwnerRouteIds], lastAlternateOwnerRouteIds: [...this.selectiveReripStats.lastAlternateOwnerRouteIds], lastRippedRouteIds: [...this.selectiveReripStats.lastRippedRouteIds] };
}
createGreedyFinalRouteSolver(e48, t2) {
if (t2 >= 0)
return super.createGreedyFinalRouteSolver(e48, t2);
const n2 = new sJ(this.topology, this.problem, { ...e48, MAX_ITERATIONS: Math.max(e48.MAX_ITERATIONS ?? 50000, 2 * this.MAX_ITERATIONS) });
return n2.remainingReripBudget = this.costAwareFinalReripBudget - this.state.ripCount, n2;
}
onOutOfCandidates() {
const e48 = this.state.currentRouteId;
if (e48 === undefined)
throw new Error("SelectiveReripTinyHyperGraphSolver: candidate search exhausted without a current route");
const t2 = this.findRelaxedBlockerPathPreferringPreservedRoutes();
if (!t2.found || t2.owners.size === 0)
return this.selectiveReripStats.globalReripCount += 1, this.selectiveReripStats.globalReripReason = t2.found ? "no_blocker_path" : t2.reason, this.selectiveReripStats.lastFailedRouteId = e48, this.selectiveReripStats.lastDirectOwnerRouteIds = [], this.selectiveReripStats.lastRepeatedOwnerRouteIds = [], this.selectiveReripStats.lastAlternateOwnerRouteIds = [], this.selectiveReripStats.lastRippedRouteIds = [], this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount = t2.expandedLabelCount, this.selectiveReripStats.lastAlternateSearchExpandedLabelCount = 0, super.onOutOfCandidates(), void this.publishSelectiveReripStats();
const n2 = [...t2.owners], o2 = [];
for (const t3 of n2) {
this.incrementFailedOwnerPair(e48, t3) >= 2 && o2.push(t3);
}
if (n2.some((t3) => this.hasFailedOwnerPath(t3, e48)))
return this.selectiveReripStats.globalReripCount += 1, this.selectiveReripStats.globalReripReason = "failed_owner_cycle", this.selectiveReripStats.lastFailedRouteId = e48, this.selectiveReripStats.lastDirectOwnerRouteIds = n2, this.selectiveReripStats.lastRepeatedOwnerRouteIds = o2, this.selectiveReripStats.lastAlternateOwnerRouteIds = [], this.selectiveReripStats.lastRippedRouteIds = [], this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount = t2.expandedLabelCount, this.selectiveReripStats.lastAlternateSearchExpandedLabelCount = 0, this.failedOwnerPairCounts.clear(), super.onOutOfCandidates(), void this.publishSelectiveReripStats();
let i2;
if (o2.length > 0 && (this.selectiveReripStats.alternateBlockerSearchCount += 1, i2 = this.findRelaxedBlockerPathPreferringPreservedRoutes(new Set(o2)), !i2.found))
return this.selectiveReripStats.globalReripCount += 1, this.selectiveReripStats.globalReripReason = i2.reason, this.selectiveReripStats.lastFailedRouteId = e48, this.selectiveReripStats.lastDirectOwnerRouteIds = n2, this.selectiveReripStats.lastRepeatedOwnerRouteIds = o2, this.selectiveReripStats.lastAlternateOwnerRouteIds = [], this.selectiveReripStats.lastRippedRouteIds = [], this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount = t2.expandedLabelCount, this.selectiveReripStats.lastAlternateSearchExpandedLabelCount = i2.expandedLabelCount, super.onOutOfCandidates(), void this.publishSelectiveReripStats();
const r2 = i2?.found ? [...i2.owners] : undefined, s2 = function(e49) {
const t3 = new Set(e49.alternateOwnerRouteIds ?? e49.directOwnerRouteIds);
if (t3.delete(e49.failedRouteId), t3.size === 0)
throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${e49.failedRouteId} has blocker resources but no distinct committed owner can be reripped`);
return t3;
}({ failedRouteId: e48, directOwnerRouteIds: n2, alternateOwnerRouteIds: r2 });
this.clearPartialRipPlans(s2);
const a2 = (r2 ?? []).filter((e49) => !t2.owners.has(e49));
this.selectiveReripCongestionUpdateCount < 1 && (this.addCongestionCostForSelectiveRerip(), this.selectiveReripCongestionUpdateCount += 1), this.rebuildCommittedState(s2), this.state.ripCount += 1, this.state.currentRouteId = undefined, this.state.currentRouteNetId = undefined, this.state.unroutedRoutes = function(e49) {
const t3 = e49.pendingRouteIds.filter((t4) => t4 !== e49.failedRouteId && !e49.rippedRouteIds.has(t4)), n3 = [...e49.rippedRouteIds].filter((t4) => t4 !== e49.failedRouteId);
return [e49.failedRouteId, ...t3, ...n3];
}({ failedRouteId: e48, pendingRouteIds: this.state.unroutedRoutes, rippedRouteIds: s2 }), this.state.candidateQueue.clear(), this.resetCandidateBestCosts(), this.state.goalPortId = -1, this.selectiveReripStats.selectiveRipCount += 1, this.selectiveReripStats.selectivelyRippedRouteCount += s2.size, this.selectiveReripStats.alternateOwnerCount += a2.length, this.selectiveReripStats.lastFailedRouteId = e48, this.selectiveReripStats.lastDirectOwnerRouteIds = n2, this.selectiveReripStats.lastRepeatedOwnerRouteIds = o2, this.selectiveReripStats.lastAlternateOwnerRouteIds = a2, this.selectiveReripStats.lastRippedRouteIds = [...s2], this.selectiveReripStats.lastRelaxedSearchExpandedLabelCount = t2.expandedLabelCount, this.selectiveReripStats.lastAlternateSearchExpandedLabelCount = i2?.expandedLabelCount ?? 0, this.publishSelectiveReripStats();
}
addCongestionCostForSelectiveRerip() {
for (let e48 = 0;e48 < this.topology.regionCount; e48++) {
const t2 = this.state.regionIntersectionCaches[e48]?.existingRegionCost ?? 0;
this.state.regionCongestionCost[e48] += t2 * this.RIP_CONGESTION_REGION_COST_FACTOR;
}
}
findRelaxedBlockerPath(e48 = new Set) {
const t2 = this.state.currentRouteId, n2 = this.state.currentRouteNetId;
if (t2 === undefined || n2 === undefined)
throw new Error("SelectiveReripTinyHyperGraphSolver: blocker search requires a current route and net");
const o2 = this.getRouteStartPortId(t2), i2 = this.getRouteEndPortId(t2), r2 = this.getStartingNextRegionId(t2, o2);
if (r2 === undefined)
throw new Error(`SelectiveReripTinyHyperGraphSolver: route ${this.describeRoute(t2)} has no starting region for blocker search`);
const s2 = this.getPortOwners(), a2 = new Map, c2 = new Map, l2 = new Map;
return ((e49) => {
const t3 = e49.maxExpandedLabels ?? Number.POSITIVE_INFINITY;
if (t3 !== Number.POSITIVE_INFINITY && (!Number.isInteger(t3) || t3 < 0))
throw new Error("maxExpandedLabels must be a non-negative integer");
const n3 = new Map, o3 = new wq;
let i3 = 0, r3 = 0;
const s3 = { state: e49.start, stateKey: e49.getStateKey(e49.start), owners: new Set, distance: 0, parent: null, incomingHop: null, queueOrder: i3++, active: true };
for (n3.set(s3.stateKey, [s3]), o3.push(s3);; ) {
const s4 = Eq(o3);
if (s4 === null)
return { found: false, reason: "no_path", expandedLabelCount: r3 };
if (e49.isGoal(s4.state))
return Rq(s4, r3);
if (r3 >= t3)
return { found: false, reason: "expansion_limit", expandedLabelCount: r3 };
r3++;
for (const t4 of e49.getHops(s4.state)) {
if (!Number.isFinite(t4.distance) || t4.distance < 0)
throw new Error("Distinct-owner blocker hops require finite distances >= 0");
const r4 = s4.distance + t4.distance;
if (!Number.isFinite(r4))
throw new Error("Distinct-owner blocker path distance overflowed");
const a3 = e49.getStateKey(t4.state), c3 = i3++, l3 = n3.get(a3) ?? [], h2 = t4.owners ?? [];
let d2 = false;
for (const e50 of l3)
if (e50.distance <= r4 && Nq(e50.owners, s4.owners, h2)) {
d2 = true;
break;
}
if (d2)
continue;
let u2 = s4.owners;
for (const e50 of h2)
u2.has(e50) || (u2 === s4.owners && (u2 = new Set(s4.owners)), u2.add(e50));
const p2 = { state: t4.state, stateKey: a3, owners: u2, distance: r4, parent: s4, incomingHop: t4, queueOrder: c3, active: true }, m2 = [];
for (const e50 of l3)
Tq(p2, e50) ? e50.active = false : m2.push(e50);
m2.push(p2), n3.set(p2.stateKey, m2), o3.push(p2);
}
}
})({ start: { portId: o2, nextRegionId: r2 }, getStateKey: ({ portId: e49, nextRegionId: t3 }) => this.getHopId(e49, t3), isGoal: ({ portId: e49 }) => e49 === i2, getHops: (t3) => {
const o3 = this.getHopId(t3.portId, t3.nextRegionId), r3 = l2.get(o3);
if (r3)
return r3;
const h2 = this.getRelaxedSearchHops({ state: t3, goalPortId: i2, routeNetId: n2, portOwners: s2, portResources: a2, hopTemplatesByRegion: c2, forbiddenOwnerRouteIds: e48 });
return l2.set(o3, h2), h2;
}, maxExpandedLabels: this.getRelaxedSearchExpansionLimit() });
}
findRelaxedBlockerPathPreferringPreservedRoutes(e48 = new Set) {
const t2 = this.getRouteIdsPreferredForPreservation();
if (t2.size === 0)
return this.findRelaxedBlockerPath(e48);
const n2 = new Set(e48);
for (const e49 of t2)
n2.add(e49);
const o2 = this.findRelaxedBlockerPath(n2);
return o2.found && o2.owners.size > 0 ? o2 : this.findRelaxedBlockerPath(e48);
}
getRelaxedSearchExpansionLimit() {
let e48 = 0;
for (const t3 of this.topology.incidentPortRegion)
e48 += t3.length;
const t2 = Math.max(4, Math.ceil(Math.log2(this.problem.routeCount + 1)));
return Math.max(4096, e48 * t2 * 4);
}
getRelaxedSearchHops(e48) {
const { state: t2, goalPortId: n2, routeNetId: o2 } = e48;
if (this.isRegionReservedForDifferentNet(t2.nextRegionId))
return [];
if (!e48.buildRegionTemplates && !this.isKnownSingleLayerRegion(t2.nextRegionId)) {
let n3 = e48.hopTemplatesByRegion.get(t2.nextRegionId);
n3 || (n3 = this.getRelaxedSearchHops({ ...e48, buildRegionTemplates: true }), e48.hopTemplatesByRegion.set(t2.nextRegionId, n3));
const o3 = [];
for (const e49 of n3)
e49.state.portId !== t2.portId && o3.push({ state: e49.state, owners: e49.owners, data: e49.data, distance: Math.hypot(this.topology.portX[t2.portId] - this.topology.portX[e49.state.portId], this.topology.portY[t2.portId] - this.topology.portY[e49.state.portId]) });
return o3;
}
const i2 = [];
for (const r2 of this.topology.regionIncidentPorts[t2.nextRegionId] ?? []) {
if (r2 === t2.portId && !e48.buildRegionTemplates)
continue;
if (this.isPortReservedForDifferentNet(r2))
continue;
if (r2 !== n2 && this.problem.portSectionMask[r2] === 0)
continue;
const s2 = this.getHopBlockerResources({ regionId: t2.nextRegionId, fromPortId: t2.portId, toPortId: r2, routeNetId: o2, portOwners: e48.portOwners, portResources: e48.portResources }), a2 = [];
for (const e49 of s2)
for (const t3 of e49.owners)
a2.includes(t3) || a2.push(t3);
if (a2.some((t3) => e48.forbiddenOwnerRouteIds.has(t3)))
continue;
let c2 = t2.nextRegionId;
if (r2 !== n2) {
const [e49, n3] = this.topology.incidentPortRegion[r2] ?? [];
if (c2 = e49 === t2.nextRegionId ? n3 : e49, c2 === undefined || this.isRegionReservedForDifferentNet(c2))
continue;
}
i2.push({ state: { portId: r2, nextRegionId: c2 }, distance: Math.hypot(this.topology.portX[t2.portId] - this.topology.portX[r2], this.topology.portY[t2.portId] - this.topology.portY[r2]), owners: a2, data: { resources: s2 } });
}
return i2;
}
getHopBlockerResources(e48) {
const t2 = [], n2 = this.state.portAssignment[e48.toPortId];
if (n2 !== -1 && n2 !== e48.routeNetId) {
let o3 = e48.portResources.get(e48.toPortId);
if (!o3) {
const t3 = [...e48.portOwners.get(e48.toPortId) ?? new Set].filter((t4) => this.problem.routeNet[t4] !== e48.routeNetId);
if (t3.length === 0)
throw new Error(`SelectiveReripTinyHyperGraphSolver: port ${e48.toPortId} is assigned to foreign net ${n2} without a committed route owner`);
o3 = { kind: "port", portId: e48.toPortId, owners: t3 }, e48.portResources.set(e48.toPortId, o3);
}
t2.push(o3);
}
const o2 = this.getHardBlockedCrossingOwners(e48.regionId, e48.fromPortId, e48.toPortId);
return o2.length > 0 && t2.push({ kind: "same_layer_intersection", regionId: e48.regionId, fromPortId: e48.fromPortId, toPortId: e48.toPortId, owners: o2 }), t2;
}
getPortOwners() {
const e48 = new Map;
for (const t2 of this.state.regionSegments)
for (const [n2, o2, i2] of t2)
for (const t3 of [o2, i2]) {
const o3 = e48.get(t3) ?? new Set;
o3.add(n2), e48.set(t3, o3);
}
return e48;
}
getHardBlockedCrossingOwners(e48, t2, n2) {
if (!this.isKnownSingleLayerRegion(e48))
return [];
const o2 = this.state.currentRouteNetId;
if (o2 === undefined)
throw new Error("SelectiveReripTinyHyperGraphSolver: crossing ownership requires a current route net");
const i2 = new Set;
for (const [r2, s2, a2] of this.state.regionSegments[e48] ?? [])
this.problem.routeNet[r2] !== o2 && this.segmentsCrossOnSameLayer(e48, t2, n2, s2, a2) && i2.add(r2);
return [...i2];
}
segmentsCrossOnSameLayer(e48, t2, n2, o2, i2) {
const r2 = this.populateSegmentGeometryScratch(e48, t2, n2), s2 = r2.lesserAngle, a2 = r2.greaterAngle, c2 = r2.layerMask, l2 = this.populateSegmentGeometryScratch(e48, o2, i2);
if ((c2 & l2.layerMask) === 0)
return false;
if (s2 === l2.lesserAngle || s2 === l2.greaterAngle || a2 === l2.lesserAngle || a2 === l2.greaterAngle)
return false;
return (s2 < l2.lesserAngle && l2.lesserAngle < a2) !== (s2 < l2.greaterAngle && l2.greaterAngle < a2);
}
rebuildCommittedState(e48) {
this.state.regionSegments = this.state.regionSegments.map((t2) => t2.filter(([t3]) => !e48.has(t3))), this.state.portAssignment.fill(-1), this.state.regionIntersectionCaches = Array.from({ length: this.topology.regionCount }, () => XZ());
for (let e49 = 0;e49 < this.state.regionSegments.length; e49++)
for (const [t2, n2, o2] of this.state.regionSegments[e49]) {
const i2 = this.problem.routeNet[t2];
this.state.currentRouteNetId = i2;
for (const e50 of [n2, o2]) {
const t3 = this.state.portAssignment[e50];
if (t3 !== -1 && t3 !== i2)
throw new Error(`SelectiveReripTinyHyperGraphSolver: rebuilding committed routes found cross-net ownership at port ${e50} between net ${t3} and net ${i2}`);
this.state.portAssignment[e50] = i2;
}
this.appendSegmentToRegionCache(e49, n2, o2);
}
this.state.currentRouteNetId = undefined;
}
incrementFailedOwnerPair(e48, t2) {
const n2 = this.failedOwnerPairCounts.get(e48) ?? new Map, o2 = (n2.get(t2) ?? 0) + 1;
return n2.set(t2, o2), this.failedOwnerPairCounts.set(e48, n2), o2;
}
hasFailedOwnerPath(e48, t2) {
const n2 = [e48], o2 = new Set;
for (;n2.length > 0; ) {
const e49 = n2.pop();
if (e49 === t2)
return true;
o2.has(e49) || (o2.add(e49), n2.push(...this.failedOwnerPairCounts.get(e49)?.keys() ?? []));
}
return false;
}
publishSelectiveReripStats() {
const e48 = [];
for (const [t2, n2] of this.failedOwnerPairCounts)
for (const [o2, i2] of n2)
e48.push({ failedRouteId: t2, ownerRouteId: o2, count: i2 });
e48.sort((e49, t2) => e49.failedRouteId - t2.failedRouteId || e49.ownerRouteId - t2.ownerRouteId), this.selectiveReripStats.failedOwnerPairs = e48, this.selectiveReripStats.failedOwnerPairCount = e48.length, this.selectiveReripStats.maxFailedOwnerPairCount = Math.max(0, ...e48.map(({ count: e49 }) => e49)), this.stats = { ...this.stats, ...this.getSelectiveReripStats() };
}
describeRoute(e48) {
const t2 = this.problem.routeMetadata?.[e48]?.connectionId;
return t2 === undefined ? String(e48) : `${e48} (${String(t2)})`;
}
};
var sJ = class extends rJ {
remainingReripBudget = 0;
onOutOfCandidates() {
super.onOutOfCandidates(), this.state.ripCount >= this.remainingReripBudget && (this.failed = true, this.error = "Congestion-aware final routing exhausted its rerip budget");
}
};
var aJ = class extends rJ {
initialAssignmentRouteIds;
getRouteIdsPreferredForPreservation() {
return this.initialAssignmentRouteIds || (this.initialAssignmentRouteIds = new Set((this.problem.initialAssignments ?? []).map((e48) => e48.routeId))), this.initialAssignmentRouteIds;
}
resetRoutingStateForRerip() {
super.resetRoutingStateForRerip(), this.problem.initialAssignments?.length && YU({ topology: this.topology, problem: this.problem, state: this.state, routeSuccessCountByRouteId: this.routeSuccessCountByRouteId, appendSegmentToRegionCache: (e48, t2, n2) => this.appendSegmentToRegionCache(e48, t2, n2) });
}
};
var cJ = (e48) => {
if (typeof e48 != "object" || e48 === null)
return false;
const t2 = e48, n2 = t2.preloadedTraceSection;
return typeof t2.connectionId == "string" && typeof n2?.traceId == "string" && typeof n2.startRoutePosition == "number" && typeof n2.endRoutePosition == "number" && typeof n2.startPoint?.x == "number" && typeof n2.startPoint.y == "number" && typeof n2.startPoint.z == "number" && typeof n2.endPoint?.x == "number" && typeof n2.endPoint.y == "number" && typeof n2.endPoint.z == "number";
};
var lJ = (e48, t2) => `__tscircuit_preloaded_trace__:${JSON.stringify([e48, t2])}`;
var hJ = (e48) => [e48.region1Id, e48.region2Id];
var dJ = (e48, t2) => {
const n2 = new Set(hJ(t2));
return hJ(e48).filter((e49) => n2.has(e49));
};
var uJ = (e48, t2, n2) => {
const o2 = e48[t2], i2 = e48[t2 + 1], r2 = dJ(o2.port, i2.port);
if (r2.length === 0)
return;
if (r2.length === 1)
return r2[0];
const s2 = e48[t2 + 2];
if (s2) {
const e49 = new Set(dJ(i2.port, s2.port)), t3 = r2.find((t4) => e49.has(t4));
if (t3)
return t3;
}
return n2 && r2.includes(n2) ? n2 : [...r2].sort()[0];
};
var pJ = (e48, t2) => hJ(e48).find((e49) => e49 !== t2) ?? t2;
var mJ = (e48) => {
const t2 = new Set((e48.connections ?? []).filter(cJ).map((e49) => e49.connectionId)), n2 = e48.ports.filter((e49) => (e49.d?._preloadedTracePortAssignments?.length ?? 0) > 0).length, o2 = e48.regions.reduce((e49, n3) => e49 + (n3.assignments ?? []).filter((e50) => t2.has(e50.connectionId)).length, 0);
return { preloadedTraceCount: t2.size, preloadedPortCount: n2, preloadedAssignmentCount: o2 };
};
var gJ = (e48) => typeof e48 == "object" && e48 !== null ? e48 : {};
var fJ = (e48) => typeof e48 == "object" && e48 !== null ? e48 : {};
var _J = 0.000001;
var yJ = { DISTANCE_TO_COST: 0.05, RIP_THRESHOLD_START: 0.05, RIP_THRESHOLD_END: 0.8, RIP_CONGESTION_REGION_COST_FACTOR: 0.1, ACCEPT_BEST_SOLUTION_ON_TIMEOUT: true, 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: 0.02, PARTIAL_RIP_MAX_REGION_COST_GROWTH_RATIO: 0.05, PARTIAL_RIP_MAX_TOTAL_COST_GROWTH_RATIO: 0.1 };
var bJ = { DISTANCE_TO_COST: 0.05, RIP_THRESHOLD_START: 0.05, RIP_THRESHOLD_END: 0.8, RIP_CONGESTION_REGION_COST_FACTOR: 0.1, ACCEPT_BEST_SOLUTION_ON_TIMEOUT: true, GREEDY_FINAL_ROUTE_ITERS: 4, MAX_RIPS_WITHOUT_MAX_REGION_COST_IMPROVEMENT: 6, EXTRA_RIPS_AFTER_BEATING_BASELINE_MAX_REGION_COST: Number.POSITIVE_INFINITY };
var xJ = (e48) => Math.max(e48, 0.01);
var vJ = (e48) => Number.isFinite(e48) ? { minViaPadDiameter: e48 } : {};
var IJ = (e48, t2) => {
const n2 = xJ(e48);
return { ...yJ, ...vJ(t2), USE_SPARSE_CANDIDATE_STORAGE: false, RIP_THRESHOLD_RAMP_ATTEMPTS: Math.ceil(10 * n2), MAX_ITERATIONS: Math.ceil(2000000 * n2) };
};
var SJ = (e48, t2) => {
const n2 = xJ(e48);
return { ...bJ, ...vJ(t2), USE_SPARSE_CANDIDATE_STORAGE: false, RIP_THRESHOLD_RAMP_ATTEMPTS: Math.ceil(16 * n2), MAX_ITERATIONS: Math.ceil(1e6 * n2) };
};
var CJ = (e48) => (e48.solveGraphOptions?.MAX_ITERATIONS ?? 1e6) + (e48.sectionSolverOptions?.MAX_ITERATIONS ?? 1e6) + 1e6;
var PJ = (e48) => e48.mutuallyConnectedNetworkId;
var MJ = (e48, t2) => e48.simpleRouteConnection?.pointsToConnect[t2];
var wJ = (e48) => {
const t2 = MJ(e48.routeMetadata, e48.endpointIndex);
if (!t2)
return e48.fallbackZ;
const n2 = Co(t2).map((t3) => go(t3, e48.layerCount));
return e48.regionAvailableZ.find((e49) => n2.includes(e49)) ?? e48.fallbackZ;
};
var NJ = (e48, t2) => {
const n2 = e48.d, o2 = n2.bounds;
return { capacityMeshNodeId: e48.d.capacityMeshNodeId, center: { x: e48.d.center.x, y: e48.d.center.y }, width: e48.d.width, height: e48.d.height, availableZ: [...e48.d.availableZ], ...o2 ? { bounds: { minX: o2.minX, maxX: o2.maxX, minY: o2.minY, maxY: o2.maxY } } : {}, _containsObstacle: e48.d._containsObstacle, _containsTarget: e48.d._containsTarget, _offBoardConnectionId: e48.d._offBoardConnectionId, _offBoardConnectedCapacityMeshNodeIds: e48.d._offBoardConnectedCapacityMeshNodeIds === undefined ? undefined : [...e48.d._offBoardConnectedCapacityMeshNodeIds], _qfpRegionType: n2._qfpRegionType, _isNarrowQfpPadGap: n2._isNarrowQfpPadGap, ...t2 !== undefined ? { netId: t2 } : {} };
};
var TJ = (e48) => {
const t2 = e48.d;
return { portId: e48.d.portId, x: e48.d.x, y: e48.d.y, z: e48.d.z, prevPortPointId: t2.prevPortPointId, nextPortPointId: t2.nextPortPointId, distToCentermostPortOnZ: e48.d.distToCentermostPortOnZ, tinyHypergraphPortPenalty: e48.d.tinyHypergraphPortPenalty, cramped: e48.d.cramped, _preloadedFixedNetIds: e48.d._preloadedFixedNetIds, _preloadedTracePortAssignments: e48.d._preloadedTracePortAssignments };
};
var RJ = (e48) => {
const t2 = function() {
const e49 = new Map;
return (t3) => {
const n3 = t3.mutuallyConnectedNetworkId;
let o3 = e49.get(n3);
return o3 === undefined && (o3 = e49.size, e49.set(n3, o3)), o3;
};
}(), n2 = function(e49) {
const t3 = new Map, n3 = new Set, o3 = new Map;
for (const i4 of e49.params.connections) {
const r3 = i4.mutuallyConnectedNetworkId, s3 = e49.getNetIndex({ connectionId: i4.connectionId, mutuallyConnectedNetworkId: r3 });
for (const e50 of [i4.connectionId, r3])
o3.set(e50, s3);
for (const o4 of i4.simpleRouteConnection.pointsToConnect) {
const i5 = VH({ point: o4, layerCount: e49.params.layerCount });
for (const r4 of e49.params.graph.regions) {
if (!HH({ point: o4, region: r4, layerCount: e49.params.layerCount, pointZLayers: i5 }))
continue;
if (o4.pcb_port_id === undefined && r4.d._containsTarget !== true) {
n3.add(r4.regionId);
continue;
}
let a3 = t3.get(r4.regionId);
a3 || (a3 = new Set, t3.set(r4.regionId, a3)), a3.add(s3);
}
}
}
for (const n4 of e49.params.graph.regions)
for (const e50 of n4.d._connectedTo ?? []) {
const i4 = o3.get(e50);
if (i4 === undefined)
continue;
let r3 = t3.get(n4.regionId);
r3 || (r3 = new Set, t3.set(n4.regionId, r3)), r3.add(i4);
}
const i3 = new Map;
for (const e50 of n3)
i3.set(e50, -1);
for (const [e50, n4] of t3)
n4.size === 1 && i3.set(e50, [...n4][0]);
return i3;
}({ params: e48, getNetIndex: t2 }), o2 = e48.graph.regions.map((e49) => ({ regionId: e49.regionId, pointIds: e49.ports.map((e50) => e50.d.portId), d: NJ(e49, n2.get(e49.regionId)) })), i2 = new Map;
for (const e49 of o2)
i2.has(e49.regionId) || i2.set(e49.regionId, e49);
const r2 = e48.graph.ports.map((e49) => ({ portId: e49.d.portId, region1Id: e49.region1.regionId, region2Id: e49.region2.regionId, d: TJ(e49) })), s2 = e48.connections.map((e49) => ({ connectionId: e49.connectionId, mutuallyConnectedNetworkId: e49.mutuallyConnectedNetworkId, startRegionId: e49.startRegion.regionId, endRegionId: e49.endRegion.regionId, simpleRouteConnection: e49.simpleRouteConnection })), a2 = [];
for (const n3 of e48.connections) {
const s3 = { connectionId: n3.connectionId, mutuallyConnectedNetworkId: n3.mutuallyConnectedNetworkId, simpleRouteConnection: n3.simpleRouteConnection }, c3 = t2(s3), l2 = MJ(s3, 0), h2 = MJ(s3, 1), d2 = n3.startRegion.d.availableZ[0] ?? 0, u2 = n3.endRegion.d.availableZ[0] ?? 0, p2 = wJ({ routeMetadata: s3, endpointIndex: 0, fallbackZ: d2, regionAvailableZ: n3.startRegion.d.availableZ, layerCount: e48.layerCount }), m2 = wJ({ routeMetadata: s3, endpointIndex: 1, fallbackZ: u2, regionAvailableZ: n3.endRegion.d.availableZ, layerCount: e48.layerCount }), g2 = `tiny-terminal:start-region:${n3.connectionId}`, f2 = `tiny-terminal:end-region:${n3.connectionId}`, _2 = `tiny-terminal:start-port:${n3.connectionId}`, y2 = `tiny-terminal:end-port:${n3.connectionId}`;
o2.push({ regionId: g2, pointIds: [_2], d: { capacityMeshNodeId: g2, center: { x: l2?.x ?? n3.startRegion.d.center.x, y: l2?.y ?? n3.startRegion.d.center.y }, width: _J, height: _J, availableZ: [p2], _containsTarget: true, _tinyTerminal: true, _tinyTerminalNetId: n3.mutuallyConnectedNetworkId, netId: c3 } }), o2.push({ regionId: f2, pointIds: [y2], d: { capacityMeshNodeId: f2, center: { x: h2?.x ?? n3.endRegion.d.center.x, y: h2?.y ?? n3.endRegion.d.center.y }, width: _J, height: _J, availableZ: [m2], _containsTarget: true, _tinyTerminal: true, _tinyTerminalNetId: n3.mutuallyConnectedNetworkId, netId: c3 } }), r2.push({ portId: _2, region1Id: n3.startRegion.regionId, region2Id: g2, d: { portId: _2, x: l2?.x ?? n3.startRegion.d.center.x, y: l2?.y ?? n3.startRegion.d.center.y, z: p2, distToCentermostPortOnZ: 0, _tinyTerminal: true, ...e48.preserveTerminalPcbPortIds && l2?.pcb_port_id ? { pcb_port_id: l2.pcb_port_id } : {} } }), r2.push({ portId: y2, region1Id: n3.endRegion.regionId, region2Id: f2, d: { portId: y2, x: h2?.x ?? n3.endRegion.d.center.x, y: h2?.y ?? n3.endRegion.d.center.y, z: m2, distToCentermostPortOnZ: 0, _tinyTerminal: true, ...e48.preserveTerminalPcbPortIds && h2?.pcb_port_id ? { pcb_port_id: h2.pcb_port_id } : {} } });
const b2 = i2.get(n3.startRegion.regionId), x2 = i2.get(n3.endRegion.regionId);
b2?.pointIds.push(_2), x2?.pointIds.push(y2), a2.push({ connection: { connectionId: n3.connectionId }, path: [{ portId: _2 }, { portId: y2 }] });
}
const c2 = { regions: o2, ports: r2, connections: s2, solvedRoutes: a2 };
return ((e49) => {
const t3 = new Map, n3 = new Map, o3 = new Set((e49.connections ?? []).flatMap((e50) => [e50.startRegionId, e50.endRegionId])), i3 = new Set(e49.regions.filter((e50) => {
const t4 = typeof e50.d?.netId == "number" ? e50.d.netId : typeof e50.d?.NetId == "number" ? e50.d.NetId : undefined;
return e50.d?._containsObstacle === true && (t4 === undefined || t4 === -1) && !o3.has(e50.regionId);
}).map((e50) => e50.regionId));
let r3 = 0;
for (const o4 of e49.ports) {
const e50 = o4.d, s4 = e50?._preloadedTracePortAssignments ?? [];
if (s4.length > 0 && r3++, !i3.has(o4.region1Id) && !i3.has(o4.region2Id))
for (const e51 of s4) {
const i4 = n3.get(e51.traceId);
if (i4 !== undefined && i4 !== e51.fixedNetId)
throw new Error(`Preloaded trace "${e51.traceId}" maps to multiple canonical nets`);
n3.set(e51.traceId, e51.fixedNetId);
const r4 = t3.get(e51.traceId) ?? [];
r4.push({ port: o4, assignment: e51 }), t3.set(e51.traceId, r4);
}
}
const s3 = new Map(e49.regions.map((e50) => [e50.regionId, e50])), a3 = e49.connections ??= [], c3 = e49.solvedRoutes ??= [];
for (const [e50, o4] of t3) {
o4.sort((e51, t5) => e51.assignment.routePosition - t5.assignment.routePosition || e51.assignment.z - t5.assignment.z || e51.port.portId.localeCompare(t5.port.portId));
const t4 = o4.filter(({ port: e51 }, t5) => t5 === 0 || e51.portId !== o4[t5 - 1].port.portId);
if (t4.length < 2)
continue;
const i4 = [];
let r4;
for (let e51 = 0;e51 < t4.length - 1; e51++) {
const n4 = t4[e51], o5 = t4[e51 + 1];
if (n4.assignment.z === o5.assignment.z && Math.abs(n4.assignment.routePosition - o5.assignment.routePosition) <= 0.000001) {
r4 = undefined;
continue;
}
const s4 = uJ(t4, e51, r4);
s4 ? (i4.push({ regionId: s4, from: n4, to: o5 }), r4 = s4) : r4 = undefined;
}
const d2 = [];
for (const e51 of i4) {
const t5 = d2.at(-1);
t5 && t5.at(-1).to.port.portId === e51.from.port.portId ? t5.push(e51) : d2.push([e51]);
}
for (const [t5, o5] of d2.entries()) {
const i5 = lJ(e50, t5);
for (const t6 of o5) {
const n4 = s3.get(t6.regionId);
if (!n4)
throw new Error(`Preloaded trace "${e50}" references missing region "${t6.regionId}"`);
n4.assignments = [...n4.assignments ?? [], { regionPort1Id: t6.from.port.portId, regionPort2Id: t6.to.port.portId, connectionId: i5 }];
}
const r5 = o5[0], l3 = o5.at(-1), d3 = r5.from.port, u2 = l3.to.port, p2 = { connectionId: i5, mutuallyConnectedNetworkId: n3.get(e50) ?? e50, startRegionId: pJ(d3, r5.regionId), endRegionId: pJ(u2, l3.regionId), preloadedTraceSection: { traceId: e50, startRoutePosition: r5.from.assignment.routePosition, endRoutePosition: l3.to.assignment.routePosition, startPoint: { x: r5.from.assignment.tracePoint.x, y: r5.from.assignment.tracePoint.y, z: r5.from.assignment.z }, endPoint: { x: l3.to.assignment.tracePoint.x, y: l3.to.assignment.tracePoint.y, z: l3.to.assignment.z } } };
a3.push(p2), c3.push({ requiredRip: false, connection: p2, path: [d3, u2].map((e51) => ({ portId: e51.portId, g: 0, h: 0, f: 0, hops: 0, ripRequired: false })) });
}
}
})(c2), c2;
};
var EJ = (e48) => {
const t2 = new Map;
for (let n2 = 0;n2 < e48.problem.routeNet.length; n2++) {
const o2 = e48.problem.routeMetadata?.[n2], i2 = o2?.mutuallyConnectedNetworkId;
if (typeof i2 != "string" || i2.length === 0)
throw new Error(`Tiny hypergraph route ${n2} is missing a net ID`);
t2.set(i2, e48.problem.routeNet[n2]);
}
for (let n2 = 0;n2 < e48.problem.regionNetId.length; n2++) {
const o2 = e48.topology.regionMetadata?.[n2]?._tinyTerminalNetId;
if (typeof o2 != "string")
continue;
const i2 = t2.get(o2);
i2 !== undefined && (e48.problem.regionNetId[n2] = i2);
}
};
var AJ = (e48) => {
const t2 = new Map;
e48.topology.regionMetadata?.forEach((e49, n3) => {
typeof e49.serializedRegionId == "string" && t2.set(e49.serializedRegionId, n3);
});
const n2 = new Set;
for (const t3 of e48.problem.routeMetadata ?? [])
cJ(t3) || (typeof t3.startRegionId == "string" && n2.add(t3.startRegionId), typeof t3.endRegionId == "string" && n2.add(t3.endRegionId));
for (const o2 of e48.problem.routeMetadata ?? [])
if (cJ(o2))
for (const i2 of [o2.startRegionId, o2.endRegionId]) {
if (typeof i2 != "string" || n2.has(i2))
continue;
const o3 = t2.get(i2);
if (o3 === undefined)
continue;
const r2 = e48.topology.regionMetadata?.[o3];
typeof r2?.netId == "number" || typeof r2?.NetId == "number" || (e48.problem.regionNetId[o3] = -1);
}
};
var OJ = (e48) => {
if (e48.problem.metadataPortPenaltiesApplied)
return 0;
let t2 = 0, n2 = e48.problem.portPenalty !== undefined;
for (let o3 = 0;o3 < e48.topology.portCount; o3++) {
const i2 = Number(e48.topology.portMetadata?.[o3]?.tinyHypergraphPortPenalty), r2 = Number.isFinite(i2) && i2 > 0 ? i2 : 0;
r2 > 0 && t2++, e48.problem.portPenalty?.[o3] !== r2 && (n2 = false);
}
if (n2)
return e48.problem.metadataPortPenaltiesApplied = true, t2;
t2 = 0;
const o2 = e48.problem.portPenalty ? new Float64Array(e48.problem.portPenalty) : new Float64Array(e48.topology.portCount);
for (let n3 = 0;n3 < e48.topology.portCount; n3++) {
const i2 = Number(e48.topology.portMetadata?.[n3]?.tinyHypergraphPortPenalty);
!Number.isFinite(i2) || i2 <= 0 || (o2[n3] += i2, t2++);
}
return t2 > 0 && (e48.problem.portPenalty = o2), e48.problem.metadataPortPenaltiesApplied = true, t2;
};
var kJ = class extends iJ {
configuredSolvers = new WeakSet;
duplicatePortPenaltyCount = 0;
metadataPortPenaltyCount = 0;
crampedPortPenaltyCount = 0;
preloadedPortCount = 0;
preloadedFixedSegmentCount = 0;
crampedPortTraversalPenalty;
useSelectiveReripRouting;
constructor(e48, t2) {
super(e48), this.useSelectiveReripRouting = t2, this.crampedPortTraversalPenalty = 150;
const n2 = mJ(e48.serializedHyperGraph);
if (this.preloadedPortCount = n2.preloadedPortCount, this.preloadedFixedSegmentCount = n2.preloadedAssignmentCount, t2) {
const e49 = this.pipelineDef.find((e50) => e50.solverName === "solveGraph");
if (!e49)
throw new Error("Tiny hypergraph pipeline is missing the solveGraph stage");
e49.solverClass = aJ;
}
this.MAX_ITERATIONS = CJ(e48);
}
loadHyperGraph(e48) {
const t2 = super.loadHyperGraph(e48);
((e49, t3) => {
const n3 = new Map;
for (const e50 of t3.connections ?? [])
cJ(e50) && n3.set(e50.connectionId, e50.preloadedTraceSection);
for (const t4 of e49.problem.routeMetadata ?? []) {
const e50 = n3.get(t4.connectionId);
e50 && (t4.preloadedTraceSection = e50);
}
})(t2, this.inputProblem.serializedHyperGraph);
const n2 = OJ(t2), { duplicatePortPenaltyCount: o2, crampedPortPenaltyCount: i2 } = ((e49, t3) => {
let n3 = 0, o3 = 0;
const i3 = e49.problem.portPenalty ? new Float64Array(e49.problem.portPenalty) : new Float64Array(e49.topology.portCount);
for (let r2 = 0;r2 < e49.topology.portCount; r2++) {
const s2 = e49.topology.portMetadata?.[r2];
typeof s2?.duplicatedFromPortId == "string" && (i3[r2] += 150, n3++), s2?.cramped && t3 > 0 && (i3[r2] += t3, o3++);
}
return (n3 > 0 || o3 > 0) && (e49.problem.portPenalty = i3), { duplicatePortPenaltyCount: n3, crampedPortPenaltyCount: o3 };
})(t2, this.crampedPortTraversalPenalty);
return EJ(t2), AJ(t2), this.metadataPortPenaltyCount = Math.max(this.metadataPortPenaltyCount, n2), this.duplicatePortPenaltyCount = Math.max(this.duplicatePortPenaltyCount, o2), this.crampedPortPenaltyCount = Math.max(this.crampedPortPenaltyCount, i2), t2;
}
_step() {
super._step(), this.configureSolver(this.activeSubSolver);
}
getInitialVisualizationSolver() {
if (this.useSelectiveReripRouting && !this.initialVisualizationSolver) {
const { topology: e49, problem: t2 } = this.loadHyperGraph(this.inputProblem.serializedHyperGraph);
this.initialVisualizationSolver = new aJ(e49, t2, this.getSolveGraphOptions());
}
const e48 = super.getInitialVisualizationSolver();
return this.configureSolver(e48), e48;
}
getSolvedTinySolver() {
const e48 = this.getSolver("optimizeSection");
if (e48?.solved && !e48.failed)
return e48.getSolvedSolver();
const t2 = this.getSolver("solveGraph");
if (t2?.solved && !t2.failed)
return t2;
throw new Error("TinyHyperGraph section pipeline does not have a solved graph");
}
configureSolver(e48) {
if (e48 && !this.configuredSolvers.has(e48)) {
if (e48 instanceof Vq || e48 instanceof ZZ) {
const t2 = e48;
OJ(t2), EJ(t2), AJ(t2);
}
this.configuredSolvers.add(e48);
}
}
};
var DJ = class extends ai {
constructor(e48) {
super(), this.params = e48;
const t2 = ((e49) => e49.map((e50) => {
const t3 = e50.simpleRouteConnection;
if (!t3)
throw new Error(`TinyHypergraphPortPointPathingSolver requires a SimpleRouteConnection for "${e50.connectionId}"`);
const n3 = e50.mutuallyConnectedNetworkId;
if (!n3)
throw new Error(`TinyHypergraphPortPointPathingSolver requires a net ID for "${e50.connectionId}"`);
return { ...e50, mutuallyConnectedNetworkId: n3, simpleRouteConnection: t3 };
}))(e48.connections), n2 = e48.flags.USE_SELECTIVE_RERIP_ROUTING ? function(e49, t3) {
const n3 = new Map;
for (const o3 of e49) {
const e50 = t3(o3);
n3.set(e50, (n3.get(e50) ?? 0) + 1);
}
return e49.map((e50, t4) => ({ connection: e50, index: t4 })).sort((e50, o3) => (n3.get(t3(o3.connection)) ?? 0) - (n3.get(t3(e50.connection)) ?? 0) || e50.index - o3.index).map(({ connection: e50 }) => e50);
}(t2, PJ) : t2;
this.rootConnectionNameByConnectionId = new Map(n2.map((e49) => [e49.connectionId, e49.simpleRouteConnection.__rootConnectionNames?.[0]]));
const o2 = RJ({ ...e48, connections: n2 });
this.originalPreloadedSegmentKeysByConnectionId = ((e49) => {
const t3 = new Map;
for (const n3 of e49.connections ?? [])
cJ(n3) && t3.set(n3.connectionId, new Set);
for (const n3 of e49.regions)
for (const e50 of n3.assignments ?? []) {
const o3 = t3.get(e50.connectionId);
if (!o3)
continue;
const [i3, r3] = [e50.regionPort1Id, e50.regionPort2Id].sort();
o3.add(JSON.stringify([n3.regionId, i3, r3]));
}
return t3;
})(o2);
const i2 = mJ(o2), r2 = i2.preloadedPortCount > 0, s2 = r2 && e48.flags.USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES === true, a2 = s2 ? Math.max(o2.connections?.length ?? 0, i2.preloadedAssignmentCount) : undefined;
let c2 = o2;
const l2 = new Pq(o2, { duplicatePortProximity: 0.05, useSerializedPortPenalties: false, routeSolveOptions: { ...vJ(e48.minViaPadDiameter), USE_SPARSE_CANDIDATE_STORAGE: false, ACCEPT_BEST_SOLUTION_ON_TIMEOUT: true, GREEDY_FINAL_ROUTE_ITERS: 4, MAX_ITERATIONS: Math.ceil(2000000 * xJ(e48.effort)), RIP_THRESHOLD_RAMP_ATTEMPTS: 0, STATIC_REACHABILITY_PRECHECK: true } });
if (l2.solve(), l2.failed)
this.duplicateCongestedPortError = l2.error ?? "unknown error";
else {
this.duplicateCongestedPortReport = l2.report, c2 = l2.getOutput();
for (const e49 of c2.ports) {
const t3 = fJ(e49.d);
typeof t3.duplicatedFromPortId == "string" && (delete t3._preloadedFixedNetIds, delete t3._preloadedTracePortAssignments);
}
}
this.duplicatedPortCount = this.duplicateCongestedPortReport?.duplicatedPorts.reduce((e49, t3) => e49 + t3.duplicatePortIds.length, 0) ?? 0;
const h2 = ((e49, t3, n3, o3 = true, i3) => {
const r3 = e49.connections?.length ?? 0, s3 = i3 ?? r3, a3 = yJ.PARTIAL_RIP_MIN_ROUTE_COUNT, c3 = yJ.PARTIAL_RIP_MAX_ROUTE_COUNT, l3 = o3 && s3 >= a3 && s3 <= c3;
return { serializedHyperGraph: e49, createSectionMask: ({ topology: e50 }) => new Int8Array(e50.portCount), solveGraphOptions: { ...IJ(t3, n3), ...l3 ? { 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: false, OUTSIDE_IN_ROUTING: false } }, sectionSolverOptions: SJ(t3, n3) };
})({ ...c2, solvedRoutes: o2.solvedRoutes }, e48.effort, e48.minViaPadDiameter, !r2 || s2, a2);
this.tinyPipelineSolver = new kJ(h2, e48.flags.USE_SELECTIVE_RERIP_ROUTING === true), this.primaryTinyPipelineSolver = this.tinyPipelineSolver, n2.length >= 30 && n2.length <= 99 && (this.alternativeTinyPipelineInput = { ...h2, solveGraphOptions: { ...h2.solveGraphOptions, TRACE_DENSITY_COST_FACTOR: 1 } }), this.MAX_ITERATIONS = CJ(h2) * (this.alternativeTinyPipelineInput ? 2 : 1), this.originalRegionById = new Map(e48.graph.regions.map((e49) => [e49.regionId, e49])), this.originalRegionIds = new Set(this.originalRegionById.keys()), this.inputNodeWithPortPoints = ((e49, t3) => {
const n3 = new Map(t3.regions.map((e50) => [e50.regionId, e50])), o3 = new Map(t3.ports.map((e50) => [e50.portId, e50]));
return e49.graph.regions.map((e50) => {
const t4 = n3.get(e50.regionId), i3 = (t4?.pointIds ?? e50.ports.map((e51) => e51.d.portId)).map((e51) => o3.get(e51)).filter((e51) => e51 && !fJ(e51.d)._tinyTerminal).map((e51) => {
const t5 = e51, o4 = fJ(t5.d), i4 = n3.get(t5.region1Id), r3 = n3.get(t5.region2Id), s3 = Boolean(gJ(i4?.d)._offBoardConnectionId ?? gJ(r3?.d)._offBoardConnectionId);
return { portPointId: t5.portId, x: Number(o4.x ?? 0), y: Number(o4.y ?? 0), z: Number(o4.z ?? 0), prevPortPointId: typeof o4.prevPortPointId == "string" ? o4.prevPortPointId : undefined, nextPortPointId: typeof o4.nextPortPointId == "string" ? o4.nextPortPointId : undefined, connectionNodeIds: [t5.region1Id, t5.region2Id], distToCentermostPortOnZ: Number(o4.distToCentermostPortOnZ ?? 0), cramped: Boolean(o4.cramped), connectsToOffBoardNode: s3 };
});
return { capacityMeshNodeId: e50.d.capacityMeshNodeId, center: e50.d.center, width: e50.d.width, height: e50.d.height, portPoints: i3, availableZ: e50.d.availableZ, _containsObstacle: e50.d._containsObstacle, _containsTarget: e50.d._containsTarget, _offBoardConnectionId: e50.d._offBoardConnectionId, _offBoardConnectedCapacityMeshNodeIds: e50.d._offBoardConnectedCapacityMeshNodeIds, _qfpRegionType: e50.d._qfpRegionType, _isNarrowQfpPadGap: e50.d._isNarrowQfpPadGap };
});
})(e48, c2), Object.defineProperty(this, "stats", { configurable: true, enumerable: true, get: () => this.getStatsSnapshot(), set: (e49) => {
this.statsSnapshot = e49, this.statsSnapshotDirty = false;
} });
}
params;
tinyPipelineSolver;
primaryTinyPipelineSolver;
alternativeTinyPipelineSolver;
alternativeTinyPipelineInput;
candidatePortfolioPhase = "primary";
primaryCandidateSummary;
alternativeCandidateSummary;
alternativeCandidateEvaluated = false;
selectedCandidate = "primary";
duplicateCongestedPortReport;
duplicateCongestedPortError;
duplicatedPortCount = 0;
inputNodeWithPortPoints;
originalRegionById;
originalRegionIds;
rootConnectionNameByConnectionId;
originalPreloadedSegmentKeysByConnectionId;
statsSnapshot = {};
statsSnapshotDirty = false;
getSolverName() {
return "TinyHypergraphPortPointPathingSolver";
}
getChangedPreloadedRouteIds(e48) {
const t2 = new Map, n2 = new Map;
for (let o3 = 0;o3 < e48.problem.routeCount; o3++) {
const i2 = this.getRouteMetadata(e48, o3);
cJ(i2) && (t2.set(i2.connectionId, o3), n2.set(o3, new Set));
}
for (let t3 = 0;t3 < e48.state.regionSegments.length; t3++) {
const o3 = e48.topology.regionMetadata?.[t3]?.serializedRegionId;
for (const [i2, r2, s2] of e48.state.regionSegments[t3] ?? []) {
const t4 = n2.get(i2);
if (!t4)
continue;
const a2 = e48.topology.portMetadata?.[r2]?.serializedPortId, c2 = e48.topology.portMetadata?.[s2]?.serializedPortId;
if (typeof o3 != "string" || typeof a2 != "string" || typeof c2 != "string")
throw new Error(`Tiny hypergraph preloaded route ${i2} has a segment without serialized topology IDs`);
const [l2, h2] = [a2, c2].sort();
t4.add(JSON.stringify([o3, l2, h2]));
}
}
const o2 = new Set;
for (const [e49, i2] of this.originalPreloadedSegmentKeysByConnectionId) {
const r2 = t2.get(e49);
if (r2 === undefined)
throw new Error(`Tiny hypergraph lost preloaded trace section "${e49}"`);
const s2 = n2.get(r2);
if (i2.size > 0 && s2.size === 0)
throw new Error(`Tiny hypergraph lost preloaded trace section "${e49}"`);
(i2.size !== s2.size || [...i2].some((e50) => !s2.has(e50))) && o2.add(r2);
}
return o2;
}
summarizePipelineCandidate(e48) {
const t2 = e48.getSolvedTinySolver();
let n2 = 0, o2 = 0, i2 = 0, r2 = 0, s2 = 0, a2 = 0;
const c2 = t2.topology.regionMetadata ?? [];
for (let e49 = 0;e49 < t2.state.regionSegments.length; e49++) {
const l2 = t2.state.regionSegments[e49];
s2 += l2.length;
for (const [, e50, n3] of l2)
t2.topology.portZ[e50] !== t2.topology.portZ[n3] && (a2 += 1);
const h2 = c2[e49]?.capacityMeshNodeId;
if (!h2 || !this.originalRegionIds.has(h2))
continue;
const d2 = this.originalRegionById.get(h2);
if (!d2 || l2.length === 0)
continue;
const u2 = l2.map(([e50, n3, o3]) => [this.createAssignedPortPoint(t2, e50, n3), this.createAssignedPortPoint(t2, e50, o3)]), p2 = { capacityMeshNodeId: d2.d.capacityMeshNodeId, center: d2.d.center, width: d2.d.width, height: d2.d.height, portPoints: u2.flat(), availableZ: d2.d.availableZ }, m2 = jL(p2), g2 = nz(d2.d, m2.numSameLayerCrossings, m2.numEntryExitLayerChanges, m2.numTransitionPairCrossings);
n2 += g2, o2 += g2 * g2, i2 = Math.max(i2, g2), r2 += p2.portPoints.length ** 2;
}
return { nodePfSum: n2, nodePfSquaredSum: o2, nodePfMax: i2, squaredNodePortPointCount: r2, segmentCount: s2, layerChangeCount: a2, changedPreloadedTraceSectionCount: this.getChangedPreloadedRouteIds(t2).size };
}
shouldEvaluateAlternative(e48) {
const t2 = this.primaryTinyPipelineSolver.getSolvedTinySolver().problem.routeCount;
return this.alternativeTinyPipelineInput !== undefined && ((e49, t3) => e49.nodePfSum > 4 && e49.nodePfMax > 1 && e49.squaredNodePortPointCount / Math.max(1, t3) >= 125)(e48, t2);
}
shouldSelectAlternative(e48, t2) {
return ((e49, t3, n2) => {
if (t3.changedPreloadedTraceSectionCount > e49.changedPreloadedTraceSectionCount)
return false;
const o2 = n2 > 40 ? 0.92 : 0.95, i2 = t3.nodePfSum <= 0.9 * e49.nodePfSum && t3.nodePfSquaredSum <= 0.85 * e49.nodePfSquaredSum && t3.nodePfMax <= 0.85 * e49.nodePfMax && t3.squaredNodePortPointCount < 0.98 * e49.squaredNodePortPointCount && t3.segmentCount <= 0.97 * e49.segmentCount;
return t3.nodePfSum <= 1.03 * e49.nodePfSum && t3.nodePfSquaredSum <= 1.06 * e49.nodePfSquaredSum && (t3.squaredNodePortPointCount < e49.squaredNodePortPointCount * o2 || i2);
})(e48, t2, 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 e48 = this.tinyPipelineSolver.getSolver("solveGraph");
if (!e48)
return;
const t2 = e48.state.regionSegments.map((e49) => e49.length), n2 = this.selectedCandidate === "alternative" ? this.alternativeCandidateSummary : this.primaryCandidateSummary, o2 = e48.stats, i2 = this.tinyPipelineSolver.getStageStats().solveGraph;
return { routeCount: e48.problem.routeCount, traceDensityCandidateEvaluated: this.alternativeCandidateEvaluated, traceDensityCandidateSelected: this.selectedCandidate === "alternative", downstreamNodePfSum: n2?.nodePfSum, downstreamNodePfSquaredSum: n2?.nodePfSquaredSum, downstreamNodePfMax: n2?.nodePfMax, downstreamSquaredNodePortPointCount: n2?.squaredNodePortPointCount, changedPreloadedTraceSectionCount: n2?.changedPreloadedTraceSectionCount, iterations: e48.iterations, timeMs: i2?.timeSpent, ripCount: o2.ripCount, partialRipCount: o2.partialRipCount, partiallyRippedRouteCount: o2.partiallyRippedRouteCount, partiallyRippedSegmentCount: o2.partiallyRippedSegmentCount, retainedPartialRipSegmentCount: o2.retainedPartialRipSegmentCount, firstMaxRegionCost: o2.firstMaxRegionCost, bestMaxRegionCost: o2.bestMaxRegionCost, firstTotalRegionCost: o2.firstTotalRegionCost, bestTotalRegionCost: o2.bestTotalRegionCost, firstSegmentCount: o2.firstSegmentCount, bestSolvedSegmentCount: o2.bestSolvedSegmentCount, bestSolvedMaxRegionSegmentCount: o2.bestSolvedMaxRegionSegmentCount, bestSolvedSquaredRegionSegmentCount: o2.bestSolvedSquaredRegionSegmentCount, finalMaxRegionSegmentCount: Math.max(0, ...t2), finalSquaredRegionSegmentCount: t2.reduce((e49, t3) => e49 + t3 * t3, 0), finalSegmentCount: n2?.segmentCount, finalLayerChangeCount: n2?.layerChangeCount, warmupFullRipAttempts: o2.partialRipWarmupFullRipAttempts, complexityAwareSelection: o2.partialRipComplexityAwareSelection, targetReached: o2.partialRipTargetReached, outsideInCompletedRouteCount: o2.outsideInCompletedRouteCount, outsideInFallbackRouteCount: o2.outsideInFallbackRouteCount, outsideInForwardExpansionCount: o2.outsideInForwardExpansionCount, outsideInReverseExpansionCount: o2.outsideInReverseExpansionCount };
}
_step() {
this.tinyPipelineSolver.step(), this.candidatePortfolioPhase === "primary" && this.primaryTinyPipelineSolver.failed ? (this.alternativeTinyPipelineInput = undefined, this.finishCandidatePortfolio()) : this.candidatePortfolioPhase === "primary" && this.primaryTinyPipelineSolver.solved ? (this.primaryCandidateSummary = this.summarizePipelineCandidate(this.primaryTinyPipelineSolver), this.shouldEvaluateAlternative(this.primaryCandidateSummary) ? (this.alternativeCandidateEvaluated = true, this.alternativeTinyPipelineSolver = new kJ(this.alternativeTinyPipelineInput, this.params.flags.USE_SELECTIVE_RERIP_ROUTING === true), this.tinyPipelineSolver = this.alternativeTinyPipelineSolver, this.candidatePortfolioPhase = "alternative") : (this.alternativeTinyPipelineInput = undefined, this.finishCandidatePortfolio())) : this.candidatePortfolioPhase === "alternative" && (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 = undefined, this.alternativeTinyPipelineSolver = undefined) : (this.tinyPipelineSolver = this.primaryTinyPipelineSolver, this.alternativeTinyPipelineSolver = undefined), this.alternativeTinyPipelineInput = undefined, this.finishCandidatePortfolio()), this.solved = this.candidatePortfolioPhase === "complete" && this.tinyPipelineSolver.solved, this.failed = this.candidatePortfolioPhase === "complete" && this.tinyPipelineSolver.failed, this.error = this.failed ? this.tinyPipelineSolver.error ?? null : null, this.progress = this.candidatePortfolioPhase === "complete" ? 1 : this.candidatePortfolioPhase === "alternative" ? 0.5 + 0.5 * this.tinyPipelineSolver.progress : this.alternativeTinyPipelineInput ? 0.5 * this.tinyPipelineSolver.progress : this.tinyPipelineSolver.progress, this.statsSnapshotDirty = true, this.activeSubSolver = this.tinyPipelineSolver.activeSubSolver ?? null;
}
getStatsSnapshot() {
if (!this.statsSnapshotDirty)
return this.statsSnapshot;
const e48 = this.tinyPipelineSolver.getSolver("optimizeSection"), t2 = this.getCurrentTinySolver();
return this.statsSnapshot = { duplicateCongestedPortSourceCount: this.duplicateCongestedPortReport?.duplicatedPorts.length ?? 0, duplicateCongestedPortCount: this.duplicatedPortCount, 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 ?? {}, ...t2?.stats ?? {}, ...e48?.stats ?? {}, currentStage: this.tinyPipelineSolver.getCurrentStageName(), stageStats: this.tinyPipelineSolver.getStageStats() }, this.statsSnapshotDirty = false, this.statsSnapshot;
}
preview() {
return this.visualize();
}
getCurrentTinySolver() {
const e48 = this.tinyPipelineSolver.getSolver("optimizeSection");
if (e48?.solved && !e48.failed)
return e48.getSolvedSolver();
const t2 = this.tinyPipelineSolver.getSolver("solveGraph");
return t2 || undefined;
}
getSolvedTinySolver() {
return this.tinyPipelineSolver.getSolvedTinySolver();
}
getRouteMetadata(e48, t2) {
return e48.problem.routeMetadata?.[t2];
}
createAssignedPortPoint(e48, t2, n2) {
const o2 = this.getRouteMetadata(e48, t2), i2 = o2 ? ((e49) => e49.simpleRouteConnection?.name ?? e49.connectionId)(o2) : `route-${t2}`, r2 = o2 ? this.rootConnectionNameByConnectionId.get(o2.connectionId) ?? o2.mutuallyConnectedNetworkId : undefined, s2 = e48.topology.portMetadata?.[n2];
return { portPointId: String(s2?.serializedPortId ?? s2?.portId ?? `tiny-port-${n2}`), x: e48.topology.portX[n2], y: e48.topology.portY[n2], z: e48.topology.portZ[n2], connectionName: i2, rootConnectionName: r2, ...this.params.preserveTerminalPcbPortIds && typeof s2?.pcb_port_id == "string" ? { pcb_port_id: s2.pcb_port_id } : {}, prevPortPointId: typeof s2?.prevPortPointId == "string" ? s2.prevPortPointId : undefined, nextPortPointId: typeof s2?.nextPortPointId == "string" ? s2.nextPortPointId : undefined };
}
getOutput() {
const e48 = this.getSolvedTinySolver(), t2 = [], n2 = e48.state.regionSegments, o2 = e48.topology.regionMetadata ?? [], i2 = this.getChangedPreloadedRouteIds(e48);
for (let r3 = 0;r3 < n2.length; r3++) {
const s2 = o2[r3]?.capacityMeshNodeId;
if (!s2 || !this.originalRegionIds.has(s2))
continue;
const a2 = this.originalRegionById.get(s2);
if (!a2)
continue;
const c2 = n2[r3].filter(([t3]) => {
const n3 = this.getRouteMetadata(e48, t3);
return !cJ(n3) || i2.has(t3);
}).map(([t3, n3, o3]) => {
const i3 = this.createAssignedPortPoint(e48, t3, n3), r4 = this.createAssignedPortPoint(e48, t3, o3);
return i3.portPointId && r4.portPointId && (i3.nextPortPointId = r4.portPointId, r4.prevPortPointId = i3.portPointId), [i3, r4];
}), l2 = c2.flat();
l2.length !== 0 && t2.push({ capacityMeshNodeId: a2.d.capacityMeshNodeId, center: a2.d.center, width: a2.d.width, height: a2.d.height, portPoints: l2, portPointsInPairs: c2, availableZ: a2.d.availableZ });
}
const r2 = [...i2].map((t3) => {
const n3 = this.getRouteMetadata(e48, t3);
if (!cJ(n3))
throw new Error(`Changed preloaded hypergraph route ${t3} is missing section metadata`);
const o3 = n3.preloadedTraceSection;
return { connectionName: n3.connectionId, traceId: o3.traceId, startRoutePosition: o3.startRoutePosition, endRoutePosition: o3.endRoutePosition, connection: { name: n3.connectionId, __rootConnectionNames: [n3.mutuallyConnectedNetworkId], pointsToConnect: [{ x: o3.startPoint.x, y: o3.startPoint.y, layer: Po(o3.startPoint.z, this.params.layerCount) }, { x: o3.endPoint.x, y: o3.endPoint.y, layer: Po(o3.endPoint.z, this.params.layerCount) }] } };
});
return this.stats.changedPreloadedTraceSectionCount = r2.length, { nodesWithPortPoints: t2, inputNodeWithPortPoints: this.inputNodeWithPortPoints, changedPreloadedTraceSections: r2 };
}
computeNodePf(e48) {
const t2 = this.getOutput().nodesWithPortPoints.find((t3) => t3.capacityMeshNodeId === e48.capacityMeshNodeId);
return this.computeSolvedNodePf(e48.capacityMeshNodeId, t2);
}
computeNodePfMap() {
const e48 = new Map(this.getOutput().nodesWithPortPoints.map((e49) => [e49.capacityMeshNodeId, e49]));
return new Map(this.inputNodeWithPortPoints.map((t2) => [t2.capacityMeshNodeId, this.computeSolvedNodePf(t2.capacityMeshNodeId, e48.get(t2.capacityMeshNodeId))]));
}
computeSolvedNodePf(e48, t2) {
const n2 = this.originalRegionById.get(e48);
if (!t2 || !n2)
return null;
const o2 = jL(t2);
return nz(n2.d, o2.numSameLayerCrossings, o2.numEntryExitLayerChanges, o2.numTransitionPairCrossings);
}
tryFinalAcceptance() {}
getConstructorParams() {
return [this.params];
}
visualize() {
return this.tinyPipelineSolver.visualize();
}
};
var LJ = (e48, t2) => {
if (!e48 || e48 === "none")
return e48;
try {
const n2 = fe(e48);
return `rgba(${n2.red},${n2.green},${n2.blue},${t2})`;
} catch {
return Oo(e48, 1 - t2);
}
};
var zJ = ({ srj: e48, opacity: t2 = 0.25, visualizationOptions: n2 = {} }) => {
const o2 = Go({ ...e48, obstacles: [] }, n2);
return { ...o2, points: [], lines: o2.lines?.map((e49) => ({ ...e49, strokeColor: LJ(e49.strokeColor, t2) })), rects: o2.rects?.map((e49) => ({ ...e49, fill: LJ(e49.fill, t2), stroke: LJ(e49.stroke, t2) })), circles: o2.circles?.map((e49) => ({ ...e49, fill: LJ(e49.fill, t2), stroke: LJ(e49.stroke, t2) })) };
};
function BJ(e48, t2, n2, o2) {
if (_t(e48, t2, n2, o2))
return 0;
const i2 = FJ(e48, n2, o2), r2 = FJ(t2, n2, o2), s2 = FJ(n2, e48, t2), a2 = FJ(o2, e48, t2);
return Math.min(i2, r2, s2, a2);
}
function FJ(e48, t2, n2) {
const o2 = { x: n2.x - t2.x, y: n2.y - t2.y }, i2 = jJ({ x: e48.x - t2.x, y: e48.y - t2.y }, o2);
if (i2 <= 0)
return $J(e48, t2);
const r2 = jJ(o2, o2);
if (r2 <= i2)
return $J(e48, n2);
const s2 = i2 / r2;
return $J(e48, { x: t2.x + s2 * o2.x, y: t2.y + s2 * o2.y });
}
function jJ(e48, t2) {
return e48.x * t2.x + e48.y * t2.y;
}
function $J(e48, t2) {
const n2 = t2.x - e48.x, o2 = t2.y - e48.y;
return Math.sqrt(n2 * n2 + o2 * o2);
}
function YJ(e48, t2) {
return e48.x >= t2.center.x - t2.width / 2 && e48.x <= t2.center.x + t2.width / 2 && e48.y >= t2.center.y - t2.height / 2 && e48.y <= t2.center.y + t2.height / 2;
}
var XJ = 0.000001;
var WJ = (e48, t2, n2) => xt(e48, t2, n2) <= XJ;
var VJ = (e48, t2) => Math.abs(e48.x - t2.x) <= XJ && Math.abs(e48.y - t2.y) <= XJ;
var HJ = (e48, t2) => {
if (!t2 || t2.length < 3)
return false;
for (let n3 = 0;n3 < t2.length; n3++) {
const o2 = t2[n3], i2 = t2[(n3 + 1) % t2.length];
if (WJ(e48, o2, i2))
return true;
}
let n2 = false;
for (let o2 = 0, i2 = t2.length - 1;o2 < t2.length; i2 = o2++) {
const r2 = t2[o2], s2 = t2[i2];
r2.y > e48.y != s2.y > e48.y && e48.x < (s2.x - r2.x) * (e48.y - r2.y) / (s2.y - r2.y) + r2.x && (n2 = !n2);
}
return n2;
};
var GJ = "escape-via:";
var UJ = 0.0001;
var ZJ = (e48) => e48.obstacleId ?? [e48.layers.join("."), e48.center.x.toFixed(4), e48.center.y.toFixed(4), e48.width.toFixed(4), e48.height.toFixed(4)].join(":");
var qJ = (e48, t2, n2 = 0.0001) => vt(e48, t2) <= n2;
var JJ = class extends ai {
constructor(e48, t2 = {}) {
super(), this.ogSrj = e48, this.viaDiameter = t2.viaDiameter ?? Xo(e48).padDiameter, this.viaRadius = this.viaDiameter / 2, this.minTraceWidth = t2.minTraceWidth ?? e48.minTraceWidth, this.obstacleMargin = t2.obstacleMargin ?? e48.defaultObstacleMargin ?? 0.15, this.requiredViaToPadClearance = Math.max(this.obstacleMargin, e48.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 = e48, this.escapeViaMetadataByPointId = new Map, this.createdEscapeVias = [];
}
ogSrj;
getSolverName() {
return "EscapeViaLocationSolver";
}
viaDiameter;
viaRadius;
minTraceWidth;
obstacleMargin;
escapeOffset;
requiredTraceClearance;
requiredViaToPadClearance;
requiredViaToViaClearance;
outputSrj;
escapeViaMetadataByPointId;
createdEscapeVias;
nextEscapeViaIndex = 0;
getConnectionNetIds(e48) {
return new Set([e48.name, ...e48.__rootConnectionNames ?? [], e48.__netConnectionName].filter((e49) => Boolean(e49)));
}
obstacleMatchesConnectionNet(e48, t2) {
return e48.connectedTo.some((e49) => t2.has(e49));
}
getObstacleZs(e48) {
return e48.__zLayers && e48.__zLayers.length > 0 ? e48.__zLayers : e48.layers.map((e49) => go(e49, this.ogSrj.layerCount));
}
getViaSpanLayers(e48, t2) {
const n2 = go(e48, this.ogSrj.layerCount), o2 = go(t2, this.ogSrj.layerCount), i2 = Math.min(n2, o2), r2 = Math.max(n2, o2), s2 = Array.from({ length: r2 - i2 + 1 }, (e49, t3) => i2 + t3);
return { __zLayers: s2, layers: s2.map((e49) => Po(e49, this.ogSrj.layerCount)) };
}
createEscapeViaObstacle(e48) {
const { escapeVia: t2, connectionNetIds: n2 } = e48, { layers: o2, __zLayers: i2 } = this.getViaSpanLayers(t2.sourceLayer, t2.targetLayer);
return { obstacleId: `escape-via-obstacle:${t2.pointId}`, type: "rect", layers: o2, __zLayers: i2, center: { x: t2.x, y: t2.y }, width: this.viaDiameter, height: this.viaDiameter, connectedTo: Array.from(n2) };
}
selectSourceObstacle(e48) {
const { point: t2, sourceLayer: n2, connectionNetIds: o2 } = e48;
return this.ogSrj.obstacles.filter((e49) => !e49.isCopperPour && e49.layers.includes(n2) && YJ(t2, e49)).sort((e49, n3) => {
const i2 = e49.connectedTo.includes(t2.pointId ?? "") || e49.connectedTo.includes(t2.pcb_port_id ?? "") || this.obstacleMatchesConnectionNet(e49, o2);
return i2 !== (n3.connectedTo.includes(t2.pointId ?? "") || n3.connectedTo.includes(t2.pcb_port_id ?? "") || this.obstacleMatchesConnectionNet(n3, o2)) ? i2 ? -1 : 1 : e49.width * e49.height - n3.width * n3.height;
})[0];
}
getCandidatePositions(e48, t2) {
if (!t2)
return this.dedupeCandidatePositions([{ x: e48.x + this.escapeOffset, y: e48.y }, { x: e48.x - this.escapeOffset, y: e48.y }, { x: e48.x, y: e48.y + this.escapeOffset }, { x: e48.x, y: e48.y - this.escapeOffset }, { x: e48.x + this.escapeOffset, y: e48.y + this.escapeOffset }, { x: e48.x + this.escapeOffset, y: e48.y - this.escapeOffset }, { x: e48.x - this.escapeOffset, y: e48.y + this.escapeOffset }, { x: e48.x - this.escapeOffset, y: e48.y - this.escapeOffset }]);
const n2 = t2.center.x - t2.width / 2, o2 = t2.center.x + t2.width / 2, i2 = t2.center.y - t2.height / 2, r2 = t2.center.y + t2.height / 2, s2 = n2 - this.escapeOffset, a2 = o2 + this.escapeOffset, c2 = i2 - this.escapeOffset, l2 = r2 + this.escapeOffset, h2 = this.getEdgeSamples(i2, r2, e48.y), d2 = this.getEdgeSamples(n2, o2, e48.x), u2 = [];
for (const e49 of h2)
u2.push({ x: s2, y: e49 }, { x: a2, y: e49 });
for (const e49 of d2)
u2.push({ x: e49, y: c2 }, { x: e49, y: l2 });
return this.dedupeCandidatePositions(u2);
}
dedupeCandidatePositions(e48) {
const t2 = [];
for (const n2 of e48)
t2.some((e49) => qJ(e49, n2)) || t2.push(n2);
return t2;
}
pushEdgeSample(e48, t2, n2, o2) {
const i2 = Math.max(n2, Math.min(o2, t2));
e48.some((e49) => Math.abs(e49 - i2) <= UJ) || e48.push(i2);
}
getEdgeSamples(e48, t2, n2) {
const o2 = [], i2 = t2 - e48;
if (this.pushEdgeSample(o2, n2, e48, t2), i2 <= UJ)
return o2;
this.pushEdgeSample(o2, e48, e48, t2), this.pushEdgeSample(o2, t2, e48, t2), this.pushEdgeSample(o2, (e48 + t2) / 2, e48, t2);
const r2 = Math.max(e48, Math.min(t2, n2)), s2 = Math.max(this.requiredViaToViaClearance, UJ), a2 = Math.ceil(i2 / s2);
for (let n3 = 1;n3 <= a2; n3++) {
const i3 = n3 * s2;
this.pushEdgeSample(o2, r2 + i3, e48, t2), this.pushEdgeSample(o2, r2 - i3, e48, t2);
}
return o2;
}
isInsideBoard(e48) {
return !!(e48.x >= this.ogSrj.bounds.minX + this.viaRadius && e48.x <= this.ogSrj.bounds.maxX - this.viaRadius && e48.y >= this.ogSrj.bounds.minY + this.viaRadius && e48.y <= this.ogSrj.bounds.maxY - this.viaRadius) && (!(this.ogSrj.outline && this.ogSrj.outline.length >= 3) || HJ(e48, this.ogSrj.outline));
}
hasClearEscapePath(e48) {
const { sourcePoint: t2, candidate: n2, sourceLayer: o2, sourceObstacle: i2 } = e48;
if (this.ogSrj.outline && this.ogSrj.outline.length >= 3) {
if ((({ start: e49, end: t3, polygon: n3, margin: o3 = 0.2 }) => {
if (!n3 || n3.length < 3)
return false;
const i3 = HJ(e49, n3), r2 = HJ(t3, n3);
if (!i3 || !r2)
return true;
for (let i4 = 0;i4 < n3.length; i4++) {
const r3 = n3[i4], s2 = n3[(i4 + 1) % n3.length], a2 = WJ(e49, r3, s2), c2 = WJ(t3, r3, s2);
if (a2 && c2)
continue;
if (!_t(e49, t3, r3, s2)) {
if (!a2 && !c2 && BJ(e49, t3, r3, s2) < o3 - XJ)
return true;
continue;
}
const l2 = It(e49, t3, r3, s2);
if (!(l2 && (a2 && VJ(l2, e49) || c2 && VJ(l2, t3)) || l2 && (VJ(l2, e49) || VJ(l2, t3))))
return true;
}
return false;
})({ start: t2, end: n2, polygon: this.ogSrj.outline, margin: this.requiredTraceClearance }))
return false;
}
for (const e49 of this.ogSrj.obstacles) {
if (e49 === i2)
continue;
if (!e49.layers.includes(o2))
continue;
if (YJ(n2, e49))
return false;
const r2 = nj(e49);
if (Math.min(...r2.map((e50) => BJ(t2, n2, e50.start, e50.end))) + UJ < this.requiredTraceClearance)
return false;
}
return true;
}
getBoardBoundarySegments() {
if (this.ogSrj.outline && this.ogSrj.outline.length >= 3)
return this.ogSrj.outline.map((e49, t3) => ({ start: e49, end: this.ogSrj.outline[(t3 + 1) % this.ogSrj.outline.length] }));
const { minX: e48, maxX: t2, minY: n2, maxY: o2 } = this.ogSrj.bounds;
return [{ start: { x: e48, y: n2 }, end: { x: t2, y: n2 } }, { start: { x: t2, y: n2 }, end: { x: t2, y: o2 } }, { start: { x: t2, y: o2 }, end: { x: e48, y: o2 } }, { start: { x: e48, y: o2 }, end: { x: e48, y: n2 } }];
}
getRayProbeDistance() {
const { minX: e48, maxX: t2, minY: n2, maxY: o2 } = this.ogSrj.bounds;
return 2 * Math.hypot(t2 - e48, o2 - n2) + this.viaDiameter;
}
getRayIntersectionDistance(e48) {
const { rayStart: t2, rayEnd: n2, segmentStart: o2, segmentEnd: i2 } = e48;
if (!_t(t2, n2, o2, i2))
return null;
const r2 = It(t2, n2, o2, i2);
if (!r2)
return null;
const s2 = vt(t2, r2);
return s2 <= UJ ? null : s2;
}
getProjectedFreeSpace(e48) {
const { sourcePoint: t2, candidate: n2 } = e48, o2 = n2.x - t2.x, i2 = n2.y - t2.y;
return Math.abs(o2) <= UJ || Math.abs(i2) <= UJ ? this.getProjectedFreeSpaceAlongDirection({ ...e48, direction: { x: o2, y: i2 }, travelDistance: vt(t2, n2) }) : Math.min(this.getProjectedFreeSpaceAlongDirection({ ...e48, direction: { x: 0, y: Math.sign(i2) }, travelDistance: Math.abs(i2) }), this.getProjectedFreeSpaceAlongDirection({ ...e48, direction: { x: Math.sign(o2), y: Math.sign(i2) }, travelDistance: vt(t2, n2) }), this.getProjectedFreeSpaceAlongDirection({ ...e48, direction: { x: Math.sign(o2), y: 0 }, travelDistance: Math.abs(o2) }));
}
getProjectedFreeSpaceAlongDirection(e48) {
const { sourcePoint: t2, sourceLayer: n2, sourceObstacle: o2, direction: i2, travelDistance: r2 } = e48, s2 = Math.hypot(i2.x, i2.y);
if (s2 <= UJ || r2 <= UJ)
return 0;
const a2 = this.getRayProbeDistance(), c2 = i2.x / s2, l2 = i2.y / s2, h2 = { x: t2.x + c2 * a2, y: t2.y + l2 * a2 };
let d2 = Number.POSITIVE_INFINITY;
for (const e49 of this.ogSrj.obstacles)
if (e49 !== o2 && e49.layers.includes(n2))
for (const n3 of nj(e49)) {
const e50 = this.getRayIntersectionDistance({ rayStart: t2, rayEnd: h2, segmentStart: n3.start, segmentEnd: n3.end });
e50 !== null && (d2 = Math.min(d2, e50));
}
for (const e49 of this.getBoardBoundarySegments()) {
const n3 = this.getRayIntersectionDistance({ rayStart: t2, rayEnd: h2, segmentStart: e49.start, segmentEnd: e49.end });
n3 !== null && (d2 = Math.min(d2, n3));
}
return Number.isFinite(d2) ? Math.max(0, d2 - r2) : 0;
}
getMinBlockingClearance(e48) {
const { candidate: t2, connectionNetIds: n2, sourceZ: o2, targetZ: i2 } = e48, r2 = Math.min(o2, i2), s2 = Math.max(o2, i2);
let a2 = Number.POSITIVE_INFINITY;
for (const e49 of this.ogSrj.obstacles) {
const n3 = this.getObstacleZs(e49);
if (!n3.some((e50) => e50 >= r2 && e50 <= s2))
continue;
if (e49.isCopperPour && !n3.includes(o2))
continue;
const i3 = jt(t2, e49) - this.viaRadius;
if (a2 = Math.min(a2, i3), a2 + UJ < this.requiredViaToPadClearance)
return a2;
}
return a2;
}
getMinPlacedEscapeViaClearance(e48) {
let t2 = Number.POSITIVE_INFINITY;
for (const n2 of this.createdEscapeVias) {
const o2 = vt(e48, n2) - this.viaDiameter;
if (t2 = Math.min(t2, o2), t2 + UJ < this.obstacleMargin)
return t2;
}
return t2;
}
selectPointOwner(e48) {
const { point: t2, groupConnections: n2, matchingCopperPours: o2 } = e48, i2 = Mz(t2), r2 = n2.map((e49) => ({ connection: e49, pointIndex: e49.pointsToConnect.findIndex((e50) => Mz(e50) === i2) })).filter((e49) => e49.pointIndex !== -1);
return r2.length === 0 ? null : (r2.sort((e49, t3) => {
const n3 = o2.some((t4) => this.obstacleMatchesConnectionNet(t4, this.getConnectionNetIds(e49.connection)));
return n3 !== o2.some((e50) => this.obstacleMatchesConnectionNet(e50, this.getConnectionNetIds(t3.connection))) ? n3 ? -1 : 1 : e49.pointIndex - t3.pointIndex;
}), r2[0]);
}
findBestEscapeViaCandidate(e48) {
const { connection: t2, point: n2, pointIndex: o2, matchingCopperPours: i2, connectionNetIds: r2, sourceObstacle: s2 } = e48;
if (!Io(n2))
return null;
const a2 = n2.layer, c2 = go(a2, this.ogSrj.layerCount), l2 = s2 ?? this.selectSourceObstacle({ point: n2, sourceLayer: a2, connectionNetIds: r2 }), h2 = this.getCandidatePositions(n2, l2);
let d2 = null;
for (const e49 of i2) {
const i3 = e49.layers[0];
if (!i3 || i3 === a2)
continue;
const s3 = go(i3, this.ogSrj.layerCount), u2 = ZJ(e49);
for (const p2 of h2) {
if (!this.isInsideBoard(p2))
continue;
if (!YJ(p2, e49))
continue;
if (!this.hasClearEscapePath({ sourcePoint: n2, candidate: p2, sourceLayer: a2, sourceObstacle: l2 }))
continue;
const h3 = this.getMinBlockingClearance({ candidate: p2, connectionNetIds: r2, sourceZ: c2, targetZ: s3 });
if (h3 + UJ < this.requiredViaToPadClearance)
continue;
const m2 = this.getMinPlacedEscapeViaClearance(p2);
if (m2 + UJ < this.obstacleMargin)
continue;
const g2 = this.getProjectedFreeSpace({ sourcePoint: n2, candidate: p2, sourceLayer: a2, sourceObstacle: l2 }), f2 = Math.min(g2, 3), _2 = 100 * h3 - vt(n2, p2) - 0.5 * Math.abs(s3 - c2) + 2 * f2 + (Number.isFinite(m2) ? 10 * Math.min(m2, this.requiredViaToViaClearance) : 0);
(!d2 || _2 > d2.score) && (d2 = { pointId: `${GJ}${t2.name}:${n2.pointId ?? `p${o2}`}:${i3}:${this.nextEscapeViaIndex++}`, x: p2.x, y: p2.y, connectionName: t2.name, rootConnectionName: t2.__rootConnectionNames?.[0] ?? t2.name, sourcePointIndex: o2, sourcePointId: n2.pointId, sourceLayer: a2, targetLayer: i3, targetPourKey: u2, score: _2 });
}
}
return d2;
}
buildPointPlacementPlans(e48) {
const { mergedConnection: t2, groupConnections: n2, matchingCopperPours: o2, connectionNetIds: i2 } = e48, r2 = [];
for (const e49 of t2.pointsToConnect) {
const t3 = this.selectPointOwner({ point: e49, groupConnections: n2, matchingCopperPours: o2 });
if (!t3)
continue;
const s2 = Io(e49) ? this.selectSourceObstacle({ point: e49, sourceLayer: e49.layer, connectionNetIds: i2 }) : undefined, a2 = Io(e49) ? this.getCandidatePositions(e49, s2).length : 0;
r2.push({ point: e49, pointOwner: t3, sourceObstacle: s2, candidateCount: a2 });
}
return r2.sort((e49, t3) => {
if (e49.candidateCount !== t3.candidateCount)
return e49.candidateCount - t3.candidateCount;
const n3 = (e49.sourceObstacle?.width ?? 0) * (e49.sourceObstacle?.height ?? 0), o3 = (t3.sourceObstacle?.width ?? 0) * (t3.sourceObstacle?.height ?? 0);
return n3 !== o3 ? n3 - o3 : e49.pointOwner.pointIndex - t3.pointOwner.pointIndex;
});
}
_step() {
const e48 = this.ogSrj.obstacles.filter((e49) => e49.isCopperPour), t2 = this.ogSrj.connections, n2 = t2.map((e49) => structuredClone(e49)), o2 = new Map(n2.map((e49) => [e49.name, e49])), i2 = structuredClone(this.ogSrj.obstacles), r2 = wz([...t2]);
for (const n3 of r2) {
const r3 = new Set(n3.__rootConnectionNames ?? [n3.name]), s2 = t2.filter((e49) => (e49.__rootConnectionNames ?? [e49.name]).some((e50) => r3.has(e50)));
if (s2.length === 0)
continue;
const a2 = new Set;
for (const e49 of s2)
for (const t3 of this.getConnectionNetIds(e49))
a2.add(t3);
const c2 = e48.filter((e49) => this.obstacleMatchesConnectionNet(e49, a2));
if (c2.length === 0)
continue;
const l2 = new Map, h2 = new Map, d2 = this.buildPointPlacementPlans({ mergedConnection: n3, groupConnections: s2, matchingCopperPours: c2, connectionNetIds: a2 });
for (const { point: e49, pointOwner: t3, sourceObstacle: n4 } of d2) {
const r4 = this.findBestEscapeViaCandidate({ connection: t3.connection, point: e49, pointIndex: t3.pointIndex, matchingCopperPours: c2, connectionNetIds: a2, sourceObstacle: n4 });
if (!r4)
continue;
const s3 = o2.get(t3.connection.name);
if (!s3)
continue;
if (s3.pointsToConnect.some((e50) => Io(e50) && e50.layer === r4.sourceLayer && qJ(e50, r4)))
continue;
s3.pointsToConnect.push({ x: r4.x, y: r4.y, layer: r4.sourceLayer, pointId: r4.pointId, terminalVia: { toLayer: r4.targetLayer, viaDiameter: this.viaDiameter } }), this.escapeViaMetadataByPointId.set(r4.pointId, r4), this.createdEscapeVias.push(r4), i2.push(this.createEscapeViaObstacle({ escapeVia: r4, connectionNetIds: this.getConnectionNetIds(t3.connection) }));
const d3 = l2.get(r4.targetPourKey);
d3 ? d3.push(r4.pointId) : l2.set(r4.targetPourKey, [r4.pointId]), h2.has(r4.targetPourKey) || h2.set(r4.targetPourKey, t3.connection.name);
}
for (const [e49, t3] of l2.entries()) {
if (t3.length <= 1)
continue;
const n4 = h2.get(e49);
if (!n4)
continue;
const i3 = o2.get(n4);
i3 && (i3.externallyConnectedPointIds = [...i3.externallyConnectedPointIds ?? [], t3]);
}
}
this.outputSrj = { ...structuredClone(this.ogSrj), connections: n2, obstacles: i2 }, this.solved = true;
}
getOutputSimpleRouteJson() {
return structuredClone(this.outputSrj);
}
getEscapeViaMetadataByPointId() {
return new Map(this.escapeViaMetadataByPointId);
}
visualize() {
return { title: "Escape Via Location Solver", points: this.outputSrj.connections.flatMap((e48) => e48.pointsToConnect.map((t2) => ({ x: t2.x, y: t2.y, color: t2.pointId?.startsWith(GJ) === true ? "#0f766e" : "#dc2626", label: t2.pointId?.startsWith(GJ) === true ? `${e48.name}
escape via` : e48.name }))), lines: this.createdEscapeVias.map((e48) => {
const t2 = this.outputSrj.connections.find((t3) => t3.name === e48.connectionName)?.pointsToConnect[e48.sourcePointIndex] ?? null;
return { points: t2 ? [{ x: t2.x, y: t2.y }, { x: e48.x, y: e48.y }] : [{ x: e48.x, y: e48.y }], strokeColor: "#0f766e" };
}), circles: this.createdEscapeVias.map((e48) => ({ center: { x: e48.x, y: e48.y }, radius: this.viaRadius, strokeColor: "#0f766e", label: `${e48.connectionName}
${e48.targetLayer}` })), rects: this.outputSrj.obstacles.filter((e48) => !e48.isCopperPour).map((e48) => ({ ...e48, fill: "rgba(220,38,38,0.12)" })) };
}
};
var QJ = (e48) => ({ ...e48 });
var KJ = (e48) => ({ ...e48, route: e48.route?.map(QJ), vias: e48.vias?.map((e49) => ({ ...e49 })) });
var eQ = (e48) => e48.map(KJ);
var tQ = "#0000FF";
var nQ = 0.15;
var oQ = 0.000001;
var iQ = 0.1;
var rQ = ["top", "bottom", "left", "right"];
var sQ = (e48) => e48.x * e48.x + e48.y * e48.y;
var aQ = (e48, t2) => ({ x: e48.x - t2.x, y: e48.y - t2.y });
var cQ = (e48, t2, n2) => {
const o2 = aQ(n2, t2), i2 = sQ(o2);
if (i2 <= oQ)
return Math.sqrt(sQ(aQ(e48, t2)));
const r2 = (a2 = aQ(e48, t2), c2 = o2, s2 = (a2.x * c2.x + a2.y * c2.y) / i2, Math.max(0, Math.min(1, s2)));
var s2, a2, c2;
const l2 = { x: t2.x + o2.x * r2, y: t2.y + o2.y * r2 };
return Math.sqrt(sQ(aQ(e48, l2)));
};
var lQ = (e48) => e48?.z === 1 ? "bottom" : "top";
var hQ = (e48, t2, n2) => (e48.z ?? 0) === (t2.z ?? 0) && ((t2.z ?? 0) === (n2.z ?? 0) && (e48.x === t2.x && t2.x === n2.x || e48.y === t2.y && t2.y === n2.y));
var dQ = (e48, t2, n2) => {
const o2 = n2?.get(e48);
if (o2)
return o2;
const i2 = e48.route ?? [], r2 = e48.traceThickness ?? nQ;
let { POSITIVE_INFINITY: s2, POSITIVE_INFINITY: a2, NEGATIVE_INFINITY: c2, NEGATIVE_INFINITY: l2 } = Number, h2 = false;
const d2 = (e49, t3, n3) => {
s2 = Math.min(s2, e49 - n3), a2 = Math.min(a2, t3 - n3), c2 = Math.max(c2, e49 + n3), l2 = Math.max(l2, t3 + n3), h2 = true;
}, u2 = { segments: [], segmentsByLayer: { top: [], bottom: [] }, vias: (e48.vias ?? []).map((n3) => {
const o3 = (n3.diameter ?? e48.viaDiameter ?? 0.3) / 2;
return d2(n3.x, n3.y, o3), { center: { x: n3.x, y: n3.y }, radius: o3, routeIndex: t2 };
}), bounds: { minX: 0, minY: 0, maxX: 0, maxY: 0 } };
for (let e49 = 0;e49 < i2.length - 1; ) {
const n3 = i2[e49];
let o3 = e49 + 1, s3 = i2[o3];
const a3 = r2 / 2;
for (n3 && d2(n3.x, n3.y, a3), s3 && d2(s3.x, s3.y, a3);o3 < i2.length - 1; ) {
const e50 = i2[o3], t3 = i2[o3 + 1];
if (!n3 || !e50 || !t3)
break;
if (lQ(n3) !== lQ(e50))
break;
if (lQ(e50) !== lQ(t3))
break;
if (!hQ(n3, e50, t3))
break;
o3 += 1, s3 = t3, d2(t3.x, t3.y, a3);
}
if (!n3 || !s3) {
e49 += 1;
continue;
}
const c3 = lQ(n3), l3 = { start: n3, end: s3, routeIndex: t2, pointIndex: e49, endPointIndex: o3, thickness: r2, halfThickness: a3, layer: c3, minX: Math.min(n3.x, s3.x) - a3, maxX: Math.max(n3.x, s3.x) + a3, minY: Math.min(n3.y, s3.y) - a3, maxY: Math.max(n3.y, s3.y) + a3 };
u2.segments.push(l3), u2.segmentsByLayer[c3].push(l3), e49 = o3;
}
if (!h2)
for (const e49 of i2)
d2(e49.x, e49.y, r2 / 2);
return u2.bounds = h2 ? { minX: s2, minY: a2, maxX: c2, maxY: l2 } : { minX: 0, minY: 0, maxX: 0, maxY: 0 }, n2?.set(e48, u2), u2;
};
var uQ = (e48, t2, n2) => t2.x <= Math.max(e48.x, n2.x) + oQ && t2.x >= Math.min(e48.x, n2.x) - oQ && t2.y <= Math.max(e48.y, n2.y) + oQ && t2.y >= Math.min(e48.y, n2.y) - oQ;
var pQ = (e48, t2, n2) => (t2.y - e48.y) * (n2.x - t2.x) - (t2.x - e48.x) * (n2.y - t2.y);
var mQ = (e48, t2, n2, o2) => ((e49, t3, n3, o3) => {
const i2 = pQ(e49, t3, n3), r2 = pQ(e49, t3, o3), s2 = pQ(n3, o3, e49), a2 = pQ(n3, o3, t3);
return !!(Math.abs(i2) <= oQ && uQ(e49, n3, t3)) || !!(Math.abs(r2) <= oQ && uQ(e49, o3, t3)) || !!(Math.abs(s2) <= oQ && uQ(n3, e49, o3)) || !!(Math.abs(a2) <= oQ && uQ(n3, t3, o3)) || i2 > 0 != r2 > 0 && s2 > 0 != a2 > 0;
})(e48, t2, n2, o2) ? 0 : Math.min(cQ(e48, n2, o2), cQ(t2, n2, o2), cQ(n2, e48, t2), cQ(o2, e48, t2));
var gQ = (e48, t2) => Math.abs(e48.x - t2.x) <= oQ && Math.abs(e48.y - t2.y) <= oQ;
var fQ = (e48, t2) => gQ(e48.start, t2.start) || gQ(e48.start, t2.end) || gQ(e48.end, t2.start) || gQ(e48.end, t2.end);
var _Q = (e48) => {
if (!e48)
return [];
const t2 = [e48.connectionName, e48.rootConnectionName].filter((e49) => Boolean(e49));
return Array.from(new Set(t2));
};
var yQ = (e48, t2) => {
const n2 = _Q(e48), o2 = _Q(t2);
return n2.length !== 0 && o2.length !== 0 && n2.some((e49) => o2.includes(e49));
};
var bQ = (e48, t2, n2) => e48.minX - n2 <= t2.maxX && e48.maxX + n2 >= t2.minX && e48.minY - n2 <= t2.maxY && e48.maxY + n2 >= t2.minY;
var xQ = (e48, t2, n2) => {
const o2 = n2 + e48.halfThickness + t2.halfThickness - oQ;
return e48.minX - n2 <= t2.maxX && e48.maxX + n2 >= t2.minX && e48.minY - n2 <= t2.maxY && e48.maxY + n2 >= t2.minY && o2 > 0;
};
var vQ = (e48, t2, n2, o2) => {
const i2 = o2 + n2.halfThickness + t2 - oQ, r2 = e48.x - i2, s2 = e48.x + i2, a2 = e48.y - i2, c2 = e48.y + i2;
return r2 <= n2.maxX && s2 >= n2.minX && a2 <= n2.maxY && c2 >= n2.minY;
};
var IQ = (e48, t2) => {
const n2 = new WeakMap, o2 = e48.map((e49, t3) => dQ(e49, t3, n2)), i2 = [], r2 = new Set, s2 = (e49) => {
r2.has(e49.label) || (r2.add(e49.label), i2.push(e49));
};
for (let n3 = 0;n3 < o2.length; n3 += 1) {
const i3 = o2[n3];
if (i3)
for (let r3 = n3 + 1;r3 < o2.length; r3 += 1) {
const a2 = o2[r3];
if (a2 && (!yQ(e48[n3], e48[r3]) && bQ(i3.bounds, a2.bounds, t2))) {
for (const e49 of ["top", "bottom"]) {
const o3 = i3.segmentsByLayer[e49], c2 = a2.segmentsByLayer[e49];
for (const i4 of o3)
for (const o4 of c2) {
if (fQ(i4, o4))
continue;
if (!xQ(i4, o4, t2))
continue;
const a3 = t2 + (i4.thickness + o4.thickness) / 2 - oQ;
if (mQ(i4.start, i4.end, o4.start, o4.end) >= a3)
continue;
s2({ center: { x: (Math.max(i4.minX - t2, o4.minX - t2) + Math.min(i4.maxX + t2, o4.maxX + t2)) / 2, y: (Math.max(i4.minY - t2, o4.minY - t2) + Math.min(i4.maxY + t2, o4.maxY + t2)) / 2 }, label: `trace-violation:${n3}:s${i4.pointIndex}:${r3}:s${o4.pointIndex}:${e49}` });
}
}
for (const e49 of i3.segments)
for (const [o3, i4] of a2.vias.entries()) {
if (!vQ(i4.center, i4.radius, e49, t2))
continue;
const a3 = t2 + e49.halfThickness + i4.radius - oQ;
cQ(i4.center, e49.start, e49.end) >= a3 || s2({ center: i4.center, label: `trace-violation:${n3}:s${e49.pointIndex}:${r3}:v${o3}` });
}
for (const e49 of a2.segments)
for (const [o3, a3] of i3.vias.entries()) {
if (!vQ(a3.center, a3.radius, e49, t2))
continue;
const i4 = t2 + e49.halfThickness + a3.radius - oQ;
cQ(a3.center, e49.start, e49.end) >= i4 || s2({ center: a3.center, label: `trace-violation:${n3}:v${o3}:${r3}:s${e49.pointIndex}` });
}
}
}
}
return ((e49) => {
const t3 = [];
for (const n3 of e49) {
const e50 = t3.find((e51) => {
return t4 = e51.center, o3 = n3.center, Math.hypot(t4.x - o3.x, t4.y - o3.y) <= 0.28;
var t4, o3;
});
e50 ? (e50.center = { x: (e50.center.x * e50.count + n3.center.x) / (e50.count + 1), y: (e50.center.y * e50.count + n3.center.y) / (e50.count + 1) }, e50.labels.push(n3.label), e50.count += 1) : t3.push({ center: n3.center, labels: [n3.label], count: 1 });
}
return t3.map((e50, t4) => ({ center: e50.center, radius: Math.min(0.3, 0.2 + 0.035 * Math.sqrt(e50.count - 1)), stroke: "#f59e0b", fill: "rgba(245, 158, 11, 0.46)", label: e50.count === 1 ? e50.labels[0] : `trace-violations:${t4}:count-${e50.count}` }));
})(i2);
};
var SQ = new WeakMap;
var CQ = new WeakMap;
var PQ = new WeakMap;
var MQ = (e48) => {
let t2 = SQ.get(e48);
return t2 === undefined && (t2 = e48.length > 2 && e48[e48.length - 1] - e48[0] === e48.length - 1 ? `${e48[0]}..${e48[e48.length - 1]}` : e48.join(","), SQ.set(e48, t2)), t2;
};
var wQ = ({ routeIndexes: e48, layers: t2, routePointIndexes: n2 }) => `${e48[0]}:${t2[0]}:${MQ(n2[0])}:${e48[1]}:${t2[1]}:${MQ(n2[1])}`;
var NQ = (e48, t2, n2, o2, i2, r2, s2) => {
const a2 = ((e49, t3, n3, o3, i3, r3) => e49 < n3 ? `${e49}:${t3}:${MQ(i3)}:${n3}:${o3}:${MQ(r3)}` : `${n3}:${o3}:${MQ(r3)}:${e49}:${t3}:${MQ(i3)}`)(t2, n2, o2, i2, r2, s2);
e48.has(a2) || (t2 < o2 ? e48.set(a2, { routeIndexes: [t2, o2], layers: [n2, i2], routePointIndexes: [r2, s2] }) : e48.set(a2, { routeIndexes: [o2, t2], layers: [i2, n2], routePointIndexes: [s2, r2] }));
};
var TQ = (e48) => {
const t2 = CQ.get(e48);
if (t2)
return t2;
const n2 = [];
for (let t3 = e48.pointIndex;t3 <= e48.endPointIndex; t3 += 1)
n2.push(t3);
return CQ.set(e48, n2), n2;
};
var RQ = (e48, t2) => !t2 || e48.some((e49) => t2.has(e49));
var EQ = (e48, t2) => {
const n2 = PQ.get(t2);
if (n2)
return n2;
const o2 = e48.route ?? [], i2 = [];
for (let e49 = 0;e49 < o2.length; e49 += 1) {
const n3 = o2[e49];
n3 && (Math.abs(n3.x - t2.center.x) <= oQ && Math.abs(n3.y - t2.center.y) <= oQ && i2.push(e49));
}
return PQ.set(t2, i2), i2;
};
var AQ = (e48, t2, n2) => e48.minX - n2 <= t2.maxX && e48.maxX + n2 >= t2.minX && e48.minY - n2 <= t2.maxY && e48.maxY + n2 >= t2.minY;
var OQ = (e48, t2, n2) => {
const o2 = n2 + e48.halfThickness + t2.halfThickness - oQ;
return e48.minX - n2 <= t2.maxX && e48.maxX + n2 >= t2.minX && e48.minY - n2 <= t2.maxY && e48.maxY + n2 >= t2.minY && o2 > 0;
};
var kQ = (e48, t2, n2, o2) => {
const i2 = o2 + n2.halfThickness + t2 - oQ, r2 = e48.x - i2, s2 = e48.x + i2, a2 = e48.y - i2, c2 = e48.y + i2;
return r2 <= n2.maxX && s2 >= n2.minX && a2 <= n2.maxY && c2 >= n2.minY;
};
var DQ = (e48, t2, n2) => {
const o2 = n2 + e48.radius + t2.radius - oQ;
return Math.abs(e48.center.x - t2.center.x) <= o2 && Math.abs(e48.center.y - t2.center.y) <= o2;
};
var LQ = (e48, t2, n2, o2, i2) => {
const r2 = e48.map((e49, t3) => dQ(e49, t3, o2)), s2 = new Map;
if (t2.size === 0)
return [];
const a2 = Array.from(t2), c2 = new Map, l2 = (e49) => {
const t3 = c2.get(e49);
if (t3)
return t3;
const o3 = r2[e49];
if (!o3)
return [];
const i3 = [];
for (let t4 = 0;t4 < r2.length; t4 += 1) {
if (t4 === e49)
continue;
const s3 = r2[t4];
s3 && (AQ(o3.bounds, s3.bounds, n2) && i3.push(t4));
}
return c2.set(e49, i3), i3;
};
for (const e49 of a2) {
const o3 = r2[e49];
if (!o3)
continue;
const a3 = l2(e49), c3 = i2?.get(e49);
for (const l3 of o3.segments) {
const o4 = TQ(l3);
if (RQ(o4, c3))
for (const c4 of a3) {
if (e49 > c4 && t2.has(c4))
continue;
const a4 = r2[c4];
if (!a4)
continue;
const h2 = i2?.get(c4), d2 = a4.segmentsByLayer[l3.layer];
for (const e50 of d2) {
const t3 = TQ(e50);
if (!RQ(t3, h2))
continue;
if (fQ(l3, e50))
continue;
if (!OQ(l3, e50, n2))
continue;
const i3 = n2 + (l3.thickness + e50.thickness) / 2 - oQ;
mQ(l3.start, l3.end, e50.start, e50.end) < i3 && NQ(s2, l3.routeIndex, l3.layer, e50.routeIndex, e50.layer, o4, t3);
}
}
}
}
for (const o3 of a2) {
const a3 = r2[o3];
if (!a3)
continue;
const c3 = l2(o3), h2 = i2?.get(o3);
for (const l3 of a3.vias) {
const a4 = EQ(e48[l3.routeIndex], l3);
if (RQ(a4, h2))
for (const e49 of c3) {
if (o3 > e49 && t2.has(e49))
continue;
const c4 = r2[e49];
if (!c4)
continue;
const h3 = i2?.get(e49);
for (const e50 of c4.segments) {
const t3 = TQ(e50);
if (!RQ(t3, h3))
continue;
if (!kQ(l3.center, l3.radius, e50, n2))
continue;
const o4 = n2 + e50.thickness / 2 + l3.radius - oQ;
cQ(l3.center, e50.start, e50.end) < o4 && NQ(s2, e50.routeIndex, e50.layer, l3.routeIndex, "via", t3, a4);
}
}
}
}
for (const t3 of a2) {
const o3 = r2[t3];
if (!o3)
continue;
const a3 = l2(t3), c3 = i2?.get(t3);
for (const t4 of o3.segments) {
const o4 = TQ(t4);
if (RQ(o4, c3))
for (const c4 of a3) {
const a4 = r2[c4];
if (!a4)
continue;
const l3 = i2?.get(c4);
for (const i3 of a4.vias) {
const r3 = EQ(e48[i3.routeIndex], i3);
if (!RQ(r3, l3))
continue;
if (!kQ(i3.center, i3.radius, t4, n2))
continue;
const a5 = n2 + t4.thickness / 2 + i3.radius - oQ;
cQ(i3.center, t4.start, t4.end) < a5 && NQ(s2, t4.routeIndex, t4.layer, i3.routeIndex, "via", o4, r3);
}
}
}
}
for (const o3 of a2) {
const a3 = r2[o3];
if (!a3)
continue;
const c3 = l2(o3), h2 = i2?.get(o3);
for (const l3 of a3.vias) {
const a4 = EQ(e48[l3.routeIndex], l3);
if (RQ(a4, h2))
for (const h3 of c3) {
if (o3 > h3 && t2.has(h3))
continue;
const c4 = r2[h3];
if (!c4)
continue;
const d2 = i2?.get(h3);
for (const t3 of c4.vias) {
const o4 = EQ(e48[t3.routeIndex], t3);
if (!RQ(o4, d2))
continue;
if (!DQ(l3, t3, n2))
continue;
const i3 = n2 + l3.radius + t3.radius - oQ;
Math.hypot(l3.center.x - t3.center.x, l3.center.y - t3.center.y) < i3 && NQ(s2, l3.routeIndex, "via", t3.routeIndex, "via", a4, o4);
}
}
}
}
return Array.from(s2.values());
};
var zQ = (e48, t2) => e48.x >= t2.minX - oQ && e48.x <= t2.maxX + oQ && e48.y >= t2.minY - oQ && e48.y <= t2.maxY + oQ;
var BQ = (e48, t2, n2) => {
switch (t2) {
case "left":
return { minX: e48.minX, maxX: e48.minX + n2, minY: e48.minY, maxY: e48.maxY };
case "right":
return { minX: e48.maxX - n2, maxX: e48.maxX, minY: e48.minY, maxY: e48.maxY };
case "top":
return { minX: e48.minX, maxX: e48.maxX, minY: e48.maxY - n2, maxY: e48.maxY };
case "bottom":
return { minX: e48.minX, maxX: e48.maxX, minY: e48.minY, maxY: e48.minY + n2 };
}
};
var FQ = (e48, t2, n2) => {
const o2 = t2.x - e48.x, i2 = t2.y - e48.y;
let r2 = 0, s2 = 1;
const a2 = (e49, t3) => {
if (Math.abs(e49) <= oQ)
return t3 >= -1e-6;
const n3 = t3 / e49;
return e49 < 0 ? !(n3 > s2) && (n3 > r2 && (r2 = n3), true) : !(n3 < r2) && (n3 < s2 && (s2 = n3), true);
};
if (!(a2(-o2, e48.x - n2.minX) && a2(o2, n2.maxX - e48.x) && a2(-i2, e48.y - n2.minY) && a2(i2, n2.maxY - e48.y)))
return 0;
const c2 = Math.hypot(o2, i2);
return Math.max(0, s2 - r2) * c2;
};
var jQ = (e48, t2) => rQ.filter((n2) => {
switch (n2) {
case "left":
return Math.abs(e48.x - t2.minX) <= oQ;
case "right":
return Math.abs(e48.x - t2.maxX) <= oQ;
case "top":
return Math.abs(e48.y - t2.maxY) <= oQ;
case "bottom":
return Math.abs(e48.y - t2.minY) <= oQ;
}
return false;
});
var $Q = (e48, t2) => {
const n2 = [];
return e48.x < t2.minX - oQ && n2.push("left"), e48.x > t2.maxX + oQ && n2.push("right"), e48.y > t2.maxY + oQ && n2.push("top"), e48.y < t2.minY - oQ && n2.push("bottom"), n2;
};
var YQ = (e48, t2, n2) => {
const o2 = t2.x - e48.x, i2 = t2.y - e48.y;
switch (n2) {
case "left":
case "right":
return Math.abs(o2) <= oQ && Math.abs(i2) > oQ;
case "top":
case "bottom":
return Math.abs(i2) <= oQ && Math.abs(o2) > oQ;
}
};
var XQ = (e48, t2, n2) => {
const o2 = [], i2 = Math.max(n2, oQ), r2 = Math.min(0.1, i2 / 4);
for (let n3 = 0;n3 < e48.length; n3 += 1) {
const s2 = e48[n3], a2 = s2?.route ?? [];
for (let e49 = 0;e49 < a2.length - 1; e49 += 1) {
const c2 = a2[e49], l2 = a2[e49 + 1];
if (!c2 || !l2)
continue;
const h2 = $Q(c2, t2), d2 = $Q(l2, t2), u2 = jQ(c2, t2), p2 = jQ(l2, t2), m2 = rQ.filter((e50) => {
if (s2.connectedPadSides?.includes(e50))
return false;
return !(FQ(c2, l2, BQ(t2, e50, i2)) <= r2) && !!YQ(c2, l2, e50);
}), g2 = !zQ(c2, t2) || !zQ(l2, t2), f2 = Array.from(new Set([...m2, ...h2, ...d2]));
(g2 || f2.length !== 0) && o2.push({ routeIndex: n3, connectionName: s2.connectionName ?? s2.rootConnectionName ?? `route-${n3}`, segmentIndex: e49, touchedSides: f2, startSides: u2, endSides: p2, start: c2, end: l2 });
}
}
return o2;
};
var WQ = (e48) => e48?.center && e48.width && e48.height ? { minX: e48.center.x - e48.width / 2, maxX: e48.center.x + e48.width / 2, minY: e48.center.y - e48.height / 2, maxY: e48.center.y + e48.height / 2, width: e48.width, height: e48.height, center: e48.center } : null;
var VQ = (e48) => e48 === "bottom" ? tQ : "#FF0000";
var HQ = (e48) => {
const t2 = e48.route ?? [], n2 = [];
if (t2.length < 2)
return n2;
let o2 = lQ(t2[0]), i2 = [t2[0]];
for (let r2 = 1;r2 < t2.length; r2 += 1) {
const s2 = t2[r2], a2 = lQ(s2);
a2 === o2 ? i2.push(s2) : (i2.length >= 2 && n2.push({ points: i2, strokeColor: VQ(o2), strokeWidth: e48.traceThickness ?? nQ, label: e48.connectionName ?? "route" }), o2 = a2, i2 = [t2[r2 - 1], s2]);
}
return i2.length >= 2 && n2.push({ points: i2, strokeColor: VQ(o2), strokeWidth: e48.traceThickness ?? nQ, label: e48.connectionName ?? "route" }), n2;
};
var GQ = (e48) => {
const t2 = KJ(e48), n2 = t2.route ?? [], o2 = t2.vias ?? [];
for (let e49 = 1;e49 < n2.length; e49++) {
const i2 = n2[e49 - 1], r2 = n2[e49];
if ((i2.z ?? 0) === (r2.z ?? 0))
continue;
if (i2.x !== r2.x || i2.y !== r2.y)
throw new Error("Node repair requires coincident via transition endpoints");
let s2 = -1, a2 = 0.001;
for (let e50 = 0;e50 < o2.length; e50++) {
const t3 = o2[e50], n3 = Math.hypot(t3.x - i2.x, t3.y - i2.y);
n3 <= a2 && (s2 = e50, a2 = n3);
}
s2 === -1 ? o2.push({ x: i2.x, y: i2.y, diameter: t2.viaDiameter }) : o2[s2] = { ...o2[s2], x: i2.x, y: i2.y };
}
return (o2.length || t2.vias) && (t2.vias = o2), t2;
};
var UQ = (e48) => {
const t2 = e48.route ?? [], n2 = [];
for (let o2 = 1;o2 < t2.length; o2++) {
const i2 = t2[o2 - 1], r2 = t2[o2];
(i2.z ?? 0) === (r2.z ?? 0) && n2.push({ start: i2, end: r2, radius: (e48.traceThickness ?? nQ) / 2, minZ: i2.z ?? 0, maxZ: i2.z ?? 0, indexes: [o2 - 1, o2], via: false });
}
for (const [o2, i2] of (e48.vias ?? []).entries()) {
const r2 = t2.flatMap((e49, t3) => e49.x === i2.x && e49.y === i2.y ? [t3] : []), s2 = r2.map((e49) => t2[e49].z ?? 0);
n2.push({ start: i2, end: i2, radius: (i2.diameter ?? e48.viaDiameter ?? 0.3) / 2, minZ: s2.length ? Math.min(...s2) : 0, maxZ: s2.length ? Math.max(...s2) : 1, indexes: r2, via: true, viaIndex: o2 });
}
return n2;
};
var ZQ = (e48, t2, n2, o2 = [], i2, r2 = new WeakMap) => {
const s2 = [...e48, ...o2], a2 = s2.map((e49) => {
let t3 = r2.get(e49);
return t3 || (t3 = UQ(e49), r2.set(e49, t3)), t3;
}), c2 = i2 ? i2.evaluation.conflicts.filter((e49) => e49.firstRoute !== i2.changedRoute && e49.secondRoute !== i2.changedRoute) : [];
let l2 = c2.reduce((e49, t3) => e49 + t3.penetration ** 2, 0);
for (let o3 = 0;o3 < e48.length; o3++) {
const r3 = e48[o3], h2 = new Set([r3.connectionName, r3.rootConnectionName].filter(Boolean));
if (!i2 || o3 === i2.changedRoute) {
const e49 = a2[o3].filter((e50) => e50.via);
for (let n3 = 0;n3 < e49.length; n3++) {
const i3 = e49[n3];
for (let r4 = n3 + 1;r4 < e49.length; r4++) {
const s3 = e49[r4];
if (i3.maxZ < s3.minZ || s3.maxZ < i3.minZ)
continue;
const a3 = Math.hypot(i3.start.x - s3.start.x, i3.start.y - s3.start.y);
if (a3 === 0)
continue;
const h3 = t2 + i3.radius + s3.radius - a3;
h3 <= oQ || (c2.push({ key: `${o3}:vias:${n3}:${r4}`, firstRoute: o3, secondRoute: o3, first: i3, second: s3, penetration: h3 }), l2 += h3 ** 2);
}
}
for (const [e50, i3] of n2.entries()) {
if (i3.connectedTo?.some((e51) => h2.has(e51)))
continue;
let n3;
for (const r4 of a2[o3]) {
if (i3.zLayers && !i3.zLayers.some((e51) => e51 >= r4.minZ && e51 <= r4.maxZ))
continue;
const s3 = t2 - qQ(r4, i3);
s3 <= oQ || s3 <= (n3?.penetration ?? 0) || (n3 = { key: `${o3}:pad:${e50}`, firstRoute: o3, secondRoute: -1, first: r4, second: r4, penetration: s3 });
}
n3 && (c2.push(n3), l2 += n3.penetration ** 2);
}
}
for (let e49 = o3 + 1;e49 < s2.length; e49++) {
if (i2 && o3 !== i2.changedRoute && e49 !== i2.changedRoute)
continue;
const n3 = s2[e49], r4 = h2.has(n3.connectionName) || h2.has(n3.rootConnectionName), d2 = new Map;
for (const n4 of a2[o3])
for (const i3 of a2[e49]) {
if (r4 && (!n4.via || !i3.via))
continue;
if (n4.maxZ < i3.minZ || i3.maxZ < n4.minZ)
continue;
if (r4 && n4.start.x === i3.start.x && n4.start.y === i3.start.y)
continue;
const s3 = t2 + n4.radius + i3.radius;
if (Math.min(n4.start.x, n4.end.x) > Math.max(i3.start.x, i3.end.x) + s3 || Math.min(i3.start.x, i3.end.x) > Math.max(n4.start.x, n4.end.x) + s3 || Math.min(n4.start.y, n4.end.y) > Math.max(i3.start.y, i3.end.y) + s3 || Math.min(i3.start.y, i3.end.y) > Math.max(n4.start.y, n4.end.y) + s3)
continue;
const a3 = s3 - mQ(n4.start, n4.end, i3.start, i3.end);
if (a3 <= oQ)
continue;
const c3 = `${n4.via ? `via:${n4.viaIndex}` : `trace:${n4.minZ}`}:${i3.via ? `via:${i3.viaIndex}` : `trace:${i3.minZ}`}`;
a3 <= (d2.get(c3)?.penetration ?? 0) || d2.set(c3, { key: `${o3}:${e49}:${c3}`, firstRoute: o3, secondRoute: e49, first: n4, second: i3, penetration: a3 });
}
for (const e50 of d2.values())
c2.push(e50), l2 += e50.penetration ** 2;
}
}
return c2.sort((e49, t3) => t3.penetration - e49.penetration), { conflicts: c2, score: l2 };
};
var qQ = (e48, t2) => {
if (!t2.center || t2.width === undefined || t2.height === undefined)
return 1 / 0;
const n2 = t2.center.x - t2.width / 2, o2 = t2.center.x + t2.width / 2, i2 = t2.center.y - t2.height / 2, r2 = t2.center.y + t2.height / 2;
let s2 = 0;
for (const t3 of [e48.start, e48.end])
t3.x >= n2 && t3.x <= o2 && t3.y >= i2 && t3.y <= r2 && (s2 = Math.max(s2, e48.radius + Math.min(t3.x - n2, o2 - t3.x, t3.y - i2, r2 - t3.y)));
if (s2 > 0)
return -s2;
const a2 = [{ x: n2, y: i2 }, { x: o2, y: i2 }, { x: o2, y: r2 }, { x: n2, y: r2 }];
return Math.min(...a2.map((t3, n3) => mQ(e48.start, e48.end, t3, a2[(n3 + 1) % 4]))) - e48.radius;
};
var JQ = (e48, t2) => {
const n2 = UQ(e48).filter((e49) => !t2.zLayers || t2.zLayers.some((t3) => t3 >= e49.minZ && t3 <= e49.maxZ));
return Math.min(...n2.map((e49) => qQ(e49, t2)));
};
var QQ = (e48, t2, n2, o2, i2) => {
const r2 = KJ(e48), s2 = r2.route ?? [], a2 = e48.route ?? [], c2 = (e49) => e49 === 0 || e49 === s2.length - 1, l2 = new Set;
for (const e49 of t2.indexes) {
if (c2(e49))
continue;
const t3 = a2[e49];
a2.forEach((e50, n3) => {
e50.x === t3.x && e50.y === t3.y && l2.add(n3);
});
}
if (!([...l2].some(c2) || t2.via && t2.indexes.some(c2))) {
if (l2.size === 0) {
if (t2.via || t2.indexes.length !== 2)
return;
const [e49, i3] = t2.indexes, r3 = s2[e49], a3 = s2[i3], c3 = [0.25, 0.75].map((e50) => ({ ...r3, x: r3.x + (a3.x - r3.x) * e50 + n2, y: r3.y + (a3.y - r3.y) * e50 + o2 }));
s2.splice(i3, 0, ...c3);
} else {
for (const e49 of l2)
s2[e49].x += n2, s2[e49].y += o2;
for (const e49 of r2.vias ?? [])
[...l2].some((t3) => a2[t3].x === e49.x && a2[t3].y === e49.y) && (e49.x += n2, e49.y += o2);
}
if (!s2.some((e49, t3) => t3 > 0 && t3 < s2.length - 1 && (e49.x < i2.minX || e49.x > i2.maxX || e49.y < i2.minY || e49.y > i2.maxY)))
return r2;
}
};
var KQ = (e48) => {
const t2 = [], n2 = e48.route ?? [];
for (let o2 = 1;o2 < n2.length; o2++) {
const i2 = n2[o2 - 1], r2 = n2[o2];
(i2.z ?? 0) === (r2.z ?? 0) && t2.push({ start: i2, end: r2, radius: (e48.traceThickness ?? nQ) / 2, minZ: i2.z ?? 0, maxZ: i2.z ?? 0 });
}
for (const o2 of e48.vias ?? []) {
let i2 = 1 / 0, r2 = -1 / 0;
for (let e49 = 1;e49 < n2.length; e49++) {
const t3 = n2[e49 - 1], s2 = n2[e49];
Math.hypot(t3.x - o2.x, t3.y - o2.y) > 0.001 || Math.hypot(s2.x - o2.x, s2.y - o2.y) > 0.001 || t3.z === s2.z || (i2 = Math.min(i2, t3.z ?? 0, s2.z ?? 0), r2 = Math.max(r2, t3.z ?? 0, s2.z ?? 0));
}
t2.push({ start: o2, end: o2, radius: (o2.diameter ?? e48.viaDiameter ?? 0.3) / 2, minZ: i2 === 1 / 0 ? 0 : i2, maxZ: r2 === -1 / 0 ? 1 : r2 });
}
return t2;
};
var eK = (e48, t2) => {
let n2 = 1 / 0;
for (const o2 of e48)
o2.maxZ < t2.minZ || t2.maxZ < o2.minZ || (n2 = Math.min(n2, mQ(o2.start, o2.end, t2.start, t2.end) - o2.radius - t2.radius));
return n2;
};
var tK = class {
constructor(e48, t2, n2 = []) {
this.minimumClearance = t2, this.obstacles = n2, this.fixedCopper = e48.map((e49) => ({ route: e49, copper: KQ(e49) }));
}
minimumClearance;
obstacles;
fixedCopper;
cache = new WeakMap;
allows(e48, t2, n2, o2 = true) {
if (o2 && ((e49, t3, n3) => {
const o3 = new Map(ZQ(e49, n3, []).conflicts.map((e50) => [e50.key, e50.penetration]));
return ZQ(t3, n3, []).conflicts.some((e50) => e50.penetration > (o3.get(e50.key) ?? 0) + oQ);
})(e48, t2, this.minimumClearance))
return false;
if (this.fixedCopper.length === 0 && this.obstacles.length === 0)
return true;
for (const o3 of n2) {
const n3 = e48[o3], i2 = t2[o3];
if (n3 === i2)
continue;
const r2 = this.cache.get(n3) ?? KQ(n3), s2 = this.cache.get(i2) ?? KQ(i2);
this.cache.set(n3, r2), this.cache.set(i2, s2);
const a2 = new Set([n3.connectionName, n3.rootConnectionName].filter(Boolean));
for (const e49 of this.obstacles) {
if (e49.connectedTo?.some((e50) => a2.has(e50)))
continue;
const t3 = JQ(i2, e49);
if (t3 >= this.minimumClearance - oQ)
continue;
const o4 = JQ(n3, e49);
if (t3 < Math.min(o4, this.minimumClearance) - oQ)
return false;
}
for (const e49 of this.fixedCopper)
if (!a2.has(e49.route.connectionName) && !a2.has(e49.route.rootConnectionName))
for (const t3 of e49.copper) {
const e50 = eK(s2, t3);
if (e50 >= this.minimumClearance - oQ)
continue;
const n4 = eK(r2, t3);
if (e50 < Math.min(n4, this.minimumClearance) - oQ)
return false;
}
}
return true;
}
};
var nK = (e48, t2) => ({ title: `HighDensityRepair02 Initial State (margin=${t2})`, routes: e48 });
var oK = (e48) => {
const t2 = [];
for (const n2 of e48) {
const e49 = t2[t2.length - 1];
e49 && e49.z === n2.z && gQ(e49, n2) || t2.push(n2);
}
return t2;
};
var iK = (e48, t2, n2) => {
const o2 = Math.max(0, e48.minX - t2.maxX, t2.minX - e48.maxX), i2 = Math.max(0, e48.minY - t2.maxY, t2.minY - e48.maxY);
return Math.hypot(o2, i2) <= n2 + oQ;
};
var rK = (e48, t2) => {
let n2 = Number.POSITIVE_INFINITY;
for (const o2 of e48.segments)
for (const e49 of t2.segments) {
if (o2.layer !== e49.layer)
continue;
const t3 = mQ(o2.start, o2.end, e49.start, e49.end) - (o2.thickness + e49.thickness) / 2;
n2 = Math.min(n2, t3);
}
return n2;
};
var sK = ({ currentRoutes: e48, candidateRoutes: t2, candidateRouteIndexes: n2, maximumAllowedClearance: o2 }) => {
const i2 = new WeakMap, r2 = new WeakMap, s2 = [], a2 = Array.from(n2).sort((e49, t3) => e49 - t3), c2 = e48.map((e49, t3) => dQ(e49, t3, i2)), l2 = t2.map((e49, t3) => dQ(e49, t3, r2)), h2 = new Set;
for (const e49 of a2)
for (let n3 = 0;n3 < t2.length; n3 += 1) {
if (n3 === e49)
continue;
const t3 = Math.min(e49, n3), i3 = Math.max(e49, n3), r3 = `${t3}:${i3}`;
if (h2.has(r3))
continue;
h2.add(r3);
const a3 = l2[t3], d2 = l2[i3];
if (!a3 || !d2 || !iK(a3.bounds, d2.bounds, o2))
continue;
const u2 = rK(a3, d2);
if (!Number.isFinite(u2) || u2 > o2 + oQ || !c2[t3] || !c2[i3])
continue;
const p2 = rK(c2[t3], c2[i3]);
!Number.isFinite(p2) || u2 >= p2 - oQ || s2.push({ routeIndexes: [t3, i3], previousClearance: p2, nextClearance: u2 });
}
return s2;
};
var aK = 0.001;
var cK = (e48, t2) => e48.map((e49) => {
const n2 = e49.route ?? [];
return n2.length === 0 ? e49 : { ...e49, route: n2.map((e50, o2) => o2 === 0 || o2 === n2.length - 1 ? ((e51, t3) => {
const n3 = { ...e51 };
return Math.abs(n3.x - t3.minX) <= aK ? n3.x = t3.minX : Math.abs(n3.x - t3.maxX) <= aK && (n3.x = t3.maxX), Math.abs(n3.y - t3.minY) <= aK ? n3.y = t3.minY : Math.abs(n3.y - t3.maxY) <= aK && (n3.y = t3.maxY), n3;
})(e50, t2) : e50) };
});
var lK = (e48, t2) => Array.from(t2).flatMap((t3) => HQ(e48[t3]).map((e49) => ({ ...e49, strokeColor: "#000000", strokeWidth: e49.strokeWidth, label: `candidate:${e49.label}` })));
var hK = (e48, t2, n2, o2, i2) => {
const r2 = "rgba(0, 0, 0, 0)";
switch (t2) {
case "left":
return { center: { x: e48.minX + n2 / 2, y: e48.center.y }, width: n2, height: e48.height, stroke: r2, fill: o2, label: i2 };
case "right":
return { center: { x: e48.maxX - n2 / 2, y: e48.center.y }, width: n2, height: e48.height, stroke: r2, fill: o2, label: i2 };
case "top":
return { center: { x: e48.center.x, y: e48.maxY - n2 / 2 }, width: e48.width, height: n2, stroke: r2, fill: o2, label: i2 };
case "bottom":
return { center: { x: e48.center.x, y: e48.minY + n2 / 2 }, width: e48.width, height: n2, stroke: r2, fill: o2, label: i2 };
}
};
var dK = ({ routes: e48, candidateRoutes: t2, candidateRouteIndexes: n2, originalRoutes: o2, boundary: i2, side: r2, margin: s2, rejected: a2, rejectionReason: c2 }) => {
const l2 = Array.from(n2).map((e49) => t2[e49].connectionName ?? `route-${e49}`);
return { title: a2 ? `${r2} move rejected (${c2})` : `${r2} move accepted`, routes: a2 ? e48 : t2, originalRoutes: o2, activeSide: r2, candidateRouteNames: l2, overlayLines: a2 ? lK(t2, n2) : [], overlayRects: [hK(i2, r2, s2, a2 ? "rgba(220, 38, 38, 0.14)" : "rgba(16, 185, 129, 0.14)", a2 ? `rejected:${r2}` : `accepted:${r2}`)] };
};
var uK = (e48, t2, n2, o2) => {
const i2 = (e48?.adjacentObstacles ?? []).some((e49) => ((e50, t3, n3, o3) => {
const i3 = ((e51) => e51.center && e51.width && e51.height ? { minX: e51.center.x - e51.width / 2, maxX: e51.center.x + e51.width / 2, minY: e51.center.y - e51.height / 2, maxY: e51.center.y + e51.height / 2 } : null)(e50);
if (!i3)
return false;
switch (n3) {
case "left":
return i3.maxX >= t3.minX - oQ && i3.minX <= t3.minX + o3 + oQ;
case "right":
return i3.minX <= t3.maxX + oQ && i3.maxX >= t3.maxX - o3 - oQ;
case "top":
return i3.minY <= t3.maxY + oQ && i3.maxY >= t3.maxY - o3 - oQ;
case "bottom":
return i3.maxY >= t3.minY - oQ && i3.minY <= t3.minY + o3 + oQ;
}
})(e49, t2, n2, o2));
return { hasObstacle: i2, moveAmount: i2 ? o2 : o2 / 2 };
};
var pK = ({ start: e48, end: t2, side: n2, boundary: o2, amount: i2, targetAxisValue: r2 }) => {
const s2 = (({ side: e49, boundary: t3, amount: n3, targetAxisValue: o3 }) => {
const i3 = o3 ?? (() => {
switch (e49) {
case "left":
return t3.minX + n3;
case "right":
return t3.maxX - n3;
case "top":
return t3.maxY - n3;
case "bottom":
return t3.minY + n3;
}
})();
switch (e49) {
case "left":
case "right":
return Math.min(Math.max(i3, t3.minX), t3.maxX);
case "top":
case "bottom":
return Math.min(Math.max(i3, t3.minY), t3.maxY);
}
})({ side: n2, boundary: o2, amount: i2, targetAxisValue: r2 });
switch (n2) {
case "left":
case "right":
return oK([e48, { x: s2, y: e48.y, z: e48.z }, { x: s2, y: t2.y, z: t2.z }, t2]);
case "top":
case "bottom":
return oK([e48, { x: e48.x, y: s2, z: e48.z }, { x: t2.x, y: s2, z: t2.z }, t2]);
}
};
var mK = (e48, t2, n2, o2, i2, r2, s2, a2 = false) => {
const c2 = e48.route ?? [];
if (c2.length < 2 || t2.length === 0)
return KJ(e48);
const l2 = a2 ? i2 : Math.max(i2, r2), h2 = ((e49, t3) => {
switch (e49) {
case "left":
return { x: t3, y: 0 };
case "right":
return { x: -t3, y: 0 };
case "top":
return { x: 0, y: -t3 };
case "bottom":
return { x: 0, y: t3 };
}
})(o2, l2);
if (a2 || (e48.vias?.length ?? 0) > 0 || c2.length > 2) {
const n3 = KJ(e48), o3 = n3.route ?? [];
for (const e49 of t2) {
const t3 = o3[e49];
t3 && (o3[e49] = { ...t3, x: t3.x + h2.x, y: t3.y + h2.y });
}
for (const o4 of n3.vias ?? []) {
t2.some((t3) => {
const n4 = e48.route?.[t3];
return !!n4 && gQ(n4, o4);
}) && (o4.x += h2.x, o4.y += h2.y);
}
return n3;
}
const d2 = KJ(e48);
if (c2.length === 2 && t2.length === 2 && t2[0] === 0 && t2[1] === 1) {
const t3 = c2[0], i3 = c2[1];
return KJ({ ...e48, route: pK({ start: t3, end: i3, side: o2, boundary: n2, amount: l2, targetAxisValue: s2 }) });
}
return d2;
};
var gK = (e48, t2, n2) => {
switch (n2) {
case "left":
return e48.x - t2.minX;
case "right":
return t2.maxX - e48.x;
case "top":
return t2.maxY - e48.y;
case "bottom":
return e48.y - t2.minY;
}
};
var fK = (e48, t2, n2) => {
const o2 = ((e49) => {
const t3 = e49.route ?? [];
if (t3.length === 0)
return [];
const n3 = [];
for (let e50 = 0;e50 < t3.length; e50 += 1) {
const o3 = t3[e50];
if (!o3)
continue;
e50 === 0 || e50 === t3.length - 1 || n3.push(o3);
const i2 = t3[e50 + 1];
i2 && n3.push({ x: (o3.x + i2.x) / 2, y: (o3.y + i2.y) / 2 });
}
return n3;
})(e48);
return o2.length === 0 ? Number.POSITIVE_INFINITY : o2.reduce((e49, o3) => Math.min(e49, gK(o3, t2, n2)), Number.POSITIVE_INFINITY);
};
var _K = (e48, t2, n2 = []) => {
const o2 = e48.route ?? [], i2 = [], r2 = new Set, s2 = t2.length === 0 || t2.includes("via");
if (o2.length === 2)
return [0, 1];
const a2 = (e49) => {
if (e49 <= 0 || e49 >= o2.length - 1)
return;
if (r2.has(e49))
return;
const n3 = o2[e49];
n3 && (s2 || t2.includes(lQ(n3))) && (r2.add(e49), i2.push(e49));
};
if (n2.length > 0)
for (const e49 of n2)
a2(e49);
else
for (let e49 = 1;e49 < o2.length - 1; e49 += 1)
a2(e49);
for (let e49 = 0;e49 < i2.length; e49 += 1) {
const t3 = i2[e49], n3 = o2[t3];
if (n3)
for (let e50 = 1;e50 < o2.length - 1; e50 += 1) {
if (r2.has(e50))
continue;
const t4 = o2[e50];
t4 && (t4.z !== n3.z && gQ(t4, n3) && (r2.add(e50), i2.push(e50)));
}
}
return i2.sort((e49, t3) => e49 - t3), i2;
};
var yK = (e48, t2) => Math.max(0, ...(e48.route ?? []).map((e49) => Math.max(t2.minX - e49.x, e49.x - t2.maxX, t2.minY - e49.y, e49.y - t2.maxY, 0)));
var bK = (e48, t2, n2, o2) => gK(e48, t2, n2) <= o2 + oQ;
var xK = (e48, t2, n2, o2) => {
const i2 = e48.route ?? [], r2 = [], s2 = new Set;
let a2 = 1, c2 = i2.length - 2;
for (;a2 < i2.length - 1 && gQ(i2[a2], i2[0]); )
a2 += 1;
for (;c2 > 0 && gQ(i2[c2], i2[i2.length - 1]); )
c2 -= 1;
for (let e49 = a2;e49 <= c2; e49 += 1)
bK(i2[e49], t2, n2, o2) && (s2.add(e49), r2.push(e49));
for (let e49 = 0;e49 < r2.length; e49 += 1) {
const t3 = i2[r2[e49]];
if (t3)
for (let e50 = a2;e50 <= c2; e50 += 1) {
if (s2.has(e50))
continue;
const n3 = i2[e50];
n3 && (n3.z !== t3.z && gQ(n3, t3) && (s2.add(e50), r2.push(e50)));
}
}
return r2.length === 0 && i2.length === 2 && i2.some((e49) => bK(e49, t2, n2, o2)) ? [0, 1] : (r2.sort((e49, t3) => e49 - t3), r2);
};
var vK = (e48, t2, n2) => {
const o2 = e48.route ?? [], i2 = n2 === 0 ? o2[0] : o2[o2.length - 1];
return i2 ? rQ.filter((e49) => gK(i2, t2, e49) <= oQ) : [];
};
var IK = (e48, t2, n2) => {
const o2 = e48.route ?? [], i2 = t2.route ?? [];
if (o2.length === 0 || i2.length === 0)
return true;
for (const t3 of [0, -1]) {
const o3 = vK(e48, n2, t3);
if (o3.length === 0)
continue;
const r2 = t3 === 0 ? i2[0] : i2[i2.length - 1];
if (!r2)
return false;
for (const e49 of o3)
if (gK(r2, n2, e49) > oQ)
return false;
}
return true;
};
var SK = (e48, t2) => Math.hypot(t2.x - e48.x, t2.y - e48.y);
var CK = (e48, t2, n2, o2) => {
const i2 = e48.route ?? [];
if (i2.length === 0)
return "none";
let r2 = false;
for (let e49 = 0;e49 < i2.length; e49 += 1) {
const s2 = i2[e49];
if (s2 && bK(s2, t2, n2, o2)) {
if (e49 !== 0 && e49 !== i2.length - 1)
return "interior";
r2 = true;
}
}
for (let e49 = 0;e49 < i2.length - 1; e49 += 1) {
const r3 = i2[e49], s2 = i2[e49 + 1];
if (r3 && s2 && (bK(r3, t2, n2, o2) && bK(s2, t2, n2, o2) && !(SK(r3, s2) <= oQ)))
return "interior";
}
return r2 ? "endpoint" : "none";
};
var PK = ({ currentRoutes: e48, routeIndex: t2, side: n2, moveSide: o2 = n2, boundary: i2, margin: r2, moveAmount: s2, geometryCache: a2, fixedCopperGuard: c2 }) => {
const l2 = e48[t2], h2 = (l2.route?.length ?? 0) === 2, d2 = xK(l2, i2, n2, r2);
if (d2.length === 0)
return null;
const u2 = new Set, p2 = new Map, m2 = new Set, g2 = e48.slice();
let f2 = false, _2 = "overlap";
const y2 = new Set([t2]), b2 = new Map([[t2, new Set]]), x2 = new Map([[t2, new Set]]), v2 = [t2];
let I2 = 0, S2 = null, C2 = null, P2 = null, M2 = null;
const w2 = (e49) => new Set(e49.map((e50) => wQ(e50))), N2 = () => S2 || (S2 = LQ(e48, u2, r2, a2, p2), S2), T2 = () => P2 || (P2 = LQ(e48, u2, 0, a2, p2), P2), R2 = () => M2 || (M2 = LQ(g2, u2, 0, a2, p2), M2);
for (;I2 < v2.length && !f2; ) {
const c3 = v2[I2];
if (I2 += 1, y2.delete(c3), u2.has(c3))
continue;
const l3 = g2[c3], h3 = Array.from(b2.get(c3) ?? []), d3 = Array.from(x2.get(c3) ?? []);
b2.delete(c3), x2.delete(c3);
const T3 = c3 === t2 ? xK(l3, i2, n2, r2) : _K(l3, h3, d3);
if (T3.length === 0) {
if (c3 === t2)
return null;
f2 = true, _2 = "eventual-overlap";
break;
}
const R3 = l3.route ?? [], E2 = c3 === t2 ? undefined : o2 === "left" || o2 === "right" ? (R3[T3[0]]?.x ?? 0) + (o2 === "left" ? s2 : -s2) : (R3[T3[0]]?.y ?? 0) + (o2 === "top" ? -s2 : s2);
g2[c3] = mK(l3, T3, i2, o2, s2, r2, E2, c3 !== t2), u2.add(c3), p2.set(c3, new Set(T3)), S2 = null, C2 = null, P2 = null, M2 = null, (l3.route?.length ?? 0) === 2 && m2.add(c3);
const A2 = yK(e48[c3], i2);
if (yK(g2[c3], i2) > A2 + 0.000001) {
f2 = true, _2 = "boundary";
break;
}
if (!IK(e48[c3], g2[c3], i2)) {
f2 = true, _2 = "endpoint-boundary";
break;
}
const O2 = LQ(g2, new Set([c3]), r2, a2, new Map([[c3, new Set(T3)]]));
for (const e49 of O2) {
if (w2(N2()).has(wQ(e49)))
continue;
const [t3, n3] = e49.routeIndexes, o3 = u2.has(t3), i3 = u2.has(n3);
if (o3 && i3)
continue;
const r3 = o3 ? n3 : t3, s3 = o3 ? e49.layers[1] : e49.layers[0], a3 = o3 ? e49.routePointIndexes[1] : e49.routePointIndexes[0];
if (u2.has(r3) || y2.has(r3)) {
if (y2.has(r3)) {
const e50 = b2.get(r3) ?? new Set;
e50.add(s3), b2.set(r3, e50);
const t4 = x2.get(r3) ?? new Set;
for (const e51 of a3)
t4.add(e51);
x2.set(r3, t4);
}
} else
y2.add(r3), v2.push(r3), b2.set(r3, new Set([s3])), x2.set(r3, new Set(a3));
}
}
if (!f2 && u2.size > 1) {
const e49 = w2(N2()), t3 = w2(C2 || (C2 = LQ(g2, u2, r2, a2, p2), C2));
for (const n3 of t3)
if (!e49.has(n3)) {
f2 = true, _2 = "eventual-overlap";
break;
}
}
if (!f2 && u2.size > 1) {
const e49 = w2(T2()), t3 = w2(R2());
for (const n3 of t3)
if (!e49.has(n3)) {
f2 = true, _2 = "eventual-overlap";
break;
}
}
if (!f2) {
const t3 = new Set(LQ(e48, u2, 0, a2).map((e49) => wQ(e49))), n3 = LQ(g2, u2, 0, a2);
for (const e49 of n3) {
const n4 = wQ(e49);
if (!t3.has(n4)) {
f2 = true, _2 = "eventual-overlap";
break;
}
}
}
if (!f2) {
const t3 = (({ currentRoutes: e49, candidateRoutes: t4, candidateRouteIndexes: n3, boundary: o3, activeSide: i3 }) => {
const r3 = rQ.filter((e50) => e50 !== i3), s3 = [];
for (const i4 of n3) {
const n4 = e49[i4], a3 = t4[i4];
if (n4 && a3)
for (const e50 of r3) {
const t5 = fK(n4, o3, e50), r4 = fK(a3, o3, e50);
t5 > oQ && r4 <= oQ && s3.push({ routeIndex: i4, side: e50, previousClearance: t5, nextClearance: r4 });
}
}
return s3;
})({ currentRoutes: e48, candidateRoutes: g2, candidateRouteIndexes: u2, boundary: i2, activeSide: n2 });
t3.length > 0 && (f2 = true, _2 = "boundary-touch");
}
if (!f2) {
const t3 = (({ currentRoutes: e49, candidateRoutes: t4, candidateRouteIndexes: n3, geometryCache: o3, currentConflicts: i3, candidateConflicts: r3 }) => {
const s3 = i3 ?? LQ(e49, n3, 0, o3), a3 = r3 ?? LQ(t4, n3, 0, o3), c3 = new Set(s3.map((e50) => wQ(e50)));
return a3.filter((e50) => {
const o4 = wQ(e50);
if (c3.has(o4))
return false;
const [i4, r4] = e50.routeIndexes, [s4, a4] = e50.layers, l3 = n3.has(i4), h3 = n3.has(r4);
if (l3 && h3)
return false;
const d3 = l3 ? a4 : s4, u3 = t4[l3 ? r4 : i4];
return !!u3 && _K(u3, [d3]).length === 0;
});
})({ currentRoutes: e48, candidateRoutes: g2, candidateRouteIndexes: u2, geometryCache: a2, currentConflicts: T2(), candidateConflicts: R2() });
t3.length > 0 && (f2 = true, _2 = "fixed-trace-touch");
}
if (!f2) {
sK({ currentRoutes: e48, candidateRoutes: g2, candidateRouteIndexes: u2, maximumAllowedClearance: Math.min(r2 / 2, iQ) }).length > 0 && (f2 = true, _2 = "trace-clearance");
}
return !f2 && ((e49, t3, n3, o3, i3, r3) => Array.from(n3).some((n4) => {
const s3 = e49[n4], a3 = t3[n4];
return rQ.filter((e50) => e50 !== i3).some((e50) => {
const t4 = CK(s3, o3, e50, r3), n5 = CK(a3, o3, e50, r3);
return t4 === "none" && n5 !== "none";
});
}))(e48, g2, u2, i2, n2, r2) && (f2 = true, _2 = "side-regression"), f2 || !c2 || c2.allows(e48, g2, u2) || (f2 = true, _2 = "fixed-copper-clearance"), { isTwoPointRoute: h2, movableIndexes: d2, candidateRouteIndexes: u2, movedTwoPointRouteIndexes: m2, candidateRoutes: g2, rejected: f2, rejectionReason: _2 };
};
var MK = (e48, t2, n2, o2, i2) => {
const r2 = e48.route ?? [];
if (t2.length === 0)
return null;
if (o2 === "top" || o2 === "bottom") {
const e49 = t2.reduce((e50, t3) => e50 + (r2[t3]?.x ?? n2.center.x), 0) / t2.length;
return e49 < n2.center.x - i2 / 2 ? "right" : e49 > n2.center.x + i2 / 2 ? "left" : null;
}
const s2 = t2.reduce((e49, t3) => e49 + (r2[t3]?.y ?? n2.center.y), 0) / t2.length;
return s2 > n2.center.y + i2 / 2 ? "bottom" : s2 < n2.center.y - i2 / 2 ? "top" : null;
};
var wK = ({ side: e48, sample: t2, boundary: n2, margin: o2, repairedRoutes: i2, frames: r2, captureProgressFrames: s2, lockedTwoPointRoutes: a2, geometryCache: c2, fixedCopperGuard: l2, allowTwoPointWithoutObstacle: h2 = false }) => {
const { hasObstacle: d2, moveAmount: u2 } = uK(t2, n2, e48, o2);
s2 && r2.push(((e49, t3, n3, o3, i3, r3) => ({ title: `${n3} boundary analysis: move=${i3.toFixed(3)} (${r3 ? "obstacle-side" : "clear-side"})`, routes: e49, activeSide: n3, overlayRects: [hK(t3, n3, o3, "rgba(245, 158, 11, 0.16)", `strip:${n3}`)] }))(eQ(i2), n2, e48, o2, u2, d2));
const p2 = new Set;
let m2 = 0;
for (let t3 = 0;t3 < i2.length; t3 += 1) {
if (p2.has(t3))
continue;
if (a2.has(t3))
continue;
const g2 = i2[t3];
if (g2.connectedPadSides?.includes(e48))
continue;
if ((g2.route?.length ?? 0) === 2 && !d2 && !h2)
continue;
let f2 = PK({ currentRoutes: i2, routeIndex: t3, side: e48, boundary: n2, margin: o2, moveAmount: u2, geometryCache: c2, fixedCopperGuard: l2 });
if (f2) {
if (f2.rejected) {
const r3 = MK(g2, f2.movableIndexes, n2, e48, o2);
if (r3) {
const s3 = PK({ currentRoutes: i2, routeIndex: t3, side: e48, moveSide: r3, boundary: n2, margin: o2, moveAmount: u2, geometryCache: c2, fixedCopperGuard: l2 });
s3 && !s3.rejected && (f2 = s3);
}
}
if (s2 && r2.push(dK({ routes: eQ(i2), candidateRoutes: f2.candidateRoutes, candidateRouteIndexes: f2.candidateRouteIndexes, originalRoutes: f2.rejected ? undefined : Array.from(f2.candidateRouteIndexes).map((e49) => KJ(i2[e49])), boundary: n2, side: e48, margin: o2, rejected: f2.rejected, rejectionReason: f2.rejectionReason })), !f2.rejected) {
i2.splice(0, i2.length, ...f2.candidateRoutes);
for (const e49 of f2.movedTwoPointRouteIndexes)
a2.add(e49);
m2 += 1;
}
p2.add(t3);
}
}
return { movesAccepted: m2 };
};
var NK = (e48, t2, n2, o2) => bK(e48, t2, n2, o2);
var TK = (e48, t2, n2, o2) => {
switch (n2) {
case "left":
return { ...e48, x: Math.min(t2.minX + o2, t2.maxX) };
case "right":
return { ...e48, x: Math.max(t2.maxX - o2, t2.minX) };
case "top":
return { ...e48, y: Math.max(t2.maxY - o2, t2.minY) };
case "bottom":
return { ...e48, y: Math.min(t2.minY + o2, t2.maxY) };
}
};
var RK = (e48) => `${e48.routeIndexes[0]}:${e48.layers[0]}:${e48.routeIndexes[1]}:${e48.layers[1]}`;
var EK = (e48) => {
if (!e48)
return [];
const t2 = [e48.connectionName, e48.rootConnectionName].filter((e49) => Boolean(e49));
return Array.from(new Set(t2));
};
var AK = (e48, t2) => {
const n2 = EK(e48), o2 = EK(t2);
return n2.length !== 0 && o2.length !== 0 && n2.some((e49) => o2.includes(e49));
};
var OK = (e48, t2, n2) => e48 ? XQ([e48], t2, n2).length : 0;
var kK = (e48, t2, n2, o2) => {
const i2 = new Set(LQ(e48, new Set([n2]), o2).map(wQ));
return LQ(t2, new Set([n2]), o2).some((e49) => !i2.has(wQ(e49)));
};
var DK = (e48, t2, n2) => XQ(e48, t2, n2).length;
var LK = (e48) => {
if (!e48)
return [];
const t2 = [e48.connectionName, e48.rootConnectionName].filter((e49) => Boolean(e49));
return Array.from(new Set(t2));
};
var zK = (e48, t2) => LQ(e48, new Set(e48.map((e49, t3) => t3)), iQ, t2).filter((t3) => !(t3.layers[0] === "via" && t3.layers[1] === "via" || ((e49, t4) => {
const n2 = LK(e49), o2 = LK(t4);
return n2.length !== 0 && o2.length !== 0 && n2.some((e50) => o2.includes(e50));
})(e48[t3.routeIndexes[0]], e48[t3.routeIndexes[1]]))).length;
var BK = (e48) => {
const t2 = rQ;
return [...t2.slice(e48 % t2.length), ...t2.slice(0, e48 % t2.length)];
};
var FK = (e48, t2, n2 = false, o2 = true) => {
const i2 = WQ(e48?.nodeWithPortPoints), r2 = (e48?.nodeHdRoutes ?? []).map(GQ), s2 = Math.max(t2 ?? 0.4, 0.05), a2 = new tK(e48?.fixedHdRoutes ?? [], Math.min(s2 / 2, iQ), e48?.clearanceObstacles ?? e48?.adjacentObstacles), c2 = i2 && o2 ? ((e49, t3) => e49.map((e50) => {
const n3 = e50.route ?? [];
let o3 = false;
const i3 = n3.map((e51) => {
let { x: n4, y: i4 } = e51;
return n4 < t3.minX ? n4 = t3.minX : n4 > t3.maxX && (n4 = t3.maxX), i4 < t3.minY ? i4 = t3.minY : i4 > t3.maxY && (i4 = t3.maxY), n4 === e51.x && i4 === e51.y ? e51 : (o3 = true, { ...e51, x: n4, y: i4 });
});
return o3 ? { ...e50, route: i3 } : e50;
}))(cK(eQ(r2), i2), i2) : eQ(r2), l2 = o2 && a2.allows(r2, c2, r2.keys()) ? c2 : r2, h2 = eQ(l2);
if (!i2)
return { boundary: null, baseRoutes: l2, repairedRoutes: h2, margin: s2, frames: [{ title: "HighDensityRepair02 Missing Boundary", routes: h2 }] };
const d2 = n2 ? [nK(eQ(h2), s2)] : [];
if (o2) {
const t3 = new WeakMap;
let o3 = DK(h2, i2, s2);
for (let r4 = 0;r4 < 1; r4 += 1) {
const c4 = new Set;
let l3 = 0;
for (const o4 of BK(r4)) {
const { movesAccepted: u4 } = wK({ side: o4, sample: e48, boundary: i2, frames: d2, margin: s2, repairedRoutes: h2, captureProgressFrames: n2, lockedTwoPointRoutes: c4, geometryCache: t3, fixedCopperGuard: a2, allowTwoPointWithoutObstacle: r4 >= 1 });
l3 += u4;
}
const u3 = DK(h2, i2, s2);
if (l3 === 0)
break;
if (u3 === 0)
break;
if (u3 >= o3)
break;
o3 = u3;
}
const r3 = eQ(h2), c3 = zK(h2, t3);
(({ routes: e49, boundary: t4, margin: n3, geometryCache: o4, fixedCopperGuard: i3 }) => {
const r4 = XQ(e49, t4, n3);
if (r4.length === 0)
return { movesAccepted: 0 };
const s3 = new Map;
for (const e50 of r4) {
const t5 = s3.get(e50.routeIndex) ?? new Set;
for (const n4 of e50.touchedSides)
t5.add(n4);
s3.set(e50.routeIndex, t5);
}
const a3 = [0.000008, 0.01, n3 / 4, n3 / 2, n3 + 0.000008];
let c4 = 0;
const l3 = (r5, s4, a4) => {
const c5 = s4.route ?? [];
if (c5.length < 2)
return false;
const l4 = { ...s4, route: oK(c5) };
if ((l4.route?.length ?? 0) < 2)
return false;
const h4 = e49.slice();
if (h4[r5] = l4, i3 && !i3.allows(e49, h4, [r5]))
return false;
if (OK(h4[r5], t4, n3) >= a4)
return false;
const d4 = (t5) => AK(e49[t5.routeIndexes[0]], e49[t5.routeIndexes[1]]), u4 = new Set(LQ(e49, new Set([r5]), 0, o4).filter((e50) => !d4(e50)).map(RK));
return !LQ(h4, new Set([r5]), 0, o4).filter((e50) => !d4(e50)).some((e50) => !u4.has(RK(e50))) && !(sK({ currentRoutes: e49, candidateRoutes: h4, candidateRouteIndexes: new Set([r5]), maximumAllowedClearance: Math.min(n3 / 2, iQ) }).filter((t5) => !AK(e49[t5.routeIndexes[0]], e49[t5.routeIndexes[1]])).length > 0 || (e49[r5] = l4, 0));
}, h3 = (n4, o5, i4, r5) => {
if (o5.length === 0)
return false;
for (const s4 of a3) {
const a4 = e49[n4], c5 = KJ(a4), h4 = c5.route ?? [];
let d4 = false;
for (const e50 of _K(a4, [], o5)) {
const n5 = h4[e50];
n5 && (h4[e50] = TK(n5, t4, i4, s4), d4 = true);
}
if (!d4)
return false;
if (l3(n4, c5, r5))
return true;
}
return false;
}, d3 = (e50, n4) => {
const o5 = [];
return n4 === "top" || n4 === "bottom" ? (Math.abs(e50.x - t4.minX) <= oQ && o5.push("left"), Math.abs(e50.x - t4.maxX) <= oQ && o5.push("right")) : (Math.abs(e50.y - t4.minY) <= oQ && o5.push("bottom"), Math.abs(e50.y - t4.maxY) <= oQ && o5.push("top")), o5;
}, u3 = (o5, i4, r5) => {
const s4 = e49[o5], c5 = s4.route ?? [];
if (c5.length !== 2)
return false;
const [h4, u4] = c5;
if (!NK(h4, t4, i4, n3))
return false;
if (!NK(u4, t4, i4, n3))
return false;
const p2 = d3(h4, i4), m2 = d3(u4, i4);
for (const e50 of a3) {
let n4 = TK(h4, t4, i4, e50), a4 = TK(u4, t4, i4, e50);
for (const o6 of p2)
n4 = TK(n4, t4, o6, e50);
for (const n5 of m2)
a4 = TK(a4, t4, n5, e50);
const c6 = { ...s4, route: [h4, n4, a4, u4] };
if (l3(o5, c6, r5))
return true;
}
return false;
};
for (const [o5, i4] of s3)
if (e49[o5])
for (const r5 of i4) {
let i5 = true;
for (;i5; ) {
i5 = false;
const s4 = e49[o5].route ?? [];
if (s4.length === 2) {
const i6 = OK(e49[o5], t4, n3);
i6 > 0 && u3(o5, r5, i6) && (c4 += 1);
break;
}
if (s4.length < 3)
break;
const a4 = OK(e49[o5], t4, n3);
if (a4 === 0)
break;
const l4 = [];
for (let e50 = 1;e50 < s4.length - 1; e50 += 1) {
const o6 = s4[e50];
o6 && NK(o6, t4, r5, n3) && l4.push(e50);
}
if (l4.length === 0)
break;
if (h3(o5, l4, r5, a4)) {
c4 += 1, i5 = true;
continue;
}
let d4 = false, p2 = a4, m2 = 0;
for (;m2 < l4.length; ) {
let i6 = m2;
for (;i6 + 1 < l4.length && l4[i6 + 1] === l4[i6] + 1; )
i6 += 1;
h3(o5, l4.slice(m2, i6 + 1), r5, p2) && (c4 += 1, d4 = true, p2 = OK(e49[o5], t4, n3)), m2 = i6 + 1;
}
if (!d4) {
const i6 = e49[o5].route ?? [];
let s5 = a4;
for (let a5 = 1;a5 < i6.length - 1; a5 += 1) {
const l5 = i6[a5];
l5 && NK(l5, t4, r5, n3) && h3(o5, [a5], r5, s5) && (c4 += 1, d4 = true, s5 = OK(e49[o5], t4, n3));
}
}
d4 && (i5 = true);
}
}
for (const [o5, i4] of s3) {
const r5 = e49[o5];
if (!r5)
continue;
const s4 = r5.route ?? [];
if (s4.length <= 2)
continue;
const a4 = OK(e49[o5], t4, n3);
if (a4 !== 0)
for (const l4 of i4) {
if (!s4.every((e50) => NK(e50, t4, l4, n3)))
continue;
const i5 = s4[0]?.z;
if (!s4.every((e50) => e50.z === i5))
continue;
const h4 = { ...r5, route: [s4[0], s4[s4.length - 1]] }, d4 = e49[o5];
e49[o5] = h4, u3(o5, l4, a4) ? c4 += 1 : e49[o5] = d4;
break;
}
}
})({ routes: r3, boundary: i2, margin: s2, geometryCache: t3, fixedCopperGuard: a2 });
zK(r3, t3) <= c3 && h2.splice(0, h2.length, ...r3), (({ routes: e49, boundary: t4, clearanceMargin: n3, fixedCopperGuard: o4 }) => {
for (let i3 = 0;i3 < e49.length; i3 += 1) {
const r4 = e49[i3];
if ((r4.route ?? []).length <= 2)
continue;
const s3 = n3, a3 = Math.max(t4.width / 2 - oQ, 0), c4 = Math.max(t4.height / 2 - oQ, 0), l3 = Math.min(s3, a3), h3 = Math.min(s3, c4), d3 = r4.connectedPadSides ?? [], u3 = t4.minX + (d3.includes("left") ? 0 : l3), p2 = t4.maxX - (d3.includes("right") ? 0 : l3), m2 = t4.minY + (d3.includes("bottom") ? 0 : h3), g2 = t4.maxY - (d3.includes("top") ? 0 : h3), f2 = KJ(r4), _2 = f2.route ?? [];
let y2 = false;
for (let e50 = 1;e50 < _2.length - 1; e50 += 1) {
const t5 = _2[e50];
if (!t5)
continue;
const n4 = Math.min(Math.max(t5.x, u3), p2), o5 = Math.min(Math.max(t5.y, m2), g2);
(Math.abs(n4 - t5.x) > oQ || Math.abs(o5 - t5.y) > oQ) && (t5.x = n4, t5.y = o5, y2 = true);
}
if (!y2)
continue;
if (f2.route = oK(_2), (f2.route?.length ?? 0) < 2)
continue;
const b2 = eQ(e49);
b2[i3] = f2;
const x2 = kK(e49, b2, i3, 0), v2 = kK(e49, b2, i3, n3), I2 = sK({ currentRoutes: e49, candidateRoutes: b2, candidateRouteIndexes: new Set([i3]), maximumAllowedClearance: n3 }).length > 0;
x2 || v2 || I2 || !o4.allows(e49, b2, [i3]) || (e49[i3] = f2);
}
})({ routes: h2, boundary: i2, clearanceMargin: s2, fixedCopperGuard: a2 });
}
const u2 = (({ routes: e49, fixedRoutes: t3 = [], boundary: n3, fixedCopperGuard: o3, adjacentObstacles: i3 = [], clearanceObstacles: r3 = i3, clearance: s3 = 0.1, boundaryMargin: a3 = 0.2, maxCandidates: c3 }) => {
let l3 = e49;
const h3 = new WeakMap;
let d3 = ZQ(l3, s3, r3, t3, undefined, h3);
const u3 = c3 ?? Math.max(256, 96 * d3.conflicts.length), p2 = { routes: e49, initialConflictCount: d3.conflicts.length, finalConflictCount: d3.conflicts.length, candidateCount: 0 };
for (;d3.conflicts.length && p2.candidateCount < u3; ) {
let e50 = false;
const i4 = new Map(d3.conflicts.map((e51) => [e51.key, e51.penetration]));
for (const c4 of d3.conflicts) {
for (const [m2, g2] of [[c4.firstRoute, c4.first], [c4.secondRoute, c4.second]]) {
if (m2 < 0 || m2 >= l3.length)
continue;
const f2 = l3[m2], _2 = new Set([f2.connectionName, f2.rootConnectionName].filter(Boolean)), y2 = r3.filter((e51) => !e51.connectedTo?.some((e52) => _2.has(e52))), b2 = UQ(f2), x2 = XQ([f2], n3, a3).length, v2 = y2.map((e51) => Math.min(...b2.filter((t4) => !e51.zLayers || e51.zLayers.some((e52) => e52 >= t4.minZ && e52 <= t4.maxZ)).map((t4) => qQ(t4, e51))));
for (const _3 of [1.01, 2, 4]) {
const b3 = Math.max(0.01, c4.penetration * _3);
for (const [c5, _4] of [[1, 0], [-1, 0], [0, 1], [0, -1], [Math.SQRT1_2, Math.SQRT1_2], [-Math.SQRT1_2, Math.SQRT1_2], [Math.SQRT1_2, -Math.SQRT1_2], [-Math.SQRT1_2, -Math.SQRT1_2]]) {
if (p2.candidateCount >= u3)
break;
p2.candidateCount++;
const I2 = QQ(f2, g2, c5 * b3, _4 * b3, n3);
if (!I2)
continue;
if (XQ([I2], n3, a3).length > x2)
continue;
const S2 = [...l3];
S2[m2] = I2;
const C2 = ZQ(S2, s3, r3, t3, { evaluation: d3, changedRoute: m2 }, h3);
if (C2.conflicts.length > d3.conflicts.length || C2.score >= d3.score - 0.000000000001)
continue;
if (C2.conflicts.some((e51) => e51.penetration > (i4.get(e51.key) ?? 0) + oQ))
continue;
if (!o3.allows(l3, S2, [m2], false))
continue;
const P2 = UQ(I2);
if (!y2.some((e51, t4) => Math.min(...P2.filter((t5) => !e51.zLayers || e51.zLayers.some((e52) => e52 >= t5.minZ && e52 <= t5.maxZ)).map((t5) => qQ(t5, e51))) < Math.min(s3, v2[t4]) - oQ)) {
l3 = S2, d3 = C2, e50 = true;
break;
}
}
if (e50 || p2.candidateCount >= u3)
break;
}
if (e50 || p2.candidateCount >= u3)
break;
}
if (e50 || p2.candidateCount >= u3)
break;
}
if (!e50)
break;
}
return { ...p2, routes: l3, finalConflictCount: d3.conflicts.length };
})({ fixedRoutes: e48?.fixedHdRoutes, routes: h2, boundary: i2, fixedCopperGuard: a2, adjacentObstacles: e48?.adjacentObstacles, clearanceObstacles: e48?.clearanceObstacles, boundaryMargin: s2 });
return h2.splice(0, h2.length, ...u2.routes), d2.push(((e49, t3, n3) => ({ title: `HighDensityRepair02 Final State (margin=${n3})`, routes: e49, originalRoutes: t3 }))(eQ(h2), eQ(l2), s2)), { boundary: i2, baseRoutes: l2, repairedRoutes: h2, frames: d2, margin: s2, clearanceRepairStats: { nodeClearanceInitialConflictCount: u2.initialConflictCount, nodeClearanceFinalConflictCount: u2.finalConflictCount, nodeClearanceCandidateCount: u2.candidateCount } };
};
var jK = class extends De {
constructor(e48 = {}) {
super(), this.params = e48, this.showBoundryViolationMarkers = e48.showBoundryViolationMarkers ?? false;
}
params;
frames = [];
traceViolationCounts = new WeakMap;
clearanceRepairStats = {};
currentFrameIndex = 0;
showBoundryViolationMarkers;
repairedRoutes = [];
_setup() {
this.buildFrames();
const e48 = this.getCurrentBoundryViolationCount(), t2 = this.getCurrentTraceViolationCount();
this.stats = { ...this.clearanceRepairStats, boundryViolationCount: e48, traceViolationCount: t2, margin: this.params.margin ?? 0.4, frames: this.frames.length, currentFrame: this.currentFrameIndex };
}
_step() {
if (this.frames.length <= 1) {
const e49 = this.getCurrentBoundryViolationCount(), t3 = this.getCurrentTraceViolationCount();
return this.showBoundryViolationMarkers = true, this.stats = { ...this.stats, boundryViolationCount: e49, traceViolationCount: t3 }, void (this.solved = true);
}
this.currentFrameIndex < this.frames.length - 1 && (this.currentFrameIndex += 1);
const e48 = this.getCurrentBoundryViolationCount(), t2 = this.getCurrentTraceViolationCount();
this.stats = { ...this.clearanceRepairStats, boundryViolationCount: e48, traceViolationCount: t2, margin: this.params.margin ?? 0.4, frames: this.frames.length, currentFrame: this.currentFrameIndex, title: this.frames[this.currentFrameIndex]?.title }, this.currentFrameIndex >= this.frames.length - 1 && (this.showBoundryViolationMarkers = true, this.solved = true);
}
getConstructorParams() {
return [this.params];
}
getOutput() {
const e48 = this.getCurrentTraceViolationCount();
return { ...this.clearanceRepairStats, margin: this.params.margin ?? 0.4, repairedRoutes: this.repairedRoutes, frameCount: this.frames.length, traceViolationCount: e48 };
}
setShowBoundryViolationMarkers(e48) {
this.showBoundryViolationMarkers = e48;
}
buildFrames() {
const e48 = FK(this.params.sample, this.params.margin, this.params.captureProgressFrames ?? false, this.params.repairBoundaryDiagonals ?? true);
this.clearanceRepairStats = e48.clearanceRepairStats ?? {}, this.frames = e48.frames, this.repairedRoutes = e48.repairedRoutes;
}
getCurrentFrame() {
const e48 = this.params.sample;
return this.frames[this.currentFrameIndex] ?? { title: "HighDensityRepair02", routes: eQ(e48?.nodeHdRoutes ?? []) };
}
getBoundryViolationsForFrame(e48) {
const t2 = WQ(this.params.sample?.nodeWithPortPoints);
return t2 ? XQ(e48.routes, t2, this.params.margin ?? 0.4) : [];
}
getCurrentBoundryViolationCount() {
return this.getBoundryViolationsForFrame(this.getCurrentFrame()).length;
}
getRouteNetNames(e48) {
if (!e48)
return [];
const t2 = [e48.connectionName, e48.rootConnectionName].filter((e49) => Boolean(e49));
return Array.from(new Set(t2));
}
areRoutesSameNet(e48, t2) {
const n2 = this.getRouteNetNames(e48), o2 = this.getRouteNetNames(t2);
return n2.length !== 0 && o2.length !== 0 && n2.some((e49) => o2.includes(e49));
}
getCurrentTraceViolationCount() {
const e48 = this.getCurrentFrame(), t2 = this.traceViolationCounts.get(e48);
if (t2 !== undefined)
return t2;
const n2 = e48.routes, o2 = new Set(n2.map((e49, t3) => t3)), i2 = LQ(n2, o2, iQ).filter((e49) => !(e49.layers[0] === "via" && e49.layers[1] === "via" || this.areRoutesSameNet(n2[e49.routeIndexes[0]], n2[e49.routeIndexes[1]]))).length;
return this.traceViolationCounts.set(e48, i2), i2;
}
visualize() {
const e48 = this.params.sample, t2 = e48?.nodeWithPortPoints, n2 = e48?.adjacentObstacles ?? [], o2 = this.getCurrentFrame(), i2 = WQ(t2), r2 = i2 && t2?.capacityMeshNodeId ? [{ center: i2.center, width: i2.width, height: i2.height, stroke: "#1d4ed8", fill: "rgba(29, 78, 216, 0.08)", label: t2.capacityMeshNodeId }] : i2 ? [{ center: i2.center, width: i2.width, height: i2.height, stroke: "#1d4ed8", fill: "rgba(29, 78, 216, 0.08)", label: "capacity-node" }] : [], s2 = n2.filter((e49) => e49.center && e49.width && e49.height).map((e49, t3) => ({ center: e49.center, width: e49.width, height: e49.height, stroke: e49.type === "oval" ? "#a855f7" : "#dc2626", fill: e49.type === "oval" ? "rgba(168, 85, 247, 0.12)" : "rgba(220, 38, 38, 0.08)", label: e49.type ? `obstacle:${e49.type}:${t3}` : `obstacle:${t3}` })), a2 = this.showBoundryViolationMarkers && i2 ? this.getBoundryViolationsForFrame(o2).map((e49) => {
const t3 = e49.end.x - e49.start.x, n3 = e49.end.y - e49.start.y, o3 = Math.max(Math.hypot(t3, n3), 0.2), i3 = Math.abs(t3) >= Math.abs(n3);
return { center: { x: (e49.start.x + e49.end.x) / 2, y: (e49.start.y + e49.end.y) / 2 }, width: i3 ? o3 : 0.18, height: i3 ? 0.18 : o3, stroke: "#b45309", fill: "rgba(250, 204, 21, 0.45)", label: `boundry-violation:${e49.routeIndex}:${e49.segmentIndex}` };
}) : [];
const c2 = this.showBoundryViolationMarkers ? IQ(o2.routes, iQ) : [], l2 = [...(t2?.portPoints ?? []).map((e49) => ({ x: e49.x, y: e49.y, color: "#0f766e", label: e49.connectionName ?? e49.portPointId ?? "port-point" })), ...o2.routes.flatMap((e49) => e49.route ?? []).map((e49) => ({ x: e49.x, y: e49.y, color: lQ(e49) === "bottom" ? tQ : "#0ea5e9", label: "" })), ...o2.overlayPoints ?? []], h2 = [...(o2.originalRoutes ?? []).flatMap((e49) => HQ(e49).map((e50) => ({ ...e50, strokeColor: "#111111", strokeWidth: Math.max(0.6 * e50.strokeWidth, 0.05), label: `original:${e50.label}` }))), ...o2.routes.filter((e49) => (e49.route?.length ?? 0) >= 2).flatMap((e49) => HQ(e49)), ...o2.overlayLines ?? []], d2 = o2.routes.flatMap((e49) => (e49.vias ?? []).map((t3) => ({ center: { x: t3.x, y: t3.y }, radius: (t3.diameter ?? e49.viaDiameter ?? 0.3) / 2, stroke: "#7c3aed", fill: "rgba(124, 58, 237, 0.2)", label: e49.connectionName ? `via:${e49.connectionName}` : "via" })));
return d2.push(...c2), { coordinateSystem: "cartesian", title: o2.title, rects: [...r2, ...s2, ...o2.overlayRects ?? [], ...a2], points: l2, lines: h2, circles: d2, arrows: o2.overlayArrows };
}
};
var $K = (e48, t2, n2, o2) => {
const i2 = 0.001, r2 = new Set;
for (const s2 of [t2.route[0], t2.route.at(-1)]) {
if (!s2)
continue;
n2.some((e49) => e49.__zLayers.includes(s2.z) && Math.abs(s2.x - e49.center.x) <= e49.width / 2 + i2 && Math.abs(s2.y - e49.center.y) <= e49.height / 2 + i2 && vo(e49, t2, o2)) && (Math.abs(s2.x - (e48.center.x - e48.width / 2)) <= i2 && r2.add("left"), Math.abs(s2.x - (e48.center.x + e48.width / 2)) <= i2 && r2.add("right"), Math.abs(s2.y - (e48.center.y - e48.height / 2)) <= i2 && r2.add("bottom"), Math.abs(s2.y - (e48.center.y + e48.height / 2)) <= i2 && r2.add("top"));
}
return [...r2];
};
var YK = (e48, t2) => e48.minX <= t2.maxX && e48.maxX >= t2.minX && e48.minY <= t2.maxY && e48.maxY >= t2.minY;
var XK = (e48, t2 = 0) => ({ minX: e48.center.x - e48.width / 2 - t2, maxX: e48.center.x + e48.width / 2 + t2, minY: e48.center.y - e48.height / 2 - t2, maxY: e48.center.y + e48.height / 2 + t2 });
var WK = (e48) => ({ minX: e48.center.x - e48.width / 2, maxX: e48.center.x + e48.width / 2, minY: e48.center.y - e48.height / 2, maxY: e48.center.y + e48.height / 2 });
var VK = (e48, t2, n2 = 0) => {
const o2 = XK(t2, n2);
return e48.x >= o2.minX && e48.x <= o2.maxX && e48.y >= o2.minY && e48.y <= o2.maxY;
};
var HK = (e48, t2, n2) => e48.route.length > 0 && t2.some((t3) => ((e49) => (e49.__zLayers?.length ?? e49.layers?.length ?? 0) > 1)(t3) && vo(t3, e48, n2) && e48.route.every((e49) => ((e50, t4) => {
const n3 = t4.width / 2, o2 = t4.height / 2;
return Math.abs(e50.x - t4.center.x) <= n3 + 0.001 && Math.abs(e50.y - t4.center.y) <= o2 + 0.001;
})(e49, t3)));
var GK = (e48, t2, n2) => {
if (e48.regionId) {
const n3 = t2.findIndex((t3) => t3.capacityMeshNodeId === e48.regionId);
if (n3 !== -1)
return n3;
}
const o2 = [...e48.route.map(({ x: e49, y: t3 }) => ({ x: e49, y: t3 })), ...e48.vias.map(({ x: e49, y: t3 }) => ({ x: e49, y: t3 }))];
for (let e49 = 0;e49 < t2.length; e49++) {
const i2 = t2[e49];
if (o2.every((e50) => VK(e50, i2, n2)))
return e49;
}
return -1;
};
var UK = (e48, t2) => ({ connectionName: e48.connectionName ?? t2.connectionName, rootConnectionName: t2.rootConnectionName, ...t2.startPcbPortId ? { startPcbPortId: t2.startPcbPortId } : {}, ...t2.endPcbPortId ? { endPcbPortId: t2.endPcbPortId } : {}, regionId: e48.capacityMeshNodeId ?? t2.regionId, traceThickness: t2.traceThickness, viaDiameter: e48.viaDiameter ?? t2.viaDiameter, route: e48.route?.map((e49) => ({ x: e49.x, y: e49.y, z: e49.z ?? 0 })) ?? t2.route, vias: e48.vias?.map((e49) => ({ x: e49.x, y: e49.y })) ?? t2.vias, jumpers: t2.jumpers });
var ZK = (e48, t2, n2, o2, i2) => {
const r2 = XK(e48, n2);
return t2.search(r2).filter((e49) => YK(r2, WK(e49))).filter((e49) => !i2 || !o2.some((t3) => vo(e49, t3, i2))).map((e49) => ({ type: e49.type, center: e49.center, width: e49.width, height: e49.height }));
};
var qK = class extends ai {
repairMargin;
minimumTraceWidth;
sampleEntries;
originalHdRoutes;
originalNodeWithPortPoints;
originalObstacles;
obstacleSHI;
colorMap;
connMap;
repairedRoutesByIndex = new Map;
activeSampleIndex = 0;
activeSubSolver = null;
latestVisualization = {};
constructor(e48) {
super(), this.repairMargin = e48.repairMargin ?? 0.2, this.minimumTraceWidth = e48.minimumTraceWidth, this.originalHdRoutes = e48.hdRoutes, this.originalNodeWithPortPoints = e48.nodeWithPortPoints, this.originalObstacles = e48.obstacles, this.obstacleSHI = new QB("flatbush", this.originalObstacles), this.colorMap = e48.colorMap ?? {}, this.connMap = e48.connMap;
const t2 = new Map;
for (let n3 = 0;n3 < e48.hdRoutes.length; n3++) {
if (HK(e48.hdRoutes[n3], e48.obstacles, e48.connMap))
continue;
const o3 = GK(e48.hdRoutes[n3], e48.nodeWithPortPoints, this.repairMargin);
if (o3 === -1)
continue;
const i3 = t2.get(o3) ?? [];
i3.push(n3), t2.set(o3, i3);
}
const n2 = Ns(e48.obstacles, Math.max(2, ...e48.nodeWithPortPoints.flatMap((e49) => e49.availableZ?.map((e50) => e50 + 1) ?? []))), o2 = e48.hdRoutes.map((t3) => ((e49, t4, n3) => ({ capacityMeshNodeId: e49.regionId, connectionName: e49.connectionName, rootConnectionName: t4?.getNetConnectedToId(e49.connectionName) ?? e49.rootConnectionName, route: e49.route.map((e50) => ({ x: e50.x, y: e50.y, z: e50.z })), traceThickness: Math.max(e49.traceThickness, n3 ?? e49.traceThickness), vias: e49.vias.map((t5) => ({ x: t5.x, y: t5.y, diameter: e49.viaDiameter })), viaDiameter: e49.viaDiameter }))(t3, e48.connMap, e48.minimumTraceWidth)), i2 = new JB(e48.hdRoutes.length);
for (const [t3, n3] of e48.hdRoutes.entries()) {
const e49 = [...n3.route, ...n3.vias];
if (e49.length === 0)
throw new Error(`High density repair route "${n3.connectionName}" has no points`);
const r3 = Math.max(o2[t3].traceThickness, n3.viaDiameter) / 2;
i2.insert({ routeIndex: t3 }, Math.min(...e49.map((e50) => e50.x)) - r3, Math.min(...e49.map((e50) => e50.y)) - r3, Math.max(...e49.map((e50) => e50.x)) + r3, Math.max(...e49.map((e50) => e50.y)) + r3);
}
e48.hdRoutes.length > 0 && i2.finish();
const r2 = Array.from(t2.entries()).map(([t3, r3]) => {
const s2 = e48.nodeWithPortPoints[t3], a2 = Math.max(...r3.map((t4) => Math.max(o2[t4].traceThickness, e48.hdRoutes[t4].viaDiameter) / 2)), c2 = XK(s2, Math.max(this.repairMargin, a2 + 0.1)), l2 = new Set(r3);
return { node: s2, routeIndexes: r3, sample: { nodeWithPortPoints: { capacityMeshNodeId: s2.capacityMeshNodeId, center: s2.center, width: s2.width, height: s2.height, portPoints: s2.portPoints.map((e49) => ({ x: e49.x, y: e49.y, z: e49.z, connectionName: e49.connectionName, portPointId: e49.portPointId, prevPortPointId: e49.prevPortPointId, nextPortPointId: e49.nextPortPointId })) }, nodeHdRoutes: r3.map((t4) => ({ ...o2[t4], ...e48.connMap ? { connectedPadSides: $K(s2, e48.hdRoutes[t4], n2, e48.connMap) } : {} })), fixedHdRoutes: i2.search(c2.minX, c2.minY, c2.maxX, c2.maxY).filter(({ routeIndex: e49 }) => !l2.has(e49)).map(({ routeIndex: e49 }) => o2[e49]), clearanceObstacles: n2.filter((e49) => YK(c2, WK(e49))).map((t4) => ({ type: t4.type, center: t4.center, width: t4.width, height: t4.height, zLayers: t4.__zLayers, connectedTo: [...new Set(t4.connectedTo.flatMap((t5) => {
const n3 = e48.connMap?.getNetConnectedToId(t5);
return n3 ? [t5, n3] : [t5];
}))] })), adjacentObstacles: ZK(s2, this.obstacleSHI, this.repairMargin, r3.map((t4) => e48.hdRoutes[t4]), e48.connMap) } };
});
this.sampleEntries = r2, this.MAX_ITERATIONS = Math.max(1000 * this.sampleEntries.length, 1e5), this.stats = { sampleCount: this.sampleEntries.length, repairedNodeCount: 0, repairedRouteCount: 0 };
}
getSolverName() {
return "Pipeline4HighDensityRepairSolver";
}
getConstructorParams() {
return [{ nodeWithPortPoints: this.sampleEntries.map((e48) => e48.node), hdRoutes: this.originalHdRoutes, obstacles: this.originalObstacles, repairMargin: this.repairMargin, minimumTraceWidth: this.minimumTraceWidth, colorMap: this.colorMap, connMap: this.connMap }];
}
_step() {
const e48 = this.sampleEntries[this.activeSampleIndex];
if (e48) {
if (this.activeSubSolver) {
if (this.activeSubSolver.step(), this.latestVisualization = this.activeSubSolver.visualize(), this.activeSubSolver.failed)
return this.failed = true, this.error = this.activeSubSolver.error ?? `High density repair failed for node ${e48.node.capacityMeshNodeId}`, void (this.activeSubSolver = null);
if (!this.activeSubSolver.solved)
return;
const t2 = this.activeSubSolver.getOutput().repairedRoutes, n2 = { nodeClearanceInitialConflictCount: Number(this.stats.nodeClearanceInitialConflictCount ?? 0) + Number(this.activeSubSolver.stats.nodeClearanceInitialConflictCount ?? 0), nodeClearanceFinalConflictCount: Number(this.stats.nodeClearanceFinalConflictCount ?? 0) + Number(this.activeSubSolver.stats.nodeClearanceFinalConflictCount ?? 0), nodeClearanceCandidateCount: Number(this.stats.nodeClearanceCandidateCount ?? 0) + Number(this.activeSubSolver.stats.nodeClearanceCandidateCount ?? 0) };
for (let n3 = 0;n3 < e48.routeIndexes.length; n3++) {
const o2 = e48.routeIndexes[n3], i2 = this.originalHdRoutes[o2], r2 = t2[n3];
this.repairedRoutesByIndex.set(o2, r2 ? UK(r2, i2) : i2);
}
return this.activeSubSolver = null, this.activeSampleIndex += 1, this.stats = { ...n2, sampleCount: this.sampleEntries.length, repairedNodeCount: this.activeSampleIndex, repairedRouteCount: this.repairedRoutesByIndex.size }, void (this.activeSampleIndex >= this.sampleEntries.length && (this.solved = true));
}
this.activeSubSolver = new jK({ repairBoundaryDiagonals: false, sample: e48.sample, margin: this.repairMargin }), this.latestVisualization = this.activeSubSolver.visualize();
} else
this.solved = true;
}
getOutput() {
return this.originalHdRoutes.map((e48, t2) => this.repairedRoutesByIndex.get(t2) ?? e48);
}
visualize() {
if (this.activeSubSolver)
return this.activeSubSolver.visualize();
if (!this.solved)
return this.latestVisualization;
const e48 = [], t2 = [];
for (const n2 of this.getOutput()) {
const o2 = this.colorMap[n2.connectionName] ?? "#0ea5e9";
for (let t3 = 0;t3 < n2.route.length - 1; t3++) {
const i2 = n2.route[t3], r2 = n2.route[t3 + 1];
i2.z === r2.z && e48.push({ points: [{ x: i2.x, y: i2.y }, { x: r2.x, y: r2.y }], strokeColor: i2.z === 0 ? o2 : Oo(o2, 0.5), strokeWidth: n2.traceThickness, layer: `z${i2.z}`, strokeDash: i2.z !== 0 ? [0.1, 0.3] : undefined });
}
for (const e49 of n2.vias)
t2.push({ center: { x: e49.x, y: e49.y }, radius: n2.viaDiameter / 2, stroke: o2, fill: "rgba(14,165,233,0.12)" });
}
return { title: "Pipeline4 High Density Repair", lines: e48, circles: t2 };
}
};
var JK = 0.000001;
var QK = ({ startGap: e48, endGap: t2, segmentGap: n2, requiredGap: o2 }) => {
const i2 = e48 < o2 && t2 >= o2 - JK && n2 >= e48 - JK, r2 = t2 < o2 && e48 >= o2 - JK && n2 >= t2 - JK, s2 = e48 < o2 && t2 < o2 && n2 >= Math.min(e48, t2) - JK;
return i2 || r2 || s2;
};
var KK = class {
minClearance;
rootsByConnection = new Map;
sameNetCache = new Map;
segments = [];
vias = [];
segmentIndexesByLayer;
viaIndex;
constructor({ hdRoutes: e48, minClearance: t2 = 0.1 }) {
this.minClearance = t2;
for (const t3 of e48)
this.addRoute(t3);
this.buildSpatialIndexes();
}
addRoute(e48) {
const t2 = this.rootsByConnection.get(e48.connectionName) ?? new Set;
t2.add(e48.rootConnectionName ?? e48.connectionName), this.rootsByConnection.set(e48.connectionName, t2), this.sameNetCache.clear();
for (let t3 = 0;t3 < e48.route.length - 1; t3 += 1) {
const n2 = e48.route[t3], o2 = e48.route[t3 + 1];
if (n2.z !== o2.z)
continue;
if (n2.insideJumperPad && o2.insideJumperPad)
continue;
const i2 = { connectionName: e48.connectionName, start: n2, end: o2, traceThickness: e48.traceThickness };
this.segments.push(i2), this.insertSegmentIntoSpatialIndex(i2);
}
for (const t3 of e48.vias) {
const n2 = { connectionName: e48.connectionName, x: t3.x, y: t3.y, diameter: e48.viaDiameter };
this.vias.push(n2), this.insertViaIntoSpatialIndex(n2);
}
}
insertSegmentIntoSpatialIndex(e48) {
if (!this.segmentIndexesByLayer)
return;
let t2 = this.segmentIndexesByLayer.get(e48.start.z);
t2 || (t2 = new qB, this.segmentIndexesByLayer.set(e48.start.z, t2));
const n2 = e48.traceThickness / 2;
t2.insert(e48, Math.min(e48.start.x, e48.end.x) - n2, Math.min(e48.start.y, e48.end.y) - n2, Math.max(e48.start.x, e48.end.x) + n2, Math.max(e48.start.y, e48.end.y) + n2);
}
insertViaIntoSpatialIndex(e48) {
if (!this.viaIndex)
return;
const t2 = e48.diameter / 2;
this.viaIndex.insert(e48, e48.x - t2, e48.y - t2, e48.x + t2, e48.y + t2);
}
buildSpatialIndexes() {
this.segmentIndexesByLayer = new Map;
const e48 = new Map;
for (const t2 of this.segments) {
const n2 = e48.get(t2.start.z);
n2 ? n2.push(t2) : e48.set(t2.start.z, [t2]);
}
for (const [t2, n2] of e48) {
const e49 = new qB;
e49.bulkLoad(n2.map((e50) => {
const t3 = e50.traceThickness / 2;
return { item: e50, minX: Math.min(e50.start.x, e50.end.x) - t3, minY: Math.min(e50.start.y, e50.end.y) - t3, maxX: Math.max(e50.start.x, e50.end.x) + t3, maxY: Math.max(e50.start.y, e50.end.y) + t3 };
})), this.segmentIndexesByLayer.set(t2, e49);
}
this.viaIndex = new qB, this.viaIndex.bulkLoad(this.vias.map((e49) => {
const t2 = e49.diameter / 2;
return { item: e49, minX: e49.x - t2, minY: e49.y - t2, maxX: e49.x + t2, maxY: e49.y + t2 };
}));
}
areSameNet(e48, t2) {
if (e48 === t2)
return true;
const n2 = this.sameNetCache.get(e48)?.get(t2);
if (n2 !== undefined)
return n2;
const o2 = this.rootsByConnection.get(e48), i2 = this.rootsByConnection.get(t2);
let r2 = false;
if (o2 && i2) {
for (const e49 of o2)
if (i2.has(e49)) {
r2 = true;
break;
}
}
let s2 = this.sameNetCache.get(e48);
return s2 || (s2 = new Map, this.sameNetCache.set(e48, s2)), s2.set(t2, r2), r2;
}
isSegmentClear({ connectionName: e48, start: t2, end: n2, traceThickness: o2 }) {
const i2 = o2 / 2, r2 = this.minClearance + i2, s2 = Math.min(t2.x, n2.x) - r2, a2 = Math.min(t2.y, n2.y) - r2, c2 = Math.max(t2.x, n2.x) + r2, l2 = Math.max(t2.y, n2.y) + r2, h2 = this.segmentIndexesByLayer?.get(t2.z)?.search(s2, a2, c2, l2) ?? [];
for (const o3 of h2) {
if (this.areSameNet(e48, o3.connectionName))
continue;
const r3 = this.minClearance + i2 + o3.traceThickness / 2, s3 = BJ(t2, n2, o3.start, o3.end);
if (s3 < r3 && !QK({ startGap: xt(t2, o3.start, o3.end), endGap: xt(n2, o3.start, o3.end), segmentGap: s3, requiredGap: r3 }))
return false;
}
const d2 = this.viaIndex?.search(s2, a2, c2, l2) ?? [];
for (const o3 of d2) {
if (this.areSameNet(e48, o3.connectionName))
continue;
const r3 = this.minClearance + i2 + o3.diameter / 2, s3 = xt(o3, t2, n2);
if (s3 < r3 && !QK({ startGap: Math.hypot(t2.x - o3.x, t2.y - o3.y), endGap: Math.hypot(n2.x - o3.x, n2.y - o3.y), segmentGap: s3, requiredGap: r3 }))
return false;
}
return true;
}
};
var e0 = 0.000000001;
var t0 = 1.25;
var n0 = (e48, t2) => e48 < t2 ? -1 : e48 > t2 ? 1 : 0;
var o0 = (e48, t2) => n0(e48.z, t2.z) || n0(e48.x, t2.x) || n0(e48.y, t2.y);
var i0 = (e48) => `${e48.z.toFixed(6)}:${e48.x.toFixed(6)}:${e48.y.toFixed(6)}`;
var r0 = (e48) => {
const t2 = e48.route.map(i0).join("|"), n2 = [...e48.route].reverse().map(i0).join("|");
return t2 <= n2 ? t2 : n2;
};
var s0 = (e48, t2) => {
const n2 = e48.connectionName.localeCompare(t2.connectionName);
if (n2 !== 0)
return n2;
const o2 = (e48.rootConnectionName ?? "").localeCompare(t2.rootConnectionName ?? "");
if (o2 !== 0)
return o2;
const i2 = r0(e48).localeCompare(r0(t2));
return i2 !== 0 ? i2 : n0(e48.traceThickness, t2.traceThickness) || n0(e48.viaDiameter, t2.viaDiameter) || n0(e48.route.length, t2.route.length) || n0(e48.vias.length, t2.vias.length) || n0(e48.jumpers?.length ?? 0, t2.jumpers?.length ?? 0);
};
var a0 = 1e5;
var c0 = 0.001;
var l0 = 1.000000001;
var h0 = class extends ai {
getSolverName() {
return "SingleHighDensityRouteStitchSolver3";
}
mergedHdRoute;
remainingHdRoutes;
start;
end;
colorMap;
allowedLayerTransitionPointKeys;
isStitchSegmentClear;
stitchClearanceMode;
isPlanarStitchClear(e48, t2) {
return this.isStitchSegmentClear({ connectionName: this.mergedHdRoute.connectionName, start: e48, end: t2, traceThickness: this.mergedHdRoute.traceThickness });
}
constructor(e48) {
super();
const t2 = [...e48.hdRoutes].sort(s0);
if (this.remainingHdRoutes = t2, this.colorMap = e48.colorMap ?? {}, this.allowedLayerTransitionPointKeys = e48.allowedLayerTransitionPointKeys, this.isStitchSegmentClear = e48.isStitchSegmentClear, this.stitchClearanceMode = e48.stitchClearanceMode, t2.length === 0) {
this.start = e48.start, this.end = e48.end;
const n3 = e48.defaultTraceThickness ?? 0.15, o3 = [{ x: e48.start.x, y: e48.start.y, z: e48.start.z }], i3 = [];
if (e48.start.z !== e48.end.z) {
if (e48.allowedLayerTransitionPointKeys && !e48.allowedLayerTransitionPointKeys.has(BH(e48.start)))
return this.failed = true, void (this.error = `Layer transition at ${BH(e48.start)} is not allowed`);
o3.push({ x: e48.start.x, y: e48.start.y, z: e48.end.z }), i3.push({ x: e48.start.x, y: e48.start.y });
}
const r3 = o3[o3.length - 1], s3 = { x: e48.end.x, y: e48.end.y, z: e48.end.z }, a3 = { connectionName: e48.connectionName, start: r3, end: s3, traceThickness: n3 };
return vt(r3, s3) > c0 && !this.isStitchSegmentClear(a3) && this.stitchClearanceMode === "require_clear" ? (this.failed = true, void (this.error = `Terminal stitch for "${e48.connectionName}" violates copper clearance`)) : (o3.push(s3), this.mergedHdRoute = { connectionName: e48.connectionName, ...e48.preserveTerminalPcbPortIds && e48.start.pcb_port_id ? { startPcbPortId: e48.start.pcb_port_id } : {}, ...e48.preserveTerminalPcbPortIds && e48.end.pcb_port_id ? { endPcbPortId: e48.end.pcb_port_id } : {}, rootConnectionName: t2[0]?.rootConnectionName, route: o3, vias: i3, jumpers: [], viaDiameter: e48.defaultViaDiameter ?? 0.3, traceThickness: n3 }, void (this.solved = true));
}
const n2 = new Set((e48.preserveTerminalPcbPortIds ? [e48.start.pcb_port_id, e48.end.pcb_port_id] : []).filter((e49) => e49 !== undefined));
if (e48.preserveTerminalPcbPortIds && e48.start.pcb_port_id && e48.start.pcb_port_id === e48.end.pcb_port_id)
throw new Error(`SingleHighDensityRouteStitchSolver3 received duplicate PCB terminal "${e48.start.pcb_port_id}" for "${e48.connectionName}"`);
const o2 = t2.flatMap((e49) => [e49.startPcbPortId, e49.endPcbPortId]).filter((e49) => e49 !== undefined);
if (n2.size > 0) {
for (const t3 of o2)
if (!n2.has(t3))
throw new Error(`SingleHighDensityRouteStitchSolver3 found unknown PCB terminal "${t3}" on "${e48.connectionName}"`);
}
let i2 = 1 / 0, r2 = t2[0], s2 = "start-to-end";
for (const n3 of t2) {
const t3 = n3.route[0], o3 = n3.route[n3.route.length - 1], a3 = vt(e48.start, t3), c3 = vt(e48.start, o3), l3 = vt(e48.end, t3), h3 = vt(e48.end, o3), d3 = Math.min(a3, c3, l3, h3);
(d3 < i2 - e0 || Math.abs(d3 - i2) <= e0 && s0(n3, r2) < 0) && (i2 = d3, r2 = n3, s2 = Math.min(l3, h3) < Math.min(a3, c3) - e0 || Math.abs(Math.min(l3, h3) - Math.min(a3, c3)) <= e0 && o0(e48.end, e48.start) < 0 ? "end-to-start" : "start-to-end");
}
s2 === "start-to-end" ? (this.start = e48.start, this.end = e48.end) : (this.start = e48.end, this.end = e48.start);
const a2 = r2.route[0], c2 = r2.route[r2.route.length - 1], l2 = vt(this.start, a2), h2 = vt(this.start, c2), d2 = l2 < h2 - e0 || Math.abs(l2 - h2) <= e0 && o0(a2, c2) <= 0 ? a2 : c2, u2 = d2 === a2 ? r2.startPcbPortId : r2.endPcbPortId;
if (u2 && this.start.pcb_port_id && u2 !== this.start.pcb_port_id)
throw new Error(`SingleHighDensityRouteStitchSolver3 terminal identity disagrees with route orientation for "${e48.connectionName}"`);
this.mergedHdRoute = { connectionName: e48.connectionName, ...e48.preserveTerminalPcbPortIds && this.start.pcb_port_id ? { startPcbPortId: this.start.pcb_port_id } : {}, ...e48.preserveTerminalPcbPortIds && this.end.pcb_port_id ? { endPcbPortId: this.end.pcb_port_id } : {}, rootConnectionName: r2.rootConnectionName, route: [{ x: this.start.x, y: this.start.y, z: d2.z }], vias: [], jumpers: [], viaDiameter: r2.viaDiameter, traceThickness: r2.traceThickness };
}
getDisjointedRoute() {
for (const e48 of this.remainingHdRoutes) {
if ([e48.route[0], e48.route[e48.route.length - 1]].some((t2) => !this.remainingHdRoutes.some((n2) => {
if (n2 === e48)
return false;
return [n2.route[0], n2.route[n2.route.length - 1]].some((e49) => e49.z === t2.z && vt(t2, e49) < 0.001);
})))
return { firstRoute: e48 };
}
return { firstRoute: this.remainingHdRoutes[0] };
}
_step() {
const e48 = this.mergedHdRoute.route.at(-1), t2 = this.mergedHdRoute.endPcbPortId !== undefined && e48.z === this.end.z && vt(e48, this.end) < c0;
if (this.remainingHdRoutes.length === 0 || t2) {
const e49 = this.mergedHdRoute.route[this.mergedHdRoute.route.length - 1], t3 = { ...this.end, z: e49.z }, n3 = vt(e49, t3);
if (n3 > c0 && n3 <= t0) {
if (!this.isPlanarStitchClear(e49, t3) && this.stitchClearanceMode === "require_clear")
return this.failed = true, 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: e49.z });
}
return void (this.solved = true);
}
const n2 = this.mergedHdRoute.route[this.mergedHdRoute.route.length - 1];
let o2 = -1, i2 = "first", r2 = 1 / 0, s2 = false;
for (let e49 = 0;e49 < this.remainingHdRoutes.length; e49++) {
const t3 = this.remainingHdRoutes[e49], a3 = t3.route[0], c3 = t3.route[t3.route.length - 1], l2 = vt(n2, a3), h2 = vt(n2, c3);
let d2 = 1 / 0;
if (n2.z === a3.z) {
if (l2 < c0)
d2 = l2;
else if (l2 <= 1) {
const e50 = this.isPlanarStitchClear(n2, a3);
if (e50 || this.stitchClearanceMode === "prefer_clear") {
d2 = a0 + (e50 ? 0 : l0) + l2;
} else
s2 = true;
}
} else
l2 < c0 && (!this.allowedLayerTransitionPointKeys || this.allowedLayerTransitionPointKeys.has(BH(a3))) && (d2 = 1000 + l2);
d2 < r2 && (r2 = d2, o2 = e49, i2 = "first");
let u2 = 1 / 0;
if (n2.z === c3.z) {
if (h2 < c0)
u2 = h2;
else if (h2 <= 1) {
const e50 = this.isPlanarStitchClear(n2, c3);
if (e50 || this.stitchClearanceMode === "prefer_clear") {
u2 = a0 + (e50 ? 0 : l0) + h2;
} else
s2 = true;
}
} else
h2 < c0 && (!this.allowedLayerTransitionPointKeys || this.allowedLayerTransitionPointKeys.has(BH(c3))) && (u2 = 1000 + h2);
u2 < r2 && (r2 = u2, o2 = e49, i2 = "last");
}
if (o2 === -1)
return s2 ? (this.failed = true, void (this.error = `Route stitch for "${this.mergedHdRoute.connectionName}" violates copper clearance`)) : void (this.remainingHdRoutes = []);
const a2 = this.remainingHdRoutes[o2];
let c2;
this.remainingHdRoutes.splice(o2, 1), c2 = i2 === "first" ? a2.route : ((e49) => {
const t3 = [...e49].reverse().map((e50) => {
const { toNextSegmentType: t4, ...n3 } = e50;
return n3;
});
for (let n3 = 0;n3 < e49.length - 1; n3++) {
const o3 = e49[n3]?.toNextSegmentType;
if (!o3)
continue;
const i3 = e49.length - n3 - 2;
t3[i3] = { ...t3[i3], toNextSegmentType: o3 };
}
return t3;
})(a2.route), c2.length > 0 && vt(n2, c2[0]) < c0 && n2.z === c2[0].z ? (c2[0].toNextSegmentType && (n2.toNextSegmentType = c2[0].toNextSegmentType), this.mergedHdRoute.route.push(...c2.slice(1))) : this.mergedHdRoute.route.push(...c2), this.mergedHdRoute.vias.push(...a2.vias), a2.jumpers && this.mergedHdRoute.jumpers.push(...a2.jumpers);
}
visualize() {
const e48 = { points: [], lines: [], circles: [], rects: [], title: "Single High Density Route Stitch Solver 3" };
if (e48.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) {
e48.lines?.push({ points: this.mergedHdRoute.route.map((e49) => ({ x: e49.x, y: e49.y })), strokeColor: "green" });
for (const t2 of this.mergedHdRoute.route)
e48.points?.push({ x: t2.x, y: t2.y, color: "green" });
for (const t2 of this.mergedHdRoute.vias)
e48.circles?.push({ center: { x: t2.x, y: t2.y }, radius: this.mergedHdRoute.viaDiameter / 2, fill: "green" });
if (this.mergedHdRoute.jumpers && this.mergedHdRoute.jumpers.length > 0) {
const t2 = Az(this.mergedHdRoute.jumpers, { color: "green", label: this.mergedHdRoute.connectionName });
e48.rects.push(...t2.rects ?? []), e48.lines.push(...t2.lines ?? []);
}
}
for (const t2 of this.remainingHdRoutes) {
e48.lines?.push({ points: t2.route.map((e49) => ({ x: e49.x, y: e49.y })), strokeColor: "orange" });
for (const n2 of t2.route)
e48.points?.push({ x: n2.x, y: n2.y, color: "orange" });
for (const n2 of t2.vias)
e48.circles?.push({ center: { x: n2.x, y: n2.y }, radius: t2.viaDiameter / 2, fill: "orange" });
if (t2.jumpers && t2.jumpers.length > 0) {
const n2 = Az(t2.jumpers, { color: "orange", label: t2.connectionName });
e48.rects.push(...n2.rects ?? []), e48.lines.push(...n2.lines ?? []);
}
}
return e48;
}
};
var d0 = class {
constructor(e48 = false) {
this.preferSameLayerTerminalEndpoints = e48;
}
preferSameLayerTerminalEndpoints;
endpointClusters = new Map;
getEndpointKey(e48, t2) {
const n2 = this.endpointClusters.get(e48) ?? [];
let o2, i2 = 1 / 0;
for (const e49 of n2) {
if (e49.point.z !== t2.z)
continue;
const n3 = vt(e49.point, t2);
n3 <= 0.1 && (n3 < i2 - e0 || Math.abs(n3 - i2) <= e0 && (!o2 || o0(e49.point, o2.point) < 0)) && (o2 = e49, i2 = n3);
}
if (o2)
return o2.key;
const r2 = `${e48}:endpoint_${n2.length}`;
return n2.push({ key: r2, point: { x: t2.x, y: t2.y, z: t2.z } }), this.endpointClusters.set(e48, n2), r2;
}
getClusters(e48) {
return this.endpointClusters.get(e48) ?? [];
}
getClosestEndpointKey(e48, t2, n2) {
const o2 = t2.flatMap((e49) => [e49.route[0], e49.route[e49.route.length - 1]]), i2 = o2.filter((e49) => e49.z === n2.z), r2 = this.preferSameLayerTerminalEndpoints && i2.length > 0 ? i2 : o2;
let s2 = null, a2 = null, c2 = 1 / 0;
for (const t3 of r2) {
const o3 = vt(n2, t3), i3 = this.getEndpointKey(e48, t3);
(o3 < c2 - e0 || Math.abs(o3 - c2) <= e0 && (s2 === null || i3.localeCompare(s2) < 0 || i3 === s2 && a2 !== null && o0(t3, a2) < 0)) && (c2 = o3, s2 = i3, a2 = t3);
}
return s2;
}
};
var u0 = (e48, t2, n2) => {
const o2 = e48.get(t2) ?? [];
o2.some((e49) => e49.nextHash === n2.nextHash && e49.routeIndex === n2.routeIndex) || (o2.push(n2), e48.set(t2, o2));
};
var p0 = (e48) => {
const t2 = [...e48.possibleEndpoints].sort(o0), n2 = t2.reduce((t3, n3) => {
const o3 = vt(n3, e48.globalStart), i3 = vt(t3, e48.globalStart);
return o3 < i3 - e0 || Math.abs(o3 - i3) <= e0 && o0(n3, t3) < 0 ? n3 : t3;
}), o2 = t2.filter((e49) => e49 !== n2), i2 = (o2.length > 0 ? o2 : e48.possibleEndpoints).reduce((t3, n3) => {
const o3 = vt(n3, e48.globalEnd), i3 = vt(t3, e48.globalEnd);
return o3 < i3 - e0 || Math.abs(o3 - i3) <= e0 && o0(n3, t3) < 0 ? n3 : t3;
});
return { start: n2, end: i2 };
};
var m0 = (e48) => {
const t2 = [...e48.terminals].sort(o0);
let n2 = t2[0], o2 = vt(e48.islandEndpoint, n2);
for (const i2 of t2.slice(1)) {
const t3 = vt(e48.islandEndpoint, i2);
(t3 < o2 - e0 || Math.abs(t3 - o2) <= e0 && o0(i2, n2) < 0) && (n2 = i2, o2 = t3);
}
return o2 <= t0 ? n2 : e48.islandEndpoint;
};
var g0 = (e48) => {
if (e48.hdRoutes.length <= 2)
return e48.hdRoutes;
const t2 = [...e48.hdRoutes].sort(s0), n2 = e48.endpointIndex.getClosestEndpointKey(e48.connectionName, t2, e48.start), o2 = e48.endpointIndex.getClosestEndpointKey(e48.connectionName, t2, e48.end);
if (!n2 || !o2 || n2 === o2)
return t2;
const i2 = new Map;
for (let n3 = 0;n3 < t2.length; n3++) {
const o3 = t2[n3], r3 = e48.endpointIndex.getEndpointKey(e48.connectionName, o3.route[0]), s3 = e48.endpointIndex.getEndpointKey(e48.connectionName, o3.route[o3.route.length - 1]);
u0(i2, r3, { nextHash: s3, routeIndex: n3 }), u0(i2, s3, { nextHash: r3, routeIndex: n3 });
}
const r2 = [...e48.endpointIndex.getClusters(e48.connectionName)].sort((e49, t3) => o0(e49.point, t3.point));
for (let e49 = 0;e49 < r2.length; e49++) {
const t3 = r2[e49];
for (let n3 = e49 + 1;n3 < r2.length; n3++) {
const e50 = r2[n3];
t3.point.z === e50.point.z && (vt(t3.point, e50.point) > 1 || (u0(i2, t3.key, { nextHash: e50.key, routeIndex: null }), u0(i2, e50.key, { nextHash: t3.key, routeIndex: null })));
}
}
for (const [e49, n3] of i2.entries())
i2.set(e49, [...n3].sort((e50, n4) => {
if (e50.routeIndex === null && n4.routeIndex !== null)
return 1;
if (e50.routeIndex !== null && n4.routeIndex === null)
return -1;
if (e50.routeIndex !== null && n4.routeIndex !== null) {
const o3 = s0(t2[e50.routeIndex], t2[n4.routeIndex]);
if (o3 !== 0)
return o3;
}
return e50.nextHash.localeCompare(n4.nextHash);
}));
const s2 = [n2], a2 = new Set([n2]), c2 = new Map;
for (;s2.length > 0; ) {
const e49 = s2.shift();
if (e49 === o2)
break;
for (const t3 of i2.get(e49) ?? [])
a2.has(t3.nextHash) || (a2.add(t3.nextHash), c2.set(t3.nextHash, { prevHash: e49, routeIndex: t3.routeIndex }), s2.push(t3.nextHash));
}
if (!a2.has(o2))
return t2;
const l2 = [];
let h2 = o2;
for (;h2 !== n2; ) {
const e49 = c2.get(h2);
if (!e49)
return t2;
e49.routeIndex !== null && l2.push(e49.routeIndex), h2 = e49.prevHash;
}
if (l2.length === 0)
return e48.hdRoutes;
const d2 = l2.reverse().map((e49) => t2[e49]);
return d2.length > 0 && !e48.canStitchBetweenTerminals({ connectionName: e48.connectionName, hdRoutes: d2, start: e48.start, end: e48.end }) ? t2 : d2;
};
var f0 = class extends ai {
getSolverName() {
return "MultipleHighDensityRouteStitchSolver3";
}
unsolvedRoutes;
activeSolver = null;
mergedHdRoutes = [];
colorMap = {};
defaultTraceThickness;
defaultViaDiameter;
allowedLayerTransitionPointKeys;
preserveTerminalPcbPortIds;
endpointIndex;
clearanceValidator;
canStitchBetweenTerminals(e48) {
const t2 = new h0({ connectionName: e48.connectionName, hdRoutes: e48.hdRoutes, start: e48.start, end: e48.end, colorMap: this.colorMap, defaultTraceThickness: this.defaultTraceThickness, defaultViaDiameter: this.defaultViaDiameter, allowedLayerTransitionPointKeys: this.allowedLayerTransitionPointKeys, preserveTerminalPcbPortIds: this.preserveTerminalPcbPortIds, isStitchSegmentClear: (e49) => this.clearanceValidator.isSegmentClear(e49), stitchClearanceMode: "require_clear" });
for (;!t2.solved && !t2.failed && t2.iterations < t2.MAX_ITERATIONS; )
t2.step();
if (t2.failed)
return false;
const n2 = t2.mergedHdRoute.route[0], o2 = t2.mergedHdRoute.route[t2.mergedHdRoute.route.length - 1];
return n2.z === t2.start.z && o2.z === t2.end.z && vt(n2, t2.start) + vt(o2, t2.end) <= t0;
}
getSharedRootPathRoutes(e48) {
const t2 = e48.rootConnectionName;
if (!t2)
return null;
const n2 = new Set(e48.hdRoutes), o2 = e48.allHdRoutes.filter((e49) => (e49.rootConnectionName ?? e49.connectionName) === t2);
if (o2.every((e49) => n2.has(e49)))
return null;
const i2 = g0({ connectionName: e48.connectionName, hdRoutes: o2, start: e48.start, end: e48.end, endpointIndex: this.endpointIndex, canStitchBetweenTerminals: (e49) => this.canStitchBetweenTerminals(e49) });
return !i2.some((e49) => !n2.has(e49)) || i2.length >= o2.length ? null : i2;
}
constructor(e48) {
super(), this.endpointIndex = new d0(e48.preferSameLayerTerminalEndpoints), this.colorMap = e48.colorMap ?? {}, this.allowedLayerTransitionPointKeys = e48.allowedLayerTransitionPointKeys, this.preserveTerminalPcbPortIds = e48.preserveTerminalPcbPortIds ?? false;
const t2 = [...e48.hdRoutes].sort(s0);
this.clearanceValidator = new KK({ hdRoutes: t2 });
const n2 = t2[0];
this.defaultTraceThickness = n2?.traceThickness ?? 0.15, this.defaultViaDiameter = n2?.viaDiameter ?? e48.defaultViaDiameter ?? 0.3;
const o2 = new Rz({}), i2 = [], r2 = new Map;
for (let e49 = 0;e49 < t2.length; e49++) {
const n3 = t2[e49], o3 = n3.route[0], r3 = n3.route[n3.route.length - 1];
i2.push([`route_island_${e49}`, this.endpointIndex.getEndpointKey(n3.connectionName, o3), this.endpointIndex.getEndpointKey(n3.connectionName, r3)]);
}
o2.addConnections(i2);
for (const e49 of i2)
for (const t3 of e49.slice(1))
r2.set(t3, (r2.get(t3) ?? 0) + 1);
this.unsolvedRoutes = [];
const s2 = Array.from(new Set(Object.values(o2.idToNetMap)));
for (const n3 of s2) {
const i3 = o2.getIdsConnectedToNet(n3), s3 = t2.filter((e49, t3) => i3.includes(`route_island_${t3}`));
if (s3.length === 0)
continue;
const a3 = e48.connections.find((e49) => e49.name === s3[0].connectionName), c2 = s3.flatMap((e49) => [e49.route[0], e49.route[e49.route.length - 1]]), l2 = new Map, h2 = [];
for (const e49 of c2) {
const t3 = this.endpointIndex.getEndpointKey(s3[0].connectionName, e49);
l2.has(t3) || l2.set(t3, e49), r2.get(t3) === 1 && h2.push(e49);
}
const d2 = h2.length > 0 ? h2 : [...l2.values()];
if (d2.length === 0)
continue;
let u2, p2;
if (d2.length >= 2) {
const t3 = { ...a3.pointsToConnect[0], z: go(So(a3.pointsToConnect[0]), e48.layerCount) }, n4 = { ...a3.pointsToConnect[1], z: go(So(a3.pointsToConnect[1]), e48.layerCount) };
(({ start: u2, end: p2 } = p0({ possibleEndpoints: d2, globalStart: t3, globalEnd: n4 }))), vt(u2, a3.pointsToConnect[1]) < vt(p2, a3.pointsToConnect[0]) && ([u2, p2] = [p2, u2]), u2 = m0({ islandEndpoint: u2, terminals: [t3, n4] }), p2 = m0({ islandEndpoint: p2, terminals: [t3, n4] });
} else
u2 = { ...a3.pointsToConnect[0], z: go(So(a3.pointsToConnect[0]), e48.layerCount) }, p2 = { ...a3.pointsToConnect[1], z: go(So(a3.pointsToConnect[1]), e48.layerCount) };
const m2 = g0({ connectionName: s3[0].connectionName, hdRoutes: s3, start: u2, end: p2, endpointIndex: this.endpointIndex, canStitchBetweenTerminals: (e49) => this.canStitchBetweenTerminals(e49) });
this.unsolvedRoutes.push({ connectionName: s3[0].connectionName, hdRoutes: m2, start: u2, end: p2 });
}
const a2 = new Map;
for (const e49 of this.unsolvedRoutes) {
const t3 = a2.get(e49.connectionName);
t3 ? t3.push(e49) : a2.set(e49.connectionName, [e49]);
}
this.unsolvedRoutes = Array.from(a2.entries()).flatMap(([n3, o3]) => {
const i3 = e48.connections.find((e49) => e49.name === n3), r3 = o3.some((e49) => e49.hdRoutes.some((e50) => e50.route.length < 2)), s3 = o3.length > 1 && ((e49) => {
for (let t3 = 0;t3 < e49.length; t3++)
for (let n4 = t3 + 1;n4 < e49.length; n4++) {
const o4 = [e49[t3].start, e49[t3].end], i4 = [e49[n4].start, e49[n4].end];
for (const e50 of o4)
for (const t4 of i4)
if (e50.z === t4.z && vt(e50, t4) <= 1)
return true;
}
return false;
})(o3);
if (!i3)
return o3;
const a3 = { ...i3.pointsToConnect[0], z: go(So(i3.pointsToConnect[0]), e48.layerCount) }, c2 = { ...i3.pointsToConnect[1], z: go(So(i3.pointsToConnect[1]), e48.layerCount) }, l2 = o3.flatMap((e49) => e49.hdRoutes), h2 = o3.length > 1 ? this.getSharedRootPathRoutes({ connectionName: n3, rootConnectionName: i3.__rootConnectionNames?.[0] ?? l2[0]?.rootConnectionName, hdRoutes: l2, allHdRoutes: t2, start: a3, end: c2 }) : null;
return r3 || s3 || h2 ? [{ connectionName: n3, hdRoutes: h2 ?? g0({ connectionName: n3, hdRoutes: l2, start: a3, end: c2, endpointIndex: this.endpointIndex, canStitchBetweenTerminals: (e49) => this.canStitchBetweenTerminals(e49) }), start: a3, end: c2 }] : o3;
}), this.MAX_ITERATIONS = 1e5;
}
_step() {
if (this.activeSolver)
return this.activeSolver.step(), void (this.activeSolver.solved ? (this.activeSolver instanceof h0 && (this.clearanceValidator.addRoute(this.activeSolver.mergedHdRoute), this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute)), this.activeSolver = null) : this.activeSolver.failed && (this.failed = true, this.error = this.activeSolver.error));
const e48 = this.unsolvedRoutes.pop();
e48 ? this.activeSolver = new h0({ connectionName: e48.connectionName, hdRoutes: e48.hdRoutes, start: e48.start, end: e48.end, colorMap: this.colorMap, defaultTraceThickness: this.defaultTraceThickness, defaultViaDiameter: this.defaultViaDiameter, allowedLayerTransitionPointKeys: this.allowedLayerTransitionPointKeys, preserveTerminalPcbPortIds: this.preserveTerminalPcbPortIds, isStitchSegmentClear: (e49) => this.clearanceValidator.isSegmentClear(e49), stitchClearanceMode: "prefer_clear" }) : this.solved = true;
}
visualize() {
const e48 = { points: [], lines: [], circles: [], rects: [], title: "Multiple High Density Route Stitch Solver 3" };
if (this.activeSolver) {
const t2 = this.activeSolver.visualize();
t2.points?.length && e48.points?.push(...t2.points), t2.lines?.length && e48.lines?.push(...t2.lines), t2.circles?.length && e48.circles?.push(...t2.circles), t2.rects?.length && (e48.rects || (e48.rects = []), e48.rects.push(...t2.rects));
}
for (const [t2, n2] of this.mergedHdRoutes.entries()) {
const o2 = this.colorMap[n2.connectionName] ?? `hsl(120, 100%, ${40 + 10 * t2 % 40}%)`;
for (let t3 = 0;t3 < n2.route.length - 1; t3++) {
const i2 = n2.route[t3], r2 = n2.route[t3 + 1], s2 = i2.z !== 0 ? Oo(o2, 0.5) : o2;
e48.lines?.push({ points: [{ x: i2.x, y: i2.y }, { x: r2.x, y: r2.y }], strokeColor: s2, strokeWidth: n2.traceThickness });
}
for (const t3 of n2.route) {
const n3 = t3.z !== 0 ? Oo(o2, 0.5) : o2;
e48.points?.push({ x: t3.x, y: t3.y, color: n3 });
}
for (const t3 of n2.vias)
e48.circles?.push({ center: { x: t3.x, y: t3.y }, radius: n2.viaDiameter / 2, fill: o2 });
if (n2.jumpers && n2.jumpers.length > 0) {
const t3 = Az(n2.jumpers, { color: o2, label: n2.connectionName });
e48.rects.push(...t3.rects ?? []), e48.lines.push(...t3.lines ?? []);
}
}
return e48;
}
};
var _0 = (e48) => (e48 % 360 + 360) % 360;
var y0 = (e48, t2) => {
const { ccwRotationDegrees: n2, ...o2 } = e48, i2 = ((e49) => {
const t3 = _0(e49), n3 = [0, 90, 180, 270];
for (const e50 of n3)
if (Math.min(Math.abs(t3 - e50), 360 - Math.abs(t3 - e50)) <= 0.01)
return e50;
return null;
})(t2);
return i2 === 90 || i2 === 270 ? { ...o2, width: e48.height, height: e48.width } : o2;
};
var b0 = (e48, t2) => !(Co(e48).length > 0 && !Co(e48).some((e49) => t2.layers.includes(e49))) && wt(e48, Vt(t2));
var x0 = (e48, t2) => {
const { minX: n2, maxX: o2, minY: i2, maxY: r2 } = Vt(t2);
return { x: Math.max(n2, Math.min(o2, e48.x)), y: Math.max(i2, Math.min(r2, e48.y)) };
};
var v0 = (e48, t2) => e48.obstacleId ?? `${e48.componentId ?? "obstacle"}_${t2}`;
function I0(e48, t2 = 2) {
const { center: n2, width: o2, height: i2, rotation: r2 } = e48, s2 = [], a2 = Math.max(1, Math.ceil(t2)), c2 = r2 * Math.PI / 180, l2 = Math.cos(c2), h2 = Math.sin(c2);
if (o2 >= i2) {
const e49 = o2 / a2;
for (let t3 = 0;t3 < a2; t3++) {
const o3 = (t3 - a2 / 2 + 0.5) * e49, r3 = o3 * l2, c3 = o3 * h2, d2 = Math.abs(e49 * l2) + Math.abs(i2 * h2), u2 = Math.abs(e49 * h2) + Math.abs(i2 * l2);
s2.push({ center: { x: n2.x + r3, y: n2.y + c3 }, width: d2, height: u2 });
}
} else {
const e49 = i2 / a2;
for (let t3 = 0;t3 < a2; t3++) {
const i3 = (t3 - a2 / 2 + 0.5) * e49, r3 = -i3 * h2, c3 = i3 * l2, d2 = Math.abs(o2 * l2) + Math.abs(e49 * h2), u2 = Math.abs(o2 * h2) + Math.abs(e49 * l2);
s2.push({ center: { x: n2.x + r3, y: n2.y + c3 }, width: d2, height: u2 });
}
}
return s2;
}
var S0 = (e48) => {
if (e48.type === "oval")
return S0({ ...e48, type: "rect" });
const t2 = e48.ccwRotationDegrees;
if (typeof t2 != "number" || !Number.isFinite(t2))
return [e48];
if (((e49) => {
const t3 = _0(e49);
return [0, 90, 180, 270].some((e50) => Math.min(Math.abs(t3 - e50), 360 - Math.abs(t3 - e50)) <= 0.01);
})(t2))
return [y0(e48, t2)];
const { ccwRotationDegrees: n2, ...o2 } = e48, i2 = { center: e48.center, width: e48.width, height: e48.height, rotation: t2 }, r2 = ((e49) => {
const t3 = Math.max(e49.width, e49.height), n3 = Math.min(e49.width, e49.height);
return e49.obstacleId?.startsWith("trace_obstacle_") ? Math.max(2, Math.ceil(t3 / 0.75)) : n3 <= 0 ? 2 : t3 / n3 < 2 || n3 >= 0.9 ? null : Math.max(2, Math.ceil(t3 / 0.75));
})(e48), s2 = e48.connectedTo.length > 0 && !e48.obstacleId?.startsWith("trace_obstacle_"), a2 = e48.isNonPlatedHole || s2 ? ((e49) => {
const t3 = e49.rotation * Math.PI / 180, n3 = Math.cos(t3), o3 = Math.sin(t3), i3 = [-1, 1].flatMap((t4) => [-1, 1].map((i4) => {
const r4 = t4 * (e49.width / 2), s4 = i4 * (e49.height / 2);
return { x: e49.center.x + r4 * n3 - s4 * o3, y: e49.center.y + r4 * o3 + s4 * n3 };
})), r3 = [i3[0], i3[2], i3[3], i3[1]], s3 = Math.min(...r3.map((e50) => e50.x)), a3 = Math.max(...r3.map((e50) => e50.x)), c3 = Math.min(...r3.map((e50) => e50.y)), l2 = Math.max(...r3.map((e50) => e50.y)), h2 = a3 - s3 <= l2 - c3 ? "x" : "y", d2 = h2 === "x" ? s3 : c3, u2 = h2 === "x" ? a3 : l2, p2 = Math.max(1, Math.ceil((u2 - d2) / 0.4)), m2 = (u2 - d2) / p2, g2 = (e50, t4, n4) => {
const o4 = [], i4 = (e51) => e51[h2];
for (let r4 = 0;r4 < e50.length; r4++) {
const s4 = e50[r4], a4 = e50[(r4 + 1) % e50.length], c4 = i4(s4), l3 = i4(a4), h3 = n4 ? c4 >= t4 : c4 <= t4, d3 = n4 ? l3 >= t4 : l3 <= t4;
if (h3 && o4.push(s4), h3 === d3)
continue;
const u3 = (t4 - c4) / (l3 - c4);
o4.push({ x: s4.x + (a4.x - s4.x) * u3, y: s4.y + (a4.y - s4.y) * u3 });
}
return o4;
}, f2 = [];
for (let e50 = 0;e50 < p2; e50++) {
const t4 = d2 + e50 * m2, n4 = e50 === p2 - 1 ? u2 : t4 + m2, o4 = g2(g2(r3, t4, true), n4, false);
if (o4.length === 0)
continue;
const i4 = Math.min(...o4.map((e51) => e51.x)), s4 = Math.max(...o4.map((e51) => e51.x)), a4 = Math.min(...o4.map((e51) => e51.y)), c4 = Math.max(...o4.map((e51) => e51.y));
f2.push({ center: { x: (i4 + s4) / 2, y: (a4 + c4) / 2 }, width: s4 - i4, height: c4 - a4 });
}
return f2;
})(i2) : r2 === null ? ((e49, t3) => {
const { center: n3, width: o3, height: i3, rotation: r3 } = e49, s3 = Math.max(1, Math.ceil(o3 / t3)), a3 = Math.max(1, Math.ceil(i3 / t3)), c3 = o3 / s3, l2 = i3 / a3, h2 = r3 * Math.PI / 180, d2 = Math.cos(h2), u2 = Math.sin(h2), p2 = [];
for (let e50 = 0;e50 < s3; e50++) {
const t4 = (e50 - s3 / 2 + 0.5) * c3;
for (let e51 = 0;e51 < a3; e51++) {
const o4 = (e51 - a3 / 2 + 0.5) * l2;
p2.push({ center: { x: n3.x + t4 * d2 - o4 * u2, y: n3.y + t4 * u2 + o4 * d2 }, width: Math.abs(c3 * d2) + Math.abs(l2 * u2), height: Math.abs(c3 * u2) + Math.abs(l2 * d2) });
}
}
return p2;
})(i2, ((e49) => e49.obstacleId?.startsWith("trace_obstacle_") ? 0.75 : 0.4)(e48)) : e48.obstacleId?.startsWith("trace_obstacle_") ? I0(i2, r2) : ((e49, t3) => {
const { center: n3, width: o3, height: i3, rotation: r3 } = e49, s3 = Math.max(o3, i3), a3 = Math.min(o3, i3), c3 = Math.max(1, Math.ceil(t3)), l2 = s3 / c3, h2 = r3 * Math.PI / 180, d2 = Math.cos(h2), u2 = Math.sin(h2), p2 = Math.max(l2, 0.75 * a3), m2 = [];
for (let e50 = 0;e50 < c3; e50++) {
const t4 = (e50 - c3 / 2 + 0.5) * l2, r4 = o3 >= i3 ? t4 * d2 : -t4 * u2, s4 = o3 >= i3 ? t4 * u2 : t4 * d2;
m2.push({ center: { x: n3.x + r4, y: n3.y + s4 }, width: p2, height: p2 });
}
return m2;
})(i2, r2), c2 = e48.connectedTo.length > 0 ? a2.reduce((t3, n3, o3) => {
const i3 = a2[t3], r3 = (i3.center.x - e48.center.x) ** 2 + (i3.center.y - e48.center.y) ** 2;
return (n3.center.x - e48.center.x) ** 2 + (n3.center.y - e48.center.y) ** 2 < r3 ? o3 : t3;
}, 0) : -1;
return a2.map((e49, t3) => ({ ...o2, obstacleId: t3 === c2 ? o2.obstacleId : o2.obstacleId ? `${o2.obstacleId}_approx_${t3}` : undefined, connectedTo: o2.connectedTo, center: e49.center, width: e49.width, height: e49.height }));
};
var C0 = (e48) => {
const t2 = new Map, n2 = new Map, o2 = new Map;
for (const [i3, r2] of e48.obstacles.entries()) {
const e49 = S0(r2), s2 = v0(r2, i3);
n2.set(s2, e49), o2.set(s2, r2);
for (const n3 of e49) {
const e50 = [n3.center.x.toFixed(6), n3.center.y.toFixed(6), n3.width.toFixed(6), n3.height.toFixed(6), n3.layers.join(","), n3.isNonPlatedHole ? "hole" : ""].join(":"), o3 = t2.get(e50);
o3 ? o3.connectedTo = [...new Set([...o3.connectedTo, ...n3.connectedTo])] : t2.set(e50, n3);
}
}
const i2 = e48.connections.map((e49) => ({ ...e49, pointsToConnect: e49.pointsToConnect.map((e50) => {
const t3 = ((e51) => [e51.pointId, e51.pcb_port_id].filter((e52) => Boolean(e52)))(e50);
if (t3.length === 0)
return e50;
for (const [i3, r2] of o2) {
if (!t3.some((e51) => r2.connectedTo.includes(e51)))
continue;
if (!b0(e50, r2))
continue;
const o3 = n2.get(i3) ?? [];
if (o3.length === 0)
continue;
if (o3.some((t4) => b0(e50, t4)))
return e50;
let s2 = o3[0], a2 = Number.POSITIVE_INFINITY;
for (const t4 of o3) {
const n3 = vt(x0(e50, t4), e50);
n3 < a2 && (a2 = n3, s2 = t4);
}
return { ...e50, ...x0(e50, s2) };
}
return e50;
}) }));
return { ...e48, connections: i2, obstacles: [...t2.values()] };
};
var P0 = 0.001;
var M0 = (e48) => e48.route_type === "wire";
var w0 = (e48) => e48.route_type === "via";
var N0 = (e48) => e48.route_type === "through_obstacle";
var T0 = (e48, t2, n2) => {
const o2 = go(e48, n2), i2 = go(t2, n2), r2 = Math.min(o2, i2), s2 = Math.max(o2, i2);
return Array.from({ length: s2 - r2 + 1 }, (e49, t3) => Po(r2 + t3, n2));
};
var R0 = ({ obstacleId: e48, start: t2, end: n2, width: o2, layer: i2, connectedTo: r2 }) => {
const s2 = n2.x - t2.x, a2 = n2.y - t2.y, c2 = Math.hypot(s2, a2);
return c2 <= P0 ? null : { obstacleId: e48, type: "rect", layers: [i2], center: { x: (t2.x + n2.x) / 2, y: (t2.y + n2.y) / 2 }, width: c2, height: Math.max(o2, P0), ccwRotationDegrees: 180 * Math.atan2(a2, s2) / Math.PI, connectedTo: r2 };
};
function E0(e48) {
if (!e48)
return e48;
const t2 = ((e49) => {
if (!e49)
return [];
const t3 = [], n2 = Xo(e49);
for (const [o2, i2] of (e49.traces ?? []).entries()) {
const r2 = i2.connectsTo ?? [];
for (let s2 = 0;s2 < i2.route.length; s2++) {
const a2 = i2.route[s2];
if (w0(a2)) {
const c2 = a2.via_diameter ?? n2.padDiameter;
t3.push({ obstacleId: `trace_obstacle_${i2.pcb_trace_id}_${o2}_${s2}_via`, type: "rect", layers: T0(a2.from_layer, a2.to_layer, e49.layerCount), center: { x: a2.x, y: a2.y }, width: Math.max(c2, P0), height: Math.max(c2, P0), connectedTo: r2 });
continue;
}
if (N0(a2)) {
const n3 = R0({ obstacleId: `trace_obstacle_${i2.pcb_trace_id}_${o2}_${s2}_through`, start: a2.start, end: a2.end, width: a2.width, layer: a2.from_layer, connectedTo: r2 });
n3 && (n3.layers = T0(a2.from_layer, a2.to_layer, e49.layerCount), t3.push(n3));
}
}
for (let e50 = 0;e50 < i2.route.length - 1; e50++) {
const n3 = i2.route[e50], s2 = i2.route[e50 + 1];
if (!M0(n3) || !M0(s2) || n3.layer !== s2.layer)
continue;
const a2 = R0({ obstacleId: `trace_obstacle_${i2.pcb_trace_id}_${o2}_${e50}_wire`, start: n3, end: s2, width: n3.width, layer: n3.layer, connectedTo: r2 });
a2 && t3.push(a2);
}
}
return t3;
})(e48);
return t2.length === 0 ? e48 : { ...e48, obstacles: [...e48.obstacles ?? [], ...t2] };
}
function A0(e48, t2) {
const n2 = function(e49, t3) {
const n3 = fo(e49.__zLayers ?? e49.zLayers ?? [], t3);
if (n3.length > 0)
return n3;
const o2 = _o(e49.layers, t3);
if (o2.length > 0)
return o2;
throw new Error(`Obstacle "${e49.obstacleId ?? "unknown"}" has no layers on this ${t3}-layer board`);
}(e48, t2);
return { ...e48, layers: n2.map((e49) => Po(e49, t2)), zLayers: n2, __zLayers: n2 };
}
function O0(e48) {
return { ...e48, obstacles: e48.obstacles.map((t2) => A0(t2, e48.layerCount)), jumpers: e48.jumpers?.map((t2) => ({ ...t2, pads: t2.pads.map((t3) => A0(t3, e48.layerCount)) })) };
}
var k0 = (e48) => {
const t2 = e48.obstacles.filter((t3) => !((e49, t4) => !((e50) => (e50.connectedTo?.length ?? 0) > 0 || (e50.offBoardConnectsTo?.length ?? 0) > 0 || e50.netIsAssignable === true)(e49) && (t4.outline && t4.outline.length >= 3 ? !Rt(e49, t4.outline) : !Wt({ minX: e49.center.x - e49.width / 2, maxX: e49.center.x + e49.width / 2, minY: e49.center.y - e49.height / 2, maxY: e49.center.y + e49.height / 2 }, t4.bounds)))(t3, e48)), n2 = t2.length !== e48.obstacles.length, o2 = n2 && e48.outline && e48.outline.length >= 3 ? ((e49) => {
if (e49.width && e49.height && e49.center) {
const t4 = e49.width / 2, n4 = e49.height / 2;
return { minX: e49.center.x - t4, minY: e49.center.y - n4, maxX: e49.center.x + t4, maxY: e49.center.y + n4, width: e49.width, height: e49.height, center: { x: e49.center.x, y: e49.center.y } };
}
if (!e49.outline || e49.outline.length === 0)
throw new Error("Unable to compute board bounds. pcb_board must include width/height/center or a non-empty outline.");
let { POSITIVE_INFINITY: t3, POSITIVE_INFINITY: n3, NEGATIVE_INFINITY: o3, NEGATIVE_INFINITY: i2 } = Number;
for (const r3 of e49.outline)
t3 = Math.min(t3, r3.x), n3 = Math.min(n3, r3.y), o3 = Math.max(o3, r3.x), i2 = Math.max(i2, r3.y);
const r2 = o3 - t3, s2 = i2 - n3;
return { minX: t3, minY: n3, maxX: o3, maxY: i2, width: r2, height: s2, center: { x: t3 + r2 / 2, y: n3 + s2 / 2 } };
})({ center: { x: 0, y: 0 }, num_layers: e48.layerCount, outline: e48.outline }) : e48.bounds;
return n2 ? { ...e48, obstacles: t2, bounds: o2 } : e48;
};
function D0(e48) {
const { minX: t2, maxX: n2, minY: o2, maxY: i2 } = e48.bounds;
for (const r2 of e48.connections)
if (!r2.isOffBoard) {
for (const [e49, s2] of r2.pointsToConnect.entries())
if (!(s2.x >= t2 && s2.x <= n2 && s2.y >= o2 && s2.y <= i2))
return `Connection "${r2.name}" point "${s2.pointId ?? e49}" at (${s2.x}, ${s2.y}) is outside routing bounds: x [${t2}, ${n2}], y [${o2}, ${i2}]`;
}
return null;
}
var L0 = class extends ai {
constructor(e48, t2 = {}) {
super(), this.inputSrj = e48, this.visualizationOptions = t2, this.MAX_ITERATIONS = 1;
}
inputSrj;
visualizationOptions;
outputSrj;
_step() {
if (this.error = D0(this.inputSrj), this.error)
return void (this.failed = true);
const e48 = O0(this.inputSrj), t2 = E0(e48) ?? e48, n2 = C0(k0(t2));
this.outputSrj = O0(n2), this.solved = true;
}
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 ? mi(Go({ ...this.outputSrj, traces: [] }, this.visualizationOptions), zJ({ srj: this.outputSrj, visualizationOptions: this.visualizationOptions })) : { lines: [], points: [], rects: [], circles: [] };
}
};
c(T(), 1);
var C3 = (e48, t4) => {
if (e48 === "top")
return 0;
if (e48 === "bottom")
return t4 - 1;
const n4 = /^inner(\d+)$/.exec(e48);
if (!n4)
return -1;
const o4 = Number(n4[1]);
return o4 > 0 && o4 < t4 - 1 ? o4 : -1;
};
var P3 = (e48, t4) => e48 === 0 ? "top" : e48 === t4 - 1 ? "bottom" : `inner${e48}`;
var M3 = (e48, t4, n4) => {
const o4 = C3(e48, n4), i4 = C3(t4, n4);
if (o4 < 0 || i4 < 0)
return [];
const r4 = Math.min(o4, i4), s4 = Math.max(o4, i4);
return Array.from({ length: s4 - r4 + 1 }, (e49, t6) => P3(r4 + t6, n4));
};
var w3 = (e48, t4) => {
const n4 = [], o4 = [], i4 = e48.route.find((e49) => e49.route_type === "wire"), r4 = i4?.route_type === "wire" ? i4.width : null, s4 = { "0603": 0.95, 1206: 1.8, "1206x4_pair": 1.8 };
let a4 = null;
for (let i6 = 0;i6 < e48.route.length; i6++) {
const c4 = e48.route[i6];
if (c4.route_type === "wire") {
if (!Number.isFinite(c4.x) || !Number.isFinite(c4.y) || !Number.isFinite(c4.width) || c4.width <= 0 || C3(c4.layer, t4) < 0)
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" has an invalid wire`);
if (a4 && a4.layer !== c4.layer)
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" changes layer without a transition`);
a4 && n4.push({ start: a4, end: c4, layer: c4.layer, width: Math.max(a4.width, c4.width), connectionName: e48.connection_name, terminal: null }), a4 = c4;
continue;
}
if (c4.route_type === "via") {
const s6 = M3(c4.from_layer, c4.to_layer, t4), l6 = a4, h6 = c4.via_diameter ?? l6?.width ?? r4;
if (!Number.isFinite(c4.x) || !Number.isFinite(c4.y) || s6.length < 2 || h6 === null || !Number.isFinite(h6) || h6 <= 0 || c4.via_hole_diameter !== undefined && (!Number.isFinite(c4.via_hole_diameter) || c4.via_hole_diameter <= 0 || h6 !== null && c4.via_hole_diameter >= h6))
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" has an invalid via`);
l6 && Math.hypot(l6.x - c4.x, l6.y - c4.y) > 0.00000001 && n4.push({ start: l6, end: c4, layer: l6.layer, width: l6.width, connectionName: e48.connection_name, terminal: null }), o4.push({ x: c4.x, y: c4.y, layers: s6, diameter: h6, connectionName: e48.connection_name, terminal: i6 === 0 ? "start" : i6 === e48.route.length - 1 ? "end" : null });
const d6 = e48.route.slice(i6 + 1).find((e49) => e49.route_type === "wire"), u4 = l6?.layer === c4.from_layer ? c4.to_layer : l6?.layer === c4.to_layer ? c4.from_layer : d6?.route_type !== "wire" || d6.layer !== c4.from_layer && d6.layer !== c4.to_layer ? null : d6.layer;
if (!u4)
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" has a discontinuous via`);
a4 = { x: c4.x, y: c4.y, layer: u4, width: l6?.width ?? r4 ?? h6 };
continue;
}
if (c4.route_type === "jumper") {
const o6 = s4[c4.footprint];
if (!Number.isFinite(c4.start.x) || !Number.isFinite(c4.start.y) || !Number.isFinite(c4.end.x) || !Number.isFinite(c4.end.y) || C3(c4.layer, t4) < 0)
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" has an invalid jumper`);
if (a4 && (a4.layer !== c4.layer || Math.hypot(a4.x - c4.start.x, a4.y - c4.start.y) > 0.00000001))
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" has a discontinuous jumper`);
n4.push({ start: c4.start, end: c4.end, layer: c4.layer, width: o6, connectionName: e48.connection_name, terminal: null }), a4 = { ...c4.end, layer: c4.layer, width: o6 };
continue;
}
const l4 = M3(c4.from_layer, c4.to_layer, t4);
if (!Number.isFinite(c4.start.x) || !Number.isFinite(c4.start.y) || !Number.isFinite(c4.end.x) || !Number.isFinite(c4.end.y) || !Number.isFinite(c4.width) || c4.width <= 0 || l4.length < 2)
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" has invalid through-obstacle copper`);
if (a4 && (a4.layer !== c4.from_layer && a4.layer !== c4.to_layer || Math.hypot(a4.x - c4.start.x, a4.y - c4.start.y) > 0.00000001))
throw new Error(`PostProcessingSolver: immutable trace "${e48.connection_name}" has discontinuous through-obstacle copper`);
for (const t6 of l4)
n4.push({ start: c4.start, end: c4.end, layer: t6, width: c4.width, connectionName: e48.connection_name, terminal: null });
const h4 = a4, d4 = h4?.layer === c4.to_layer ? c4.from_layer : c4.to_layer;
a4 = { ...c4.end, layer: d4, width: c4.width };
}
return { segments: n4, vias: o4 };
};
var N3 = (e48) => e48.rootConnectionName ?? e48.connectionName;
var T3 = (e48, t4) => e48.flatMap((e49, n4) => N3(e49) === t4 ? [n4] : []);
var R3 = (e48, t4, n4, o4) => {
const i4 = (e49, t6, n6) => {
const o6 = n6.x - t6.x, i6 = n6.y - t6.y, r6 = e49.x - t6.x, s6 = e49.y - t6.y, a6 = o6 ** 2 + i6 ** 2, c6 = a6 === 0 ? 0 : Math.max(0, Math.min(1, (r6 * o6 + s6 * i6) / a6));
return Math.hypot(e49.x - (t6.x + c6 * o6), e49.y - (t6.y + c6 * i6));
}, r4 = { x: t4.x - e48.x, y: t4.y - e48.y }, s4 = { x: o4.x - n4.x, y: o4.y - n4.y }, a4 = { x: n4.x - e48.x, y: n4.y - e48.y }, c4 = (e49, t6) => e49.x * t6.y - e49.y * t6.x, l4 = c4(r4, s4), h4 = Math.hypot(r4.x, r4.y), d4 = 0.000000000001 * (h4 * Math.hypot(s4.x, s4.y) + 1);
if (Math.abs(l4) > d4) {
const e49 = c4(a4, s4) / l4, t6 = c4(a4, r4) / l4;
if (e49 >= -1e-12 && e49 <= 1 + 0.000000000001 && t6 >= -1e-12 && t6 <= 1 + 0.000000000001)
return 0;
} else if (h4 > 0.000000000001 && Math.abs(c4(a4, r4)) <= d4) {
const i6 = Math.abs(r4.x) >= Math.abs(r4.y), s6 = Math.min(i6 ? e48.x : e48.y, i6 ? t4.x : t4.y), a6 = Math.max(i6 ? e48.x : e48.y, i6 ? t4.x : t4.y), c6 = Math.min(i6 ? n4.x : n4.y, i6 ? o4.x : o4.y), l6 = Math.max(i6 ? n4.x : n4.y, i6 ? o4.x : o4.y);
if (Math.max(s6, c6) <= Math.min(a6, l6) + 0.000000000001)
return 0;
}
return Math.min(i4(e48, n4, o4), i4(t4, n4, o4), i4(n4, e48, t4), i4(o4, e48, t4));
};
var E3 = (e48, t4) => Math.hypot(t4.x - e48.x, t4.y - e48.y);
var A3 = (e48) => {
let t4 = 0;
for (let n4 = 0;n4 < e48.route.length - 1; n4++)
t4 += E3(e48.route[n4], e48.route[n4 + 1]);
return t4;
};
var O3 = (e48, t4) => t4.reduce((t6, n4) => t6 + A3(e48[n4]), 0);
var k3 = (e48, t4) => {
const { __zLayers: n4, zLayers: o4 } = e48, i4 = n4 !== undefined ? n4 : o4;
if (i4 !== undefined) {
if (!Array.isArray(i4) || i4.length === 0 || i4.some((e49) => !Number.isInteger(e49) || e49 < 0 || e49 >= t4))
throw new Error("Obstacle has invalid z-layer indexes");
return i4;
}
if (e48.layers.length === 0)
throw new Error("Obstacle has no declared layers");
return e48.layers.map((e49) => {
if (e49 === "top")
return 0;
if (e49 === "bottom")
return t4 - 1;
const n6 = /^inner(\d+)$/.exec(e49), o6 = n6 ? Number(n6[1]) : -1;
if (o6 <= 0 || o6 >= t4 - 1)
throw new Error(`Obstacle has invalid layer name "${e49}"`);
return o6;
});
};
var D3 = (e48) => {
const t4 = (e49, t6, n6, o6) => {
const i6 = n6.center.x - n6.width / 2 - o6, r6 = n6.center.x + n6.width / 2 + o6, s6 = n6.center.y - n6.height / 2 - o6, a4 = n6.center.y + n6.height / 2 + o6;
if (e49.x >= i6 && e49.x <= r6 && e49.y >= s6 && e49.y <= a4 || t6.x >= i6 && t6.x <= r6 && t6.y >= s6 && t6.y <= a4)
return true;
const c4 = [{ x: i6, y: s6 }, { x: r6, y: s6 }, { x: r6, y: a4 }, { x: i6, y: a4 }];
return c4.some((n7, o7) => R3(e49, t6, n7, c4[(o7 + 1) % c4.length]) === 0);
};
if (e48.bounds && e48.meanderPoints.some((t6) => t6.x < e48.bounds.minX || t6.x > e48.bounds.maxX || t6.y < e48.bounds.minY || t6.y > e48.bounds.maxY))
return false;
const n4 = (e49, t6, n6) => {
const o6 = n6.x - t6.x, i6 = n6.y - t6.y, r6 = o6 * o6 + i6 * i6, s6 = r6 === 0 ? 0 : Math.max(0, Math.min(1, ((e49.x - t6.x) * o6 + (e49.y - t6.y) * i6) / r6));
return Math.hypot(e49.x - (t6.x + s6 * o6), e49.y - (t6.y + s6 * i6));
}, o4 = e48.meanderPoints.some((t6) => !e48.route.route.slice(1).some((o6, i6) => {
const r6 = e48.route.route[i6];
return r6.z === t6.z && o6.z === t6.z && n4(t6, r6, o6) <= 0.000000001;
})), i4 = (e48.traces ?? []).map((t6) => w3(t6, e48.layerCount)), r4 = N3(e48.route), s4 = e48.route.traceThickness / 2 + e48.obstacleMargin;
for (let a4 = 0;a4 < e48.meanderPoints.length - 1; a4++) {
const c4 = e48.meanderPoints[a4], l4 = e48.meanderPoints[a4 + 1], h4 = e48.route.route.slice(1).some((t6, o6) => {
const i6 = e48.route.route[o6];
return c4.z === l4.z && i6.z === c4.z && t6.z === l4.z && n4(c4, i6, t6) <= 0.000000001 && n4(l4, i6, t6) <= 0.000000001;
});
if (o4 && h4)
continue;
for (const n6 of e48.obstacles) {
if (!k3(n6, e48.layerCount).includes(c4.z))
continue;
const o6 = a4 === 0 || a4 === e48.meanderPoints.length - 2;
if ((!n6.connectedTo.includes(r4) || !o6) && t4(c4, l4, n6, s4))
return false;
}
const d4 = P3(c4.z, e48.layerCount);
for (const { segments: e49, vias: t6 } of i4) {
for (const t7 of e49)
if (t7.layer === d4 && R3(c4, l4, t7.start, t7.end) < s4 + t7.width / 2)
return false;
for (const e50 of t6)
if (e50.layers.includes(d4) && n4(e50, c4, l4) < s4 + e50.diameter / 2)
return false;
}
for (const t6 of e48.routedRoutes) {
const o6 = N3(t6) === r4;
for (const i6 of t6.vias) {
if (i6.zLayers && !i6.zLayers.includes(c4.z))
continue;
const r6 = Math.hypot(i6.x - c4.x, i6.y - c4.y) <= 0.00000001 || Math.hypot(i6.x - l4.x, i6.y - l4.y) <= 0.00000001, s6 = e48.route.traceThickness / 2 + t6.viaDiameter / 2 + e48.obstacleMargin;
if ((!o6 || !r6) && n4(i6, c4, l4) < s6)
return false;
}
if (!o6)
for (let n6 = 0;n6 < t6.route.length - 1; n6++) {
const o7 = t6.route[n6], i6 = t6.route[n6 + 1];
if (c4.z !== o7.z || c4.z !== i6.z)
continue;
const r6 = e48.route.traceThickness / 2 + t6.traceThickness / 2 + e48.obstacleMargin;
if (R3(c4, l4, o7, i6) < r6)
return false;
}
}
}
return true;
};
var L3 = (e48) => {
const t4 = [];
for (const n6 of e48.routeIndexes) {
const o4 = e48.routes[n6], i4 = e48.minMeanderGap ?? Math.max(0.3, 2 * o4.traceThickness), r4 = o4.traceThickness + i4, s4 = Math.max(e48.minimumToothPitch ?? 0, 2 * r4), a4 = e48.minMeanderHeight ?? r4;
for (let i6 = 0;i6 < o4.route.length - 1; i6++) {
const r6 = o4.route[i6], c4 = o4.route[i6 + 1], l4 = E3(r6, c4);
if (l4 <= 0 || r6.z !== c4.z)
continue;
const h4 = Math.min(Math.max(0, Math.floor(l4 / s4) - 1), e48.maxToothCount);
for (let o6 = 1;o6 <= h4; o6++) {
const r7 = l4 / (o6 + 1), c6 = [r7, Math.sqrt(s4 * r7), s4].filter((e49, t6, n7) => n7.findIndex((t7) => Math.abs(t7 - e49) < 0.000000001) === t6), h6 = o6 % 2 == 0 ? ["balanced", "negative", "positive"] : ["negative", "positive"];
for (const r8 of c6)
for (const s6 of h6)
t4.push({ routeIndex: n6, segmentIndex: i6, segmentLength: l4, toothCount: o6, maximumDepth: e48.maximumDepth, minimumHeight: a4, toothPitch: r8, placement: s6, heightProfile: o6 > 1 ? "tapered" : "uniform" });
}
}
}
const n4 = { balanced: 0, negative: 1, positive: 2 };
return t4.sort((e49, t6) => e49.toothCount - t6.toothCount || n4[e49.placement] - n4[t6.placement] || t6.toothPitch - e49.toothPitch || t6.segmentLength - e49.segmentLength);
};
var z3 = (e48) => {
if (e48.centerlineDistanceCost === null)
return 0;
const t4 = e48.predictedToothDepths.flatMap((e49, t6) => e49 > 0 ? [t6] : []);
if (t4.length === 0)
return 0;
const n4 = t4.map((t6) => e48.predictedToothDepths[t6]), o4 = Math.max(...n4), i4 = n4.reduce((e49, t6) => e49 + t6, 0) / n4.length, r4 = Math.sqrt(n4.reduce((e49, t6) => e49 + (t6 - i4) ** 2, 0) / n4.length), s4 = t4[0], a4 = (t4.at(-1) - s4 + 1) * e48.toothPitch, c4 = o4 / (e48.toothPitch / 2), l4 = e48.addedLength / a4, h4 = c4 / (1 + c4) * 40, d4 = l4 / (1 + l4) * 30, u4 = e48.predictedToothDepths.map((t6, n6) => Math.sin(Math.PI * (n6 + 1) / (e48.predictedToothDepths.length + 1))), p4 = Math.max(...u4), m4 = Math.sqrt(e48.predictedToothDepths.reduce((e49, t6, n6) => e49 + (t6 - o4 * u4[n6] / p4) ** 2, 0) / e48.predictedToothDepths.length), g4 = 100 - h4 - d4 - Math.min(10, (e48.heightProfile === "tapered" ? m4 : r4) / i4 * 10) - 2 * (n4.length - 1) - 7 * Math.min(1, e48.addedLength / e48.segmentLength) - 100 * e48.centerlineDistanceCost, f4 = e48.centerlineDistanceCost > 0 ? g4 : Math.max(0, g4);
return Math.round(1e6 * f4) / 1e6;
};
var B3 = (e48) => {
if (e48.toothDepths.length !== e48.toothCount)
throw new Error(`LengthMatchingSolver: expected ${e48.toothCount} tooth depths, received ${e48.toothDepths.length}`);
if (e48.toothDepths.some((e49) => !Number.isFinite(e49) || e49 < 0))
throw new Error("LengthMatchingSolver: every meander tooth depth must be a non-negative finite number");
const t4 = e48.route.route[e48.segmentIndex], n4 = e48.route.route[e48.segmentIndex + 1], o4 = E3(t4, n4), i4 = (n4.x - t4.x) / o4, r4 = (n4.y - t4.y) / o4, s4 = (o4 - (e48.toothCount - 0.5) * e48.toothPitch) / 2, a4 = [{ ...t4 }];
for (let n6 = 0;n6 < e48.toothCount; n6++) {
const o6 = e48.toothDepths[n6];
if (o6 === 0)
continue;
const c4 = e48.placement === "balanced" ? n6 % 2 == 0 ? -1 : 1 : e48.placement === "negative" ? -1 : 1, l4 = { x: -r4 * c4, y: i4 * c4 }, h4 = s4 + n6 * e48.toothPitch, d4 = h4 + e48.toothPitch / 2, u4 = { ...t4, x: t4.x + i4 * h4, y: t4.y + r4 * h4 };
a4.push(u4, { ...u4, x: u4.x + l4.x * o6, y: u4.y + l4.y * o6 }, { ...t4, x: t4.x + i4 * d4 + l4.x * o6, y: t4.y + r4 * d4 + l4.y * o6 }, { ...t4, x: t4.x + i4 * d4, y: t4.y + r4 * d4 });
}
return a4.push({ ...n4 }), ((e49) => {
if (e49.length < 3)
return e49;
const t6 = [{ ...e49[0] }];
for (let n6 = 1;n6 < e49.length - 1; n6++) {
const o6 = e49[n6 - 1], i6 = e49[n6], r6 = e49[n6 + 1], s6 = Math.hypot(i6.x - o6.x, i6.y - o6.y), a6 = Math.hypot(r6.x - i6.x, r6.y - i6.y);
if (s6 === 0 || a6 === 0)
throw new Error("LengthMatchingSolver: meander contains a zero-length segment");
const c4 = { x: (i6.x - o6.x) / s6, y: (i6.y - o6.y) / s6 }, l4 = { x: (r6.x - i6.x) / a6, y: (r6.y - i6.y) / a6 };
if (Math.abs(c4.x * l4.y - c4.y * l4.x) < 0.000000001) {
t6.push({ ...i6 });
continue;
}
const h4 = Math.min(s6, a6) / 2, d4 = { ...i6, x: i6.x - c4.x * h4, y: i6.y - c4.y * h4 }, u4 = { ...i6, x: i6.x + l4.x * h4, y: i6.y + l4.y * h4 }, p4 = t6.at(-1);
d4.x === p4.x && d4.y === p4.y || t6.push(d4);
for (let e50 = 1;e50 < 6; e50++) {
const n7 = e50 / 6, o7 = 1 - n7;
t6.push({ ...i6, x: o7 ** 2 * d4.x + 2 * o7 * n7 * i6.x + n7 ** 2 * u4.x, y: o7 ** 2 * d4.y + 2 * o7 * n7 * i6.y + n7 ** 2 * u4.y });
}
t6.push(u4);
}
return t6.push({ ...e49[e49.length - 1] }), t6;
})(a4);
};
var F3 = (e48) => [...e48.route.route.slice(0, e48.segmentIndex), ...B3(e48), ...e48.route.route.slice(e48.segmentIndex + 2)];
var j3 = (e48) => {
const t4 = A3(e48.route), n4 = (() => {
const t6 = [];
for (let n6 = 0;n6 < e48.candidate.toothCount; n6++) {
const o6 = Array(e48.candidate.toothCount).fill(0);
o6[n6] = e48.candidate.maximumDepth;
const i6 = B3({ ...e48.candidate, route: e48.route, toothDepths: o6 });
if (e48.isGeometryValid(i6)) {
t6.push(e48.candidate.maximumDepth);
continue;
}
let r6 = 0, s6 = e48.candidate.maximumDepth;
for (let t7 = 0;t7 < 32; t7++) {
const t8 = (r6 + s6) / 2, o7 = Array(e48.candidate.toothCount).fill(0);
o7[n6] = t8;
const i7 = B3({ ...e48.candidate, route: e48.route, toothDepths: o7 });
e48.isGeometryValid(i7) ? r6 = t8 : s6 = t8;
}
t6.push(r6);
}
return t6;
})(), o4 = ((e49) => {
if (e49.heightProfile !== "tapered")
return Array(e49.toothCount).fill(1);
const t6 = Array.from({ length: e49.toothCount }, (t7, n7) => Math.sin(Math.PI * (n7 + 1) / (e49.toothCount + 1))), n6 = Math.max(...t6);
return t6.map((e50) => e50 / n6);
})(e48.candidate), i4 = e48.candidate.maximumDepth, r4 = n4.map((e49, t6) => Math.min(e49, i4 * o4[t6])), s4 = [0.25, 0.75], a4 = r4.map((e49) => e49 * s4[0]), c4 = r4.map((e49) => e49 * s4[1]), l4 = F3({ ...e48.candidate, route: e48.route, toothDepths: a4 }), h4 = F3({ ...e48.candidate, route: e48.route, toothDepths: c4 }), d4 = [A3({ ...e48.route, route: l4 }) - t4, A3({ ...e48.route, route: h4 }) - t4], u4 = F3({ ...e48.candidate, route: e48.route, toothDepths: r4 }), p4 = A3({ ...e48.route, route: u4 }) - t4, m4 = (d4[1] - d4[0]) / (s4[1] - s4[0]), g4 = d4[0] - m4 * s4[0], f4 = m4 > 0 && Number.isFinite(m4) ? (e48.targetAddedLength - g4) / m4 : 0, _4 = Math.min(e48.targetAddedLength, p4), y4 = e48.targetAddedLength > 0 && _4 > 0 ? ((t6) => {
let n6 = 0, o6 = e48.candidate.maximumDepth;
for (let i7 = 0;i7 < 32; i7++) {
const i8 = (n6 + o6) / 2, r6 = t6.maximumToothDepths.map((e49, n7) => Math.min(e49, i8 * t6.toothHeightWeights[n7])), s6 = F3({ ...e48.candidate, route: e48.route, toothDepths: r6 }), a6 = A3({ ...e48.route, route: s6 }) - t6.originalLength, c6 = B3({ ...e48.candidate, route: e48.route, toothDepths: r6 });
e48.isGeometryValid(c6) ? a6 < t6.targetAddedLength ? n6 = i8 : o6 = i8 : o6 = i8;
}
const i6 = (n6 + o6) / 2;
return { depthLevel: i6, toothDepths: t6.maximumToothDepths.map((e49, n7) => Math.min(e49, i6 * t6.toothHeightWeights[n7])) };
})({ maximumToothDepths: n4, toothHeightWeights: o4, originalLength: t4, targetAddedLength: _4 }) : { depthLevel: f4 * i4, toothDepths: r4.map((e49) => Math.max(0, e49 * f4)) }, b4 = y4.depthLevel / i4, x4 = y4.toothDepths, v4 = F3({ ...e48.candidate, route: e48.route, toothDepths: x4 }), I4 = A3({ ...e48.route, route: v4 }) - t4, S4 = Math.abs(_4 - I4), C4 = B3({ ...e48.candidate, route: e48.route, toothDepths: x4 });
let P4 = 0;
if (e48.getCenterlineDistanceCost && (P4 = e48.getCenterlineDistanceCost(C4)), P4 !== null && (!Number.isFinite(P4) || P4 < 0))
throw new Error("LengthMatchingSolver: meander centerline distance cost must be a non-negative finite number");
const M4 = Number.isFinite(b4) && b4 > 0 && b4 <= 1, w4 = x4.every((t6) => t6 === 0 || t6 >= e48.candidate.minimumHeight), N4 = e48.isGeometryValid(C4);
let T4, R4 = null;
P4 === null ? R4 = "no-paired-same-layer-geometry" : M4 ? S4 > e48.lengthTolerance ? R4 = "target-error" : N4 ? w4 || (R4 = "below-minimum-height") : R4 = "invalid-geometry" : R4 = "invalid-scale", T4 = R4 ? { valid: false, invalidReason: R4 } : { valid: true, invalidReason: null };
const E4 = { ...e48.candidate, connectionName: e48.connectionName, maximumToothDepths: n4, sampleScaleFactors: s4, sampleAddedLengths: d4, slope: m4, intercept: g4, predictedScaleFactor: b4, predictedToothDepths: x4, predictedRoute: v4, addedLength: I4, maximumAddedLength: p4, resultingError: S4, testedSegment: [{ ...e48.route.route[e48.candidate.segmentIndex] }, { ...e48.route.route[e48.candidate.segmentIndex + 1] }], meanderPoints: C4, centerlineDistanceCost: P4, qualityScore: 0, ...T4 };
return { ...E4, qualityScore: z3(E4) };
};
var $3 = (e48) => {
const t4 = ((e49) => {
if (e49.heightProfile !== "tapered")
return Array(e49.toothCount).fill(1);
const t6 = Array.from({ length: e49.toothCount }, (t7, n7) => Math.sin(Math.PI * (n7 + 1) / (e49.toothCount + 1))), n6 = Math.max(...t6);
return t6.map((e50) => e50 / n6);
})(e48.candidate), n4 = Math.max(...t4.map((t6) => e48.candidate.minimumHeight / t6)), o4 = e48.candidate.maximumDepth / 2 ** 30, i4 = t4.map((e49) => e49 * (n4 + o4));
if (i4.some((t6) => t6 > e48.candidate.maximumDepth))
return null;
const r4 = B3({ ...e48.candidate, route: e48.route, toothDepths: i4 });
if (!e48.isGeometryValid(r4))
return null;
const s4 = F3({ ...e48.candidate, route: e48.route, toothDepths: i4 }), a4 = A3({ ...e48.route, route: s4 }) - A3(e48.route), c4 = j3({ ...e48, targetAddedLength: a4 });
return c4.valid ? c4 : null;
};
var Y3 = (e48) => {
const t4 = (e49, t6) => {
const n6 = e49[t6.routeIndex];
if (!n6)
throw new Error(`LengthMatchingSolver: dual meander references missing route ${t6.routeIndex}`);
const o6 = [...e49];
return o6[t6.routeIndex] = { ...n6, route: t6.predictedRoute }, o6;
}, n4 = (() => {
if (e48.targetAddedLength + e48.config.lengthTolerance < e48.plan.minimumAddedLength || e48.targetAddedLength - e48.config.lengthTolerance > e48.plan.maximumAddedLength)
return null;
const t6 = e48.plan.attemptOptions.map((e49) => Math.min(...e49.map((e50) => e50.attempt.addedLength)));
let n6 = Math.max(0, e48.targetAddedLength - e48.plan.minimumAddedLength), o6 = t6.map((e49, t7) => t7);
for (;n6 > 0.000000001 && o6.length > 0; ) {
const i6 = n6 / o6.length;
let r6 = 0;
const s6 = [];
for (const n7 of o6) {
const o7 = Math.max(...e48.plan.attemptOptions[n7].map((e49) => e49.attempt.maximumAddedLength)) - t6[n7], a6 = Math.min(o7, i6);
t6[n7] += a6, r6 += a6, o7 - a6 > 0.000000001 && s6.push(n7);
}
if (r6 <= 0.000000001)
break;
n6 -= r6, o6 = s6;
}
return n6 <= e48.config.lengthTolerance ? t6 : null;
})();
if (!n4)
return null;
const o4 = e48.plan.attemptOptions.map((e49, t6) => ({ attemptOptions: e49, targetAddedLength: n4[t6] })).sort((e49, t6) => t6.attemptOptions[0].candidate.routeIndex - e49.attemptOptions[0].candidate.routeIndex || t6.attemptOptions[0].candidate.segmentIndex - e49.attemptOptions[0].candidate.segmentIndex);
let i4 = [...e48.routes];
const r4 = [];
for (const n6 of o4) {
const o6 = n6.attemptOptions[0]?.candidate;
if (!o6)
throw new Error("LengthMatchingSolver: empty dual-meander segment options");
const s6 = i4[o6.routeIndex];
if (!s6)
throw new Error(`LengthMatchingSolver: missing planned dual-meander route ${o6.routeIndex}`);
let a6 = null;
for (const t6 of n6.attemptOptions) {
if (t6.attempt.addedLength - e48.config.lengthTolerance > n6.targetAddedLength || t6.attempt.maximumAddedLength + e48.config.lengthTolerance < n6.targetAddedLength)
continue;
const o7 = j3({ candidate: t6.candidate, route: s6, connectionName: e48.connectionName, targetAddedLength: n6.targetAddedLength, lengthTolerance: e48.config.lengthTolerance, isGeometryValid: (t7) => D3({ route: s6, meanderPoints: t7, routedRoutes: e48.excludedConnectionName ? i4.filter((t8) => N3(t8) !== e48.excludedConnectionName) : i4, ...e48.config }) });
o7.valid && (!a6 || o7.qualityScore > a6.qualityScore) && (a6 = o7);
}
if (!a6)
return null;
i4 = t4(i4, a6), r4.push(a6);
}
const s4 = r4.reduce((e49, t6) => e49 + t6.addedLength, 0);
if (Math.abs(s4 - e48.targetAddedLength) > e48.config.lengthTolerance)
return null;
const a4 = r4[0];
if (!a4)
throw new Error("LengthMatchingSolver: fitted an empty dual-meander plan");
return { attempts: [a4, ...r4.slice(1)], routes: i4, addedLength: s4 };
};
var X3 = (e48) => {
if (e48.length === 0)
throw new Error("LengthMatchingSolver: cannot score an empty meander plan");
return e48.reduce((e49, t4) => e49 + t4.qualityScore, 0) / e48.length - 3 * (e48.length - 1);
};
var W3 = (e48) => {
const t4 = (e49) => [e49.candidate.toothCount, e49.candidate.placement, e49.candidate.heightProfile].join(":"), n4 = new Map;
for (const o6 of e48) {
const e49 = t4(o6), i4 = `${o6.candidate.routeIndex}:${o6.candidate.segmentIndex}`, r4 = n4.get(e49);
if (!r4) {
n4.set(e49, new Map([[i4, [o6]]]));
continue;
}
const s4 = r4.get(i4);
s4 ? s4.push(o6) : r4.set(i4, [o6]);
}
const o4 = [];
for (const e49 of n4.values()) {
const t6 = [...e49.values()].map((e50) => ({ attempts: e50, maximumAddedLength: Math.max(...e50.map((e51) => e51.attempt.maximumAddedLength)), minimumAddedLength: Math.min(...e50.map((e51) => e51.attempt.addedLength)), rankingAttempt: e50.reduce((e51, t7) => t7.attempt.qualityScore > e51.attempt.qualityScore ? t7 : e51) })).sort((e50, t7) => t7.maximumAddedLength - e50.maximumAddedLength);
for (const e50 of t6)
o4.push({ attempts: [e50.rankingAttempt], attemptOptions: [e50.attempts], minimumAddedLength: e50.minimumAddedLength, maximumAddedLength: e50.maximumAddedLength, rankingQualityScore: e50.rankingAttempt.attempt.qualityScore });
for (let e50 = 2;e50 <= t6.length; e50++) {
const n6 = t6.slice(0, e50), i4 = n6.map((e51) => e51.rankingAttempt);
o4.push({ attempts: i4, attemptOptions: n6.map((e51) => e51.attempts), minimumAddedLength: n6.reduce((e51, t7) => e51 + t7.minimumAddedLength, 0), maximumAddedLength: n6.reduce((e51, t7) => e51 + t7.maximumAddedLength, 0), rankingQualityScore: X3(i4.map((e51) => e51.attempt)) });
}
}
return o4;
};
var V3 = class extends Error {
connectionName;
reason;
constructor(e48) {
super(e48.message), this.name = "LengthMatchingNoSolutionError", this.connectionName = e48.connectionName, this.reason = e48.reason;
}
};
var H3 = (e48) => [e48.routeIndex, e48.segmentIndex, e48.toothCount, e48.placement, e48.toothPitch, e48.heightProfile, e48.maximumDepth, e48.minimumHeight].join(":");
var G3 = (e48) => {
const t4 = new Map, n4 = [...e48.attempts].sort((e49, t6) => e49.addedLength - t6.addedLength);
let o4 = e48.targetAddedLength;
for (let e49 = 0;e49 < n4.length; e49++) {
const i4 = n4[e49], r4 = Math.min(i4.addedLength, o4 / (n4.length - e49));
t4.set(H3(i4), { routeIndex: i4.routeIndex, segmentIndex: i4.segmentIndex, targetAddedLength: r4 }), o4 -= r4;
}
return t4;
};
var U3 = (e48, t4) => `z${k3(e48, t4).join(",")}`;
var Z3 = (e48) => `z${e48}`;
var q3 = (e48) => {
if (!e48.showAttempt)
return;
if (!e48.attempt)
return void ((e49) => {
const t6 = e49.activePair?.candidates[e49.activePair.candidateIndex];
if (!t6)
return;
const n6 = e49.routes[t6.routeIndex];
if (!n6)
return;
const o6 = n6.route[t6.segmentIndex], i6 = n6.route[t6.segmentIndex + 1];
o6 && i6 && e49.graphics.lines.push({ points: [o6, i6], strokeColor: "rgba(234, 179, 8, 0.6)", strokeWidth: 2 * n6.traceThickness, strokeDash: [0.1, 0.1], layer: Z3(o6.z) });
})(e48);
const t4 = e48.routes[e48.attempt.routeIndex], [n4, o4] = e48.attempt.testedSegment, i4 = e48.theme.getConnectionColor(e48.attempt.connectionName);
e48.graphics.lines.push({ points: [n4, o4], strokeColor: e48.theme.getTestedSegmentColor(i4), strokeWidth: t4.traceThickness, strokeDash: [0.15, 0.15], layer: Z3(n4.z) }), e48.attempt.valid ? e48.graphics.lines.push({ points: e48.attempt.meanderPoints.map(({ x: e49, y: t6 }) => ({ x: e49, y: t6 })), strokeColor: "rgba(234, 179, 8, 0.6)", strokeWidth: 2 * t4.traceThickness, strokeDash: [0.1, 0.1], layer: Z3(n4.z) }) : e48.graphics.lines.push({ points: e48.attempt.meanderPoints.map(({ x: e49, y: t6 }) => ({ x: e49, y: t6 })), strokeColor: e48.theme.getRejectedCandidateColor(i4), strokeWidth: t4.traceThickness, strokeDash: [0.1, 0.1], layer: Z3(n4.z) }), e48.graphics.points.push({ x: n4.x, y: n4.y, color: i4, layer: Z3(n4.z) }, { x: o4.x, y: o4.y, color: i4, layer: Z3(o4.z) });
};
var J3 = (e48) => {
const t4 = { lines: [], points: [], rects: [], circles: [] }, n4 = ((e49) => {
for (const t6 of Object.values(e49))
Re(0, t6);
return { getConnectionColor: (t6, n6) => e49[t6] ?? (n6 ? e49[n6] : undefined) ?? ((e50) => e50 ? `hsl(${300 * e50.split("").reduce((e51, t7) => e51 + t7.charCodeAt(0), 0) / e50.length % 360}, 100%, 50%)` : "rgba(0, 0, 0, 0.5)")(t6), getInnerLayerConnectionColor: (e50) => Re(0.5, e50), getTestedSegmentColor: (e50) => Re(0.55, e50), getRejectedCandidateColor: (e50) => Re(0.45, e50), 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" } };
})(e48.colorMap);
return ((e49) => {
for (const t6 of e49.routes) {
const n6 = N3(t6), o4 = e49.theme.getConnectionColor(n6, t6.connectionName);
for (let n7 = 0;n7 < t6.route.length - 1; n7++) {
const i6 = t6.route[n7], r4 = t6.route[n7 + 1];
i6.z === r4.z && e49.graphics.lines.push({ points: [i6, r4], strokeColor: i6.z === 0 ? o4 : e49.theme.getInnerLayerConnectionColor(o4), strokeWidth: t6.traceThickness, ...i6.z === 0 ? {} : { strokeDash: [0.2, 0.2] }, layer: Z3(i6.z) });
}
const i4 = [...new Set(t6.route.map((e50) => e50.z))];
for (const n7 of t6.vias)
e49.graphics.circles.push({ center: n7, radius: t6.viaDiameter / 2, fill: e49.theme.via.fill, stroke: e49.theme.via.stroke, layer: `z${(n7.zLayers ?? i4).join(",")}` });
}
})({ routes: e48.routes, theme: n4, graphics: t4 }), ((e49) => {
if (e49.bounds) {
const { minX: t6, maxX: n6, minY: o4, maxY: i4 } = e49.bounds;
e49.graphics.rects.push({ center: { x: (t6 + n6) / 2, y: (o4 + i4) / 2 }, width: n6 - t6, height: i4 - o4, fill: e49.theme.boardBounds.fill, stroke: e49.theme.boardBounds.stroke, layer: `z${Array.from({ length: e49.layerCount }, (e50, t7) => t7).join(",")}` });
}
for (const t6 of e49.obstacles)
e49.graphics.rects.push({ center: t6.center, width: t6.width, height: t6.height, ccwRotationDegrees: t6.ccwRotationDegrees, fill: e49.theme.obstacle.fill, stroke: e49.theme.obstacle.stroke, layer: U3(t6, e49.layerCount) });
})({ obstacles: e48.obstacles, bounds: e48.bounds, layerCount: e48.layerCount, theme: n4, graphics: t4 }), q3({ routes: e48.routes, attempt: e48.currentAttempt, activePair: e48.activePair, showAttempt: !e48.solved, theme: n4, graphics: t4 }), { ...t4 };
};
var Q3 = class extends De {
constructor(e48) {
super(), this.params = e48, this.MAX_ITERATIONS = 1e5, this.matchedHdRoutes = e48.hdRoutes.map((e49) => ({ ...e49, route: e49.route.map((e50) => ({ ...e50 })) })), this.pairs = e48.differentialPairs ?? [];
}
params;
matchedHdRoutes;
pairs;
nextPairIndex = 0;
activePair = null;
currentAttempt = null;
config = null;
candidatesTried = 0;
getSolverName() {
return "LengthMatchingSolver";
}
startNextPair() {
const e48 = this.pairs[this.nextPairIndex++];
if (!e48)
return void (this.solved = true);
((e49, t6) => {
if (e49.connectionNames[0] === e49.connectionNames[1])
throw new Error("LengthMatchingSolver: a differential pair must reference two distinct connections");
if (!Number.isFinite(e49.lengthTolerance) || e49.lengthTolerance < 0)
throw new Error("LengthMatchingSolver: differential pair lengthTolerance must be a non-negative finite number");
for (const t7 of [e49.minimumCenterlineDistance, e49.maximumCenterlineDistance])
if (t7 !== undefined && (!Number.isFinite(t7) || t7 <= 0))
throw new Error("LengthMatchingSolver: differential pair centerline distances must be positive finite numbers");
if (e49.minimumCenterlineDistance !== undefined && e49.maximumCenterlineDistance !== undefined && e49.minimumCenterlineDistance > e49.maximumCenterlineDistance)
throw new Error("LengthMatchingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance");
const n6 = new Map(t6.map((e50) => [e50.name, e50]));
for (const t7 of e49.connectionNames) {
const e50 = n6.get(t7);
if (!e50)
throw new Error(`LengthMatchingSolver: differential pair references unknown connection "${t7}"`);
if (e50.pointsToConnect.length !== 2)
throw new Error(`LengthMatchingSolver: differential pair connection "${t7}" must have exactly two points before MST splitting`);
}
})(e48, this.params.originalConnections);
const t4 = T3(this.matchedHdRoutes, e48.connectionNames[0]), n4 = T3(this.matchedHdRoutes, e48.connectionNames[1]);
if (t4.length === 0 && n4.length === 0)
return;
if (t4.length === 0 || n4.length === 0)
throw new Error(`LengthMatchingSolver: differential pair ${e48.connectionNames.join("/")} has routed geometry for only one connection`);
const o4 = O3(this.matchedHdRoutes, t4), i4 = O3(this.matchedHdRoutes, n4), r4 = Math.abs(o4 - i4);
if (r4 <= e48.lengthTolerance)
return;
const s4 = o4 < i4, a4 = e48.connectionNames[s4 ? 0 : 1], c4 = e48.connectionNames[s4 ? 1 : 0], l4 = L3({ routes: this.matchedHdRoutes, routeIndexes: s4 ? t4 : n4, maximumDepth: this.getConfig().maximumMeanderDepth, minimumToothPitch: this.getConfig().minimumToothPitch, minMeanderGap: this.getConfig().minMeanderGap, minMeanderHeight: this.getConfig().minMeanderHeight, maxToothCount: this.getConfig().maxToothCount });
if (l4.length === 0)
throw new V3({ message: `LengthMatchingSolver: no same-layer straight segment can tune connection "${a4}"`, connectionName: a4, reason: "no-meander-candidate" });
this.activePair = { pair: e48, longerConnectionName: c4, longerRouteIndexes: s4 ? n4 : t4, shorterConnectionName: a4, targetAddedLength: r4, remainingAddedLength: r4, candidates: l4, candidateIndex: 0, lastMatchedSegmentIndexByRoute: new Map, partialAttempts: [], fullAttempts: [], plannedAttemptTargets: null, hasMinimumHeightBlockedAttempt: false };
}
acceptAttempt(e48, t4) {
const n4 = this.matchedHdRoutes[t4.routeIndex];
this.matchedHdRoutes[t4.routeIndex] = { ...n4, route: t4.predictedRoute }, e48.remainingAddedLength -= t4.addedLength, e48.lastMatchedSegmentIndexByRoute.set(t4.routeIndex, t4.segmentIndex), e48.candidateIndex = 0, e48.partialAttempts = [], e48.fullAttempts = [], e48.plannedAttemptTargets?.delete(H3(t4)), e48.plannedAttemptTargets?.size === 0 && (e48.plannedAttemptTargets = null), e48.remainingAddedLength <= e48.pair.lengthTolerance && (this.activePair = null);
}
tryCandidate(e48) {
let t4;
for (;!t4; ) {
const n6 = e48.candidates[e48.candidateIndex++];
if (!n6)
break;
const o6 = e48.lastMatchedSegmentIndexByRoute.get(n6.routeIndex);
(o6 === undefined || n6.segmentIndex < o6) && (!e48.plannedAttemptTargets || e48.plannedAttemptTargets.has(H3(n6)) && ![...e48.plannedAttemptTargets.values()].some((e49) => e49.routeIndex === n6.routeIndex && e49.segmentIndex > n6.segmentIndex)) && (t4 = n6);
}
if (!t4) {
const t6 = e48.fullAttempts.reduce((e49, t7) => !e49 || t7.qualityScore > e49.qualityScore ? t7 : e49, null), n6 = ((e49) => {
const t7 = (e50) => [e50.toothCount, e50.placement, e50.heightProfile].join(":"), n7 = new Map;
for (const o7 of e49.attempts) {
const e50 = `${o7.routeIndex}:${o7.segmentIndex}`, i6 = t7(o7), r4 = n7.get(i6);
if (!r4) {
n7.set(i6, new Map([[e50, [o7]]]));
continue;
}
const s4 = r4.get(e50);
s4 ? s4.push(o7) : r4.set(e50, [o7]);
}
let o6 = null;
for (const t8 of n7.values()) {
const n8 = [...t8.values()].map((e50) => ({ attempts: e50, maximumCapacityAttempt: e50.reduce((e51, t9) => t9.addedLength > e51.addedLength ? t9 : e51) })).sort((e50, t9) => t9.maximumCapacityAttempt.addedLength - e50.maximumCapacityAttempt.addedLength);
let i6 = 0;
for (let t9 = 0;t9 < n8.length; t9++) {
if (i6 += n8[t9].maximumCapacityAttempt.addedLength, i6 + e49.lengthTolerance < e49.targetAddedLength)
continue;
const r4 = n8.slice(0, t9 + 1), s4 = r4.map((e50) => e50.maximumCapacityAttempt), a4 = G3({ attempts: s4, targetAddedLength: e49.targetAddedLength }), c4 = r4.map((t10) => {
const n9 = a4.get(H3(t10.maximumCapacityAttempt));
if (!n9)
throw new Error(`LengthMatchingSolver: missing capacity target for ${H3(t10.maximumCapacityAttempt)}`);
const o7 = t10.attempts.filter((t11) => t11.addedLength + e49.lengthTolerance >= n9.targetAddedLength);
if (o7.length === 0)
throw new Error(`LengthMatchingSolver: no pitch can supply planned target for route ${t10.maximumCapacityAttempt.routeIndex} segment ${t10.maximumCapacityAttempt.segmentIndex}`);
return o7.reduce((e50, t11) => t11.qualityScore > e50.qualityScore || t11.qualityScore === e50.qualityScore && t11.toothPitch > e50.toothPitch ? t11 : e50);
}), l4 = X3(c4);
if (!o6) {
o6 = { attempts: c4 };
break;
}
const h4 = X3(o6.attempts);
(c4.length < o6.attempts.length || c4.length === o6.attempts.length && l4 > h4) && (o6 = { attempts: c4 });
break;
}
}
return o6;
})({ attempts: e48.partialAttempts, targetAddedLength: e48.remainingAddedLength, lengthTolerance: e48.pair.lengthTolerance });
if (t6 && (!n6 || t6.qualityScore >= X3(n6.attempts)))
return void this.acceptAttempt(e48, t6);
if (!n6) {
if (!(e48.hasMinimumHeightBlockedAttempt && e48.plannedAttemptTargets === null && e48.lastMatchedSegmentIndexByRoute.size === 0))
throw new V3({ message: `LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for "${e48.shorterConnectionName}"; required ${e48.targetAddedLength.toFixed(4)}mm`, connectionName: e48.shorterConnectionName, reason: "meander-search-exhausted" });
return this.tryDualMeanderPlan(e48);
}
return e48.plannedAttemptTargets = G3({ attempts: n6.attempts, targetAddedLength: e48.remainingAddedLength }), e48.candidateIndex = 0, e48.partialAttempts = [], void (e48.fullAttempts = []);
}
const n4 = this.matchedHdRoutes[t4.routeIndex], o4 = this.getConfig(), i4 = e48.plannedAttemptTargets?.get(H3(t4));
if (e48.plannedAttemptTargets !== null && i4 === undefined)
throw new Error(`LengthMatchingSolver: missing planned target for ${H3(t4)}`);
this.currentAttempt = j3({ candidate: t4, route: n4, connectionName: e48.shorterConnectionName, targetAddedLength: i4 === undefined ? e48.remainingAddedLength : i4.targetAddedLength, lengthTolerance: e48.pair.lengthTolerance, isGeometryValid: (e49) => D3({ route: n4, meanderPoints: e49, routedRoutes: this.matchedHdRoutes, traces: o4.traces, obstacles: o4.obstacles, bounds: o4.bounds, layerCount: o4.layerCount, obstacleMargin: o4.obstacleMargin }), getCenterlineDistanceCost: e48.pair.minimumCenterlineDistance === undefined && e48.pair.maximumCenterlineDistance === undefined ? undefined : (t6) => ((e49) => {
let t7 = 0, n6 = 0;
for (let o6 = 0;o6 < e49.meanderPoints.length - 1; o6++) {
const i6 = e49.meanderPoints[o6], r4 = e49.meanderPoints[o6 + 1], s4 = Math.hypot(r4.x - i6.x, r4.y - i6.y);
if (s4 !== 0) {
for (let t8 = 0;t8 < 4; t8++) {
const o7 = (t8 + 0.5) / 4, a4 = { x: i6.x + (r4.x - i6.x) * o7, y: i6.y + (r4.y - i6.y) * o7 }, c4 = [];
for (const t9 of e49.pairedRoutes)
for (let e50 = 0;e50 < t9.route.length - 1; e50++) {
const n7 = t9.route[e50], o8 = t9.route[e50 + 1];
i6.z === n7.z && i6.z === o8.z && c4.push(R3(a4, a4, n7, o8));
}
if (c4.length === 0)
return null;
const l4 = Math.min(...c4);
n6 += s4 * Math.max(0, (e49.minimumCenterlineDistance ?? Number.NEGATIVE_INFINITY) - l4, l4 - (e49.maximumCenterlineDistance ?? Number.POSITIVE_INFINITY)) / 4;
}
t7 += s4;
}
}
if (t7 === 0)
throw new Error("LengthMatchingSolver: cannot measure a zero-length meander centerline");
return n6 / t7;
})({ meanderPoints: t6, pairedRoutes: e48.longerRouteIndexes.map((e49) => this.matchedHdRoutes[e49]), minimumCenterlineDistance: e48.pair.minimumCenterlineDistance, maximumCenterlineDistance: e48.pair.maximumCenterlineDistance }) }), this.candidatesTried++, this.currentAttempt.invalidReason === "below-minimum-height" && (e48.hasMinimumHeightBlockedAttempt = true), this.stats = { pair: `${e48.pair.connectionNames[0]}/${e48.pair.connectionNames[1]}`, candidatesTried: this.candidatesTried, segmentIndex: t4.segmentIndex, toothCount: t4.toothCount, toothPitch: t4.toothPitch, placement: t4.placement, predictedScaleFactor: this.currentAttempt.predictedScaleFactor, predictedToothDepths: this.currentAttempt.predictedToothDepths, resultingError: this.currentAttempt.resultingError, qualityScore: this.currentAttempt.qualityScore, accepted: this.currentAttempt.valid }, this.currentAttempt.valid && (e48.plannedAttemptTargets === null ? e48.remainingAddedLength - this.currentAttempt.addedLength <= e48.pair.lengthTolerance ? e48.fullAttempts.push(this.currentAttempt) : e48.partialAttempts.push(this.currentAttempt) : this.acceptAttempt(e48, this.currentAttempt));
}
tryDualMeanderPlan(e48) {
if (e48.remainingAddedLength !== e48.targetAddedLength)
throw new Error(`LengthMatchingSolver: cannot start a dual-meander plan after partially tuning "${e48.shorterConnectionName}"`);
const t4 = this.getConfig(), n4 = L3({ routes: this.matchedHdRoutes, routeIndexes: e48.longerRouteIndexes, maximumDepth: t4.maximumMeanderDepth, minimumToothPitch: t4.minimumToothPitch, minMeanderGap: t4.minMeanderGap, minMeanderHeight: t4.minMeanderHeight, maxToothCount: t4.maxToothCount }), o4 = ((e49) => {
const t6 = (e50, t7) => e50.rankingQualityScore !== t7.rankingQualityScore ? e50.rankingQualityScore > t7.rankingQualityScore : e50.leftIndex !== t7.leftIndex ? e50.leftIndex < t7.leftIndex : e50.rightIndex < t7.rightIndex, n6 = (e50, n7) => {
e50.push(n7);
let o7 = e50.length - 1;
for (;o7 > 0; ) {
const i7 = Math.floor((o7 - 1) / 2), r7 = e50[i7];
if (t6(r7, n7))
break;
e50[o7] = r7, o7 = i7;
}
e50[o7] = n7;
}, o6 = (e50) => {
const n7 = e50[0], o7 = e50.pop();
if (!n7 || !o7 || e50.length === 0)
return n7;
let i7 = 0;
for (;; ) {
const n8 = 2 * i7 + 1, r7 = n8 + 1;
if (n8 >= e50.length)
break;
const s7 = r7 < e50.length && t6(e50[r7], e50[n8]) ? r7 : n8, a6 = e50[s7];
if (t6(o7, a6))
break;
e50[i7] = a6, i7 = s7;
}
return e50[i7] = o7, n7;
}, i6 = function* (e50) {
const t7 = [...e50.leftOptions].sort((t8, n7) => e50.getLeftQualityScore(n7) - e50.getLeftQualityScore(t8)), i7 = [...e50.rightOptions].sort((t8, n7) => e50.getRightQualityScore(n7) - e50.getRightQualityScore(t8)), r7 = [];
for (let o7 = 0;o7 < t7.length; o7++) {
const s7 = i7[0];
if (!s7)
break;
n6(r7, { leftIndex: o7, rightIndex: 0, rankingQualityScore: (e50.getLeftQualityScore(t7[o7]) + e50.getRightQualityScore(s7)) / 2 });
}
for (;r7.length > 0; ) {
const s7 = o6(r7);
yield [t7[s7.leftIndex], i7[s7.rightIndex]];
const a6 = s7.rightIndex + 1, c6 = i7[a6];
c6 && n6(r7, { leftIndex: s7.leftIndex, rightIndex: a6, rankingQualityScore: (e50.getLeftQualityScore(t7[s7.leftIndex]) + e50.getRightQualityScore(c6)) / 2 });
}
}, r6 = (e50, t7) => {
const n7 = e50[t7.routeIndex];
if (!n7)
throw new Error(`LengthMatchingSolver: dual meander references missing route ${t7.routeIndex}`);
const o7 = [...e50];
return o7[t7.routeIndex] = { ...n7, route: t7.predictedRoute }, o7;
}, s6 = (e50) => {
const t7 = e50.routes[e50.attempt.routeIndex];
if (!t7)
throw new Error(`LengthMatchingSolver: cannot validate missing dual-meander route ${e50.attempt.routeIndex}`);
return D3({ route: t7, meanderPoints: e50.attempt.meanderPoints, routedRoutes: e50.routes, ...e50.config });
}, a4 = (e50) => {
const t7 = e50.routes.filter((t8) => N3(t8) !== e50.counterpartConnectionName), n7 = [];
for (const o7 of e50.candidates) {
const i7 = e50.routes[o7.routeIndex];
if (!i7)
throw new Error(`LengthMatchingSolver: dual-meander candidate references missing route ${o7.routeIndex}`);
const r7 = $3({ candidate: o7, route: i7, connectionName: e50.connectionName, lengthTolerance: e50.config.lengthTolerance, isGeometryValid: (n8) => D3({ route: i7, meanderPoints: n8, routedRoutes: t7, ...e50.config }) });
r7 && n7.push({ candidate: o7, attempt: r7 });
}
return n7;
}, c4 = { traces: e49.traces, obstacles: e49.obstacles, bounds: e49.bounds, layerCount: e49.layerCount, obstacleMargin: e49.obstacleMargin }, l4 = a4({ candidates: e49.shorterCandidates, routes: e49.routes, connectionName: e49.shorterConnectionName, counterpartConnectionName: e49.longerConnectionName, config: { ...c4, lengthTolerance: e49.lengthTolerance } });
if (l4.length === 0)
return null;
const h4 = a4({ candidates: e49.longerCandidates, routes: e49.routes, connectionName: e49.longerConnectionName, counterpartConnectionName: e49.shorterConnectionName, config: { ...c4, lengthTolerance: e49.lengthTolerance } }), d4 = i6({ leftOptions: h4, rightOptions: l4, getLeftQualityScore: (e50) => e50.attempt.qualityScore, getRightQualityScore: (e50) => e50.attempt.qualityScore });
for (const [t7, n7] of d4) {
const o7 = Math.max(t7.attempt.addedLength, n7.attempt.addedLength - e49.originalLengthDifference), i7 = o7 + e49.originalLengthDifference;
if (o7 - e49.lengthTolerance > t7.attempt.maximumAddedLength || i7 - e49.lengthTolerance > n7.attempt.maximumAddedLength)
continue;
const a6 = e49.routes[t7.candidate.routeIndex];
if (!a6)
throw new Error(`LengthMatchingSolver: missing longer route ${t7.candidate.routeIndex}`);
const l6 = e49.routes[n7.candidate.routeIndex];
if (!l6)
throw new Error(`LengthMatchingSolver: missing shorter route ${n7.candidate.routeIndex}`);
const h6 = e49.routes.filter((t8) => N3(t8) !== e49.shorterConnectionName), d6 = j3({ candidate: t7.candidate, route: a6, connectionName: e49.longerConnectionName, targetAddedLength: o7, lengthTolerance: e49.lengthTolerance, isGeometryValid: (e50) => D3({ route: a6, meanderPoints: e50, routedRoutes: h6, ...c4 }) });
if (!d6.valid || Math.abs(d6.addedLength - o7) > e49.lengthTolerance)
continue;
const u6 = r6(e49.routes, d6), p4 = d6.addedLength + e49.originalLengthDifference, m4 = j3({ candidate: n7.candidate, route: l6, connectionName: e49.shorterConnectionName, targetAddedLength: p4, lengthTolerance: e49.lengthTolerance, isGeometryValid: (e50) => D3({ route: l6, meanderPoints: e50, routedRoutes: u6, ...c4 }) });
if (!m4.valid)
continue;
const g4 = r6(u6, m4), f4 = T3(g4, e49.longerConnectionName), _4 = T3(g4, e49.shorterConnectionName);
if (!(Math.abs(O3(g4, _4) - O3(g4, f4)) > e49.lengthTolerance) && s6({ attempt: d6, routes: g4, config: c4 }) && s6({ attempt: m4, routes: g4, config: c4 }))
return { longerAttempts: [d6], shorterAttempts: [m4] };
}
const u4 = i6({ leftOptions: W3(h4), rightOptions: W3(l4), getLeftQualityScore: (e50) => e50.rankingQualityScore, getRightQualityScore: (e50) => e50.rankingQualityScore });
for (const [t7, n7] of u4) {
if (t7.attempts.length === 1 && n7.attempts.length === 1)
continue;
const o7 = Math.max(t7.minimumAddedLength, n7.minimumAddedLength - e49.originalLengthDifference), i7 = o7 + e49.originalLengthDifference;
if (o7 - e49.lengthTolerance > t7.maximumAddedLength || i7 - e49.lengthTolerance > n7.maximumAddedLength)
continue;
const r7 = Y3({ plan: t7, targetAddedLength: o7, routes: e49.routes, connectionName: e49.longerConnectionName, excludedConnectionName: e49.shorterConnectionName, config: { ...c4, lengthTolerance: e49.lengthTolerance } });
if (!r7)
continue;
const a6 = Y3({ plan: n7, targetAddedLength: r7.addedLength + e49.originalLengthDifference, routes: r7.routes, connectionName: e49.shorterConnectionName, config: { ...c4, lengthTolerance: e49.lengthTolerance } });
if (!a6)
continue;
const l6 = T3(a6.routes, e49.longerConnectionName), h6 = T3(a6.routes, e49.shorterConnectionName), d6 = Math.abs(O3(a6.routes, h6) - O3(a6.routes, l6)), u6 = [...r7.attempts, ...a6.attempts];
if (!(d6 > e49.lengthTolerance || u6.some((e50) => !s6({ attempt: e50, routes: a6.routes, config: c4 }))))
return { longerAttempts: r7.attempts, shorterAttempts: a6.attempts };
}
return null;
})({ routes: this.matchedHdRoutes, longerConnectionName: e48.longerConnectionName, shorterConnectionName: e48.shorterConnectionName, originalLengthDifference: e48.targetAddedLength, lengthTolerance: e48.pair.lengthTolerance, longerCandidates: n4, shorterCandidates: e48.candidates, traces: t4.traces, obstacles: t4.obstacles, bounds: t4.bounds, layerCount: t4.layerCount, obstacleMargin: t4.obstacleMargin });
if (!o4)
throw new V3({ message: `LengthMatchingSolver: linear regression exhausted all segment/tooth combinations for "${e48.shorterConnectionName}"; required ${e48.targetAddedLength.toFixed(4)}mm`, connectionName: e48.shorterConnectionName, reason: "meander-search-exhausted" });
const i4 = [...this.matchedHdRoutes];
for (const e49 of [...o4.longerAttempts, ...o4.shorterAttempts]) {
const t6 = this.matchedHdRoutes[e49.routeIndex];
if (!t6)
throw new Error(`LengthMatchingSolver: cannot commit dual meander to missing route ${e49.routeIndex}`);
i4[e49.routeIndex] = { ...t6, route: e49.predictedRoute };
}
this.matchedHdRoutes = i4, this.currentAttempt = o4.shorterAttempts[0];
const r4 = o4.longerAttempts.reduce((e49, t6) => e49 + t6.addedLength, 0), s4 = o4.shorterAttempts.reduce((e49, t6) => e49 + t6.addedLength, 0);
this.stats = { pair: `${e48.pair.connectionNames[0]}/${e48.pair.connectionNames[1]}`, mode: "dual-meander", longerAddedLength: r4, shorterAddedLength: s4, resultingError: Math.abs(s4 - r4 - e48.targetAddedLength) }, this.activePair = null;
}
getConfig() {
return this.config || (this.config = ((e48) => {
const t4 = e48.maximumMeanderDepth ?? 5, n4 = e48.maxToothCount ?? 12;
if (!Number.isFinite(t4) || t4 <= 0)
throw new Error("LengthMatchingSolver: maximumMeanderDepth must be a positive finite number");
if (e48.minimumToothPitch !== undefined && (!Number.isFinite(e48.minimumToothPitch) || e48.minimumToothPitch <= 0))
throw new Error("LengthMatchingSolver: minimumToothPitch must be a positive finite number");
if (e48.minMeanderGap !== undefined && (!Number.isFinite(e48.minMeanderGap) || e48.minMeanderGap <= 0))
throw new Error("LengthMatchingSolver: minMeanderGap must be a positive finite number");
if (e48.minMeanderHeight !== undefined && (!Number.isFinite(e48.minMeanderHeight) || e48.minMeanderHeight <= 0))
throw new Error("LengthMatchingSolver: minMeanderHeight must be a positive finite number");
if (e48.minMeanderHeight !== undefined && e48.minMeanderHeight > t4)
throw new Error("LengthMatchingSolver: minMeanderHeight cannot exceed maximumMeanderDepth");
if (!Number.isFinite(n4) || !Number.isInteger(n4) || n4 <= 0)
throw new Error("LengthMatchingSolver: maxToothCount must be a positive finite integer");
for (const t6 of e48.traces ?? [])
w3(t6, e48.layerCount ?? 2);
return { maximumMeanderDepth: t4, minimumToothPitch: e48.minimumToothPitch, minMeanderGap: e48.minMeanderGap, minMeanderHeight: e48.minMeanderHeight, maxToothCount: n4, traces: e48.traces ?? [], obstacles: e48.obstacles ?? [], bounds: e48.bounds, obstacleMargin: e48.obstacleMargin ?? 0.15, layerCount: e48.layerCount ?? 2, colorMap: e48.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 e48 = structuredClone(this.matchedHdRoutes), t4 = this.activePair?.fullAttempts ?? [];
let n4 = null;
for (const e49 of t4)
(!n4 || e49.qualityScore > n4.qualityScore) && (n4 = e49);
if (!n4)
for (const e49 of this.activePair?.partialAttempts ?? [])
(!n4 || e49.addedLength > n4.addedLength || e49.addedLength === n4.addedLength && e49.qualityScore > n4.qualityScore) && (n4 = e49);
if (n4) {
const t6 = e48[n4.routeIndex];
t6 && (e48[n4.routeIndex] = { ...t6, route: structuredClone(n4.predictedRoute) });
}
return { matchedHdRoutes: e48 };
}
computeProgress() {
if (this.solved)
return 1;
if (this.pairs.length === 0)
return this.config ? 1 : 0;
const e48 = Math.max(0, this.nextPairIndex - 1), t4 = this.activePair ? this.activePair.candidateIndex / this.activePair.candidates.length : 0;
return Math.min(0.99, (e48 + t4) / this.pairs.length);
}
visualize() {
const e48 = this.getConfig();
return J3({ routes: this.matchedHdRoutes, obstacles: e48.obstacles, bounds: e48.bounds, layerCount: e48.layerCount, colorMap: e48.colorMap, activePair: this.activePair, currentAttempt: this.currentAttempt, solved: this.solved });
}
};
var K3 = 0.00000001;
var e48 = (e49, t4) => {
if (e49.route.length === 0)
throw new Error(`trace "${e49.connection_name}" has an empty route`);
if (e49.route.some((e50) => e50.route_type !== "wire" && e50.route_type !== "via"))
throw new Error(`trace "${e49.connection_name}" contains unsupported jumper or through-obstacle geometry`);
const n4 = e49.route.findIndex((e50) => e50.route_type === "wire"), o4 = e49.route[n4], i4 = e49.route.findLast((e50) => e50.route_type === "wire");
if (o4?.route_type !== "wire" || !i4)
throw new Error(`trace "${e49.connection_name}" must contain a wire point`);
const r4 = [], s4 = [], a4 = [], c4 = [];
let l4 = null, h4 = o4.width;
if (n4 > 0) {
let t6 = o4.layer;
for (let o6 = n4 - 1;o6 >= 0; o6--) {
const n6 = e49.route[o6];
if (n6?.route_type !== "via")
throw new Error(`trace "${e49.connection_name}" has unsupported geometry before its first wire`);
if (t6 === n6.to_layer)
t6 = n6.from_layer;
else {
if (t6 !== n6.from_layer)
throw new Error(`trace "${e49.connection_name}" has discontinuous leading vias`);
t6 = n6.to_layer;
}
}
const i6 = e49.route[0];
if (i6.route_type !== "via")
throw new Error(`trace "${e49.connection_name}" has an invalid leading entry`);
l4 = { x: i6.x, y: i6.y, layer: t6, width: o4.width }, r4.push(l4);
}
for (const n6 of e49.route) {
if (n6.route_type === "wire") {
if (!Number.isFinite(n6.x) || !Number.isFinite(n6.y) || !Number.isFinite(n6.width) || n6.width <= 0 || C3(n6.layer, t4) < 0)
throw new Error(`trace "${e49.connection_name}" has an invalid wire point`);
h4 = Math.max(h4, n6.width);
const o7 = { x: n6.x, y: n6.y, layer: n6.layer, width: n6.width };
if (l4) {
if (l4.layer !== o7.layer)
throw new Error(`trace "${e49.connection_name}" changes layers without a via`);
Math.hypot(l4.x - o7.x, l4.y - o7.y) > K3 && s4.push({ start: l4, end: o7, layer: o7.layer, width: Math.max(l4.width, o7.width), connectionName: e49.connection_name, terminal: null });
}
r4.push(o7), l4 = o7;
continue;
}
if (n6.route_type !== "via")
throw new Error(`trace "${e49.connection_name}" contains unsupported route geometry`);
if (!l4)
throw new Error(`trace "${e49.connection_name}" has a leading via`);
const o6 = C3(n6.from_layer, t4), i6 = C3(n6.to_layer, t4), d6 = n6.via_diameter ?? l4.width;
if (!Number.isFinite(n6.x) || !Number.isFinite(n6.y) || o6 < 0 || i6 < 0 || o6 === i6 || n6.via_diameter !== undefined && (!Number.isFinite(n6.via_diameter) || n6.via_diameter <= 0) || n6.via_hole_diameter !== undefined && (!Number.isFinite(n6.via_hole_diameter) || n6.via_hole_diameter <= 0 || n6.via_hole_diameter >= d6))
throw new Error(`trace "${e49.connection_name}" has an invalid via`);
const u4 = l4.layer === n6.from_layer ? n6.from_layer : l4.layer === n6.to_layer ? n6.to_layer : null;
if (!u4)
throw new Error(`trace "${e49.connection_name}" has a discontinuous via transition`);
Math.hypot(l4.x - n6.x, l4.y - n6.y) > K3 && s4.push({ start: l4, end: n6, layer: l4.layer, width: l4.width, connectionName: e49.connection_name, terminal: null });
const p4 = u4 === n6.from_layer ? n6.to_layer : n6.from_layer;
c4.push({ ...n6, from_layer: u4, to_layer: p4 }), a4.push({ x: n6.x, y: n6.y, layers: M3(u4, p4, t4), diameter: d6, connectionName: e49.connection_name, terminal: r4.length === 1 ? "start" : null }), l4 = { x: n6.x, y: n6.y, layer: p4, width: l4.width }, r4.push(l4);
}
if (r4.length < 2 || s4.length === 0)
throw new Error(`trace "${e49.connection_name}" does not contain a routable path`);
s4[0].terminal = s4.length === 1 ? "both" : "start", s4[s4.length - 1].terminal = s4.length === 1 ? "both" : "end";
const d4 = a4.at(-1);
return d4 && Math.hypot(d4.x - i4.x, d4.y - i4.y) <= K3 && (d4.terminal = "end"), { source: e49, points: r4, segments: s4, vias: a4, transitions: c4, width: h4, viaDiameter: e49.__postProcessingViaDiameter ?? h4, ...o4.start_pcb_port_id ? { startPortId: o4.start_pcb_port_id } : {}, ...i4.end_pcb_port_id ? { endPortId: i4.end_pcb_port_id } : {} };
};
var t4 = (e49) => e49.segments.reduce((e50, t6) => e50 + Math.hypot(t6.end.x - t6.start.x, t6.end.y - t6.start.y), 0);
var n4 = (e49) => {
const { simpleRouteJson: t6 } = e49.params, n6 = ((e50) => {
const t7 = new Set(e50.reroutedPairs.map((e51) => e51.connectionNames.join("\x00")));
return e50.declaredPairs.filter((n7) => {
const o6 = n7.connectionNames.map((t8) => e50.traces.filter((e51) => e51.connection_name === t8));
if (o6.some((e51) => e51.length !== 1))
return false;
if (t7.has(n7.connectionNames.join("\x00")))
return true;
const i6 = o6.map((e51) => e51[0]);
if (i6.some((e51) => e51.route.length < 2 || e51.route[0]?.route_type !== "wire" || !e51.route.every((e53) => e53.route_type === "wire" || e53.route_type === "via")))
return false;
const r6 = i6.map((t8) => t4(e48(t8, e50.layerCount)));
return Math.abs(r6[0] - r6[1]) > n7.lengthTolerance + 0.0000001;
}).map((e51) => structuredClone(e51));
})({ traces: e49.result.traces, declaredPairs: t6.differentialPairs, reroutedPairs: e49.result.reroutedPairs, layerCount: t6.layerCount }), o4 = new Set(n6.flatMap((e50) => e50.connectionNames)), i4 = [], r4 = [], s4 = [], a4 = new Set;
for (let n7 = 0;n7 < e49.result.traces.length; n7++) {
const c6 = e49.result.traces[n7];
if (!o4.has(c6.connection_name))
continue;
const l6 = c6.route.every((e50) => e50.route_type === "wire" || e50.route_type === "via"), h4 = c6.route[0]?.route_type === "wire";
if (!l6 || !h4)
throw new Error(`PostProcessingSolver: rerouted connection "${c6.connection_name}" cannot be bound to LengthMatchingSolver`);
const d4 = e48(c6, t6.layerCount), u4 = c6.route[0];
if (u4.route_type !== "wire")
throw new Error(`PostProcessingSolver: trace "${c6.connection_name}" lost its first wire during binding`);
const p4 = [{ x: u4.x, y: u4.y, z: C3(u4.layer, t6.layerCount), traceThickness: u4.width }], m4 = [], g4 = [];
let { layer: f4, width: _4 } = u4;
for (const e50 of c6.route.slice(1)) {
if (e50.route_type === "wire") {
if (e50.layer !== f4)
throw new Error(`PostProcessingSolver: trace "${c6.connection_name}" changes layers without a via while binding`);
p4.push({ x: e50.x, y: e50.y, z: C3(e50.layer, t6.layerCount), traceThickness: e50.width }), _4 = e50.width;
continue;
}
if (e50.route_type !== "via")
throw new Error(`PostProcessingSolver: trace "${c6.connection_name}" contains unsupported bound geometry`);
const n8 = f4 === e50.from_layer ? e50.to_layer : f4 === e50.to_layer ? e50.from_layer : null;
if (!n8)
throw new Error(`PostProcessingSolver: trace "${c6.connection_name}" has a discontinuous bound via`);
const o6 = p4.at(-1);
Math.hypot(o6.x - e50.x, o6.y - e50.y) > 0.00000001 && p4.push({ x: e50.x, y: e50.y, z: C3(f4, t6.layerCount), traceThickness: _4 }), p4.push({ x: e50.x, y: e50.y, z: C3(n8, t6.layerCount), traceThickness: _4 }), m4.push({ x: e50.x, y: e50.y, zLayers: M3(e50.from_layer, e50.to_layer, t6.layerCount).map((e51) => C3(e51, t6.layerCount)) }), g4.push({ ...e50 }), f4 = n8;
}
if (p4.length < 2)
throw new Error(`PostProcessingSolver: trace "${c6.connection_name}" has no bound copper segments`);
const y4 = Math.max(...p4.map((e50) => e50.traceThickness ?? d4.width)), b4 = d4.viaDiameter, x4 = i4.length;
i4.push({ connectionName: c6.connection_name, traceThickness: y4, viaDiameter: b4, route: p4, vias: m4 });
const v4 = p4[0], I4 = p4.at(-1);
r4.push({ name: c6.connection_name, pointsToConnect: [{ x: v4.x, y: v4.y, layer: u4.layer, ...d4.startPortId ? { pcb_port_id: d4.startPortId } : {} }, { x: I4.x, y: I4.y, layer: d4.points.at(-1).layer, ...d4.endPortId ? { pcb_port_id: d4.endPortId } : {} }] }), s4.push({ traceIndex: n7, matchedRouteIndex: x4, viaTemplates: g4, startEndpoint: { ...v4 }, endEndpoint: { ...I4 }, ...d4.startPortId ? { startPortId: d4.startPortId } : {}, ...d4.endPortId ? { endPortId: d4.endPortId } : {} }), a4.add(c6.connection_name);
}
for (const e50 of o4)
if (!a4.has(e50))
throw new Error(`PostProcessingSolver: missing LengthMatchingSolver binding for rerouted connection "${e50}"`);
const c4 = e49.result.traces.filter((e50) => !o4.has(e50.connection_name)), l4 = t6.minTraceToPadEdgeClearance ?? Math.max(0, ...i4.filter((e50) => e50.route.length >= 2).map((e50) => e50.traceThickness), ...c4.flatMap((e50) => w3(e50, t6.layerCount).segments.map((e51) => e51.width)));
return { solverParams: { hdRoutes: i4, traces: c4, originalConnections: r4, differentialPairs: n6, obstacles: t6.obstacles, bounds: t6.bounds, layerCount: t6.layerCount, obstacleMargin: l4 }, traceBindings: s4, baseTraces: structuredClone(e49.result.traces) };
};
var o4 = (e49) => {
const t6 = new Map;
for (const n7 of e49.differentialPairs)
for (const o7 of n7.connectionNames) {
const n8 = e49.hdRoutes.map((e50, t7) => ({ route: e50, hdRouteIndex: t7 })).filter(({ route: e50 }) => e50.connectionName === o7);
n8.length === 1 && t6.set(n8[0].hdRouteIndex, o7);
}
const n6 = e49.hdRoutes.map((t7, n7) => {
const o7 = [], i6 = new Map;
for (let e50 = 0;e50 < (t7.jumpers?.length ?? 0); e50++) {
const n8 = t7.jumpers[e50], o8 = t7.route.map((e51, t8) => ({ point: e51, index: t8 })).filter(({ point: e51 }) => Math.hypot(e51.x - n8.start.x, e51.y - n8.start.y) <= 0.00000001).map(({ index: e51 }) => e51), r4 = t7.route.map((e51, t8) => ({ point: e51, index: t8 })).filter(({ point: e51 }) => Math.hypot(e51.x - n8.end.x, e51.y - n8.end.y) <= 0.00000001).map(({ index: e51 }) => e51), s4 = [...o8.flatMap((e51) => r4.filter((t8) => t8 > e51).map((t8) => ({ startIndex: e51, endIndex: t8 }))), ...r4.flatMap((e51) => o8.filter((t8) => t8 > e51).map((t8) => ({ startIndex: e51, endIndex: t8 })))];
if (s4.length !== 1)
throw new Error(`PostProcessingSolver: immutable HD route "${t7.connectionName}" has an ambiguous jumper traversal`);
const a4 = s4[0];
if (i6.has(a4.startIndex) || [...i6.values()].some(({ endIndex: e51 }) => a4.startIndex < e51 || a4.endIndex <= e51))
throw new Error(`PostProcessingSolver: immutable HD route "${t7.connectionName}" has overlapping or unordered jumpers`);
i6.set(a4.startIndex, { endIndex: a4.endIndex, jumperIndex: e50 });
}
if (t7.route.length > 0) {
const n8 = t7.route[0];
o7.push({ route_type: "wire", x: n8.x, y: n8.y, width: n8.traceThickness ?? t7.traceThickness, layer: P3(n8.z, e49.layerCount) });
for (let n9 = 0;n9 < t7.route.length - 1; n9++) {
const r6 = t7.route[n9], s6 = i6.get(n9);
if (s6) {
const i7 = t7.route[s6.endIndex], a7 = t7.jumpers[s6.jumperIndex];
if (r6.z !== i7.z)
throw new Error(`PostProcessingSolver: immutable HD route "${t7.connectionName}" changes layers through a jumper`);
o7.push({ route_type: "jumper", start: { x: r6.x, y: r6.y }, end: { x: i7.x, y: i7.y }, footprint: a7.footprint, layer: P3(r6.z, e49.layerCount) }), o7.push({ route_type: "wire", x: i7.x, y: i7.y, width: i7.traceThickness ?? t7.traceThickness, layer: P3(i7.z, e49.layerCount) }), n9 = s6.endIndex - 1;
continue;
}
const a6 = t7.route[n9 + 1], c4 = P3(r6.z, e49.layerCount), l4 = P3(a6.z, e49.layerCount);
r6.z !== a6.z && (r6.toNextSegmentType === "through_obstacle" ? o7.push({ route_type: "through_obstacle", start: { x: r6.x, y: r6.y }, end: { x: a6.x, y: a6.y }, from_layer: c4, to_layer: l4, width: r6.traceThickness ?? t7.traceThickness }) : o7.push({ route_type: "via", x: a6.x, y: a6.y, from_layer: c4, to_layer: l4, via_diameter: t7.viaDiameter })), o7.push({ route_type: "wire", x: a6.x, y: a6.y, width: a6.traceThickness ?? t7.traceThickness, layer: l4 });
}
const r4 = o7.filter((e50) => e50.route_type === "wire"), s4 = t7.startPcbPortId ?? t7.route[0]?.pcb_port_id, a4 = t7.endPcbPortId ?? t7.route.at(-1)?.pcb_port_id;
s4 && r4[0] && (r4[0].start_pcb_port_id = s4), a4 && r4.at(-1) && (r4.at(-1).end_pcb_port_id = a4);
}
return { type: "pcb_trace", pcb_trace_id: `post_processing_hd_route_${n7}`, connection_name: t7.connectionName, __postProcessingViaDiameter: t7.viaDiameter, route: o7 };
}), o6 = new Set(n6.map((e50) => e50.connection_name));
for (const [t7, i6] of (e49.traces ?? []).entries()) {
let e50 = `post_processing_fixed_trace_${t7}`;
for (;o6.has(e50); )
e50 += "_";
o6.add(e50), n6.push({ ...structuredClone(i6), connection_name: e50 });
}
const i4 = structuredClone(e49.obstacles);
for (let n7 = 0;n7 < e49.hdRoutes.length; n7++) {
const o7 = e49.hdRoutes[n7], r4 = new Set([o7.connectionName, o7.rootConnectionName, o7.startPcbPortId, o7.endPcbPortId, o7.route[0]?.pcb_port_id, o7.route.at(-1)?.pcb_port_id, t6.get(n7)].filter((e50) => e50 !== undefined));
for (const e50 of i4)
e50.connectedTo.some((e51) => r4.has(e51)) && (e50.connectedTo = [...new Set([...e50.connectedTo, ...r4])]);
}
return { params: { simpleRouteJson: { traces: n6, differentialPairs: structuredClone(e49.differentialPairs), obstacles: i4, bounds: structuredClone(e49.bounds), layerCount: e49.layerCount, minTraceToPadEdgeClearance: e49.minTraceToPadEdgeClearance }, ...e49.routingGrid ? { routingGrid: structuredClone(e49.routingGrid) } : {} }, routeBindings: [...t6.entries()].map(([e50, t7]) => ({ hdRouteIndex: e50, traceIndex: e50, internalConnectionName: t7 })), sourceHdRoutes: structuredClone(e49.hdRoutes) };
};
function i4(e49) {
const t6 = structuredClone(e49.model.sourceHdRoutes);
for (const n6 of e49.model.routeBindings) {
const o6 = e49.binding.traceBindings.find((e50) => e50.traceIndex === n6.traceIndex);
if (!o6)
continue;
const i6 = e49.result.matchedHdRoutes[o6.matchedRouteIndex], r4 = t6[n6.hdRouteIndex];
if (!i6 || !r4)
throw new Error(`PostProcessingSolver: missing matched or source HD route for "${n6.internalConnectionName}"`);
if (i6.connectionName !== n6.internalConnectionName)
throw new Error(`PostProcessingSolver: matched HD binding changed "${n6.internalConnectionName}" to "${i6.connectionName}"`);
const s4 = i6.route.map((e50) => ({ ...e50 })), a4 = (t7, o7) => {
if (t7 && o7 && (o7.pcb_port_id && (t7.pcb_port_id = o7.pcb_port_id), o7.insideJumperPad && e49.rejectInsideJumperPad))
throw new Error(`PostProcessingSolver: cannot restore jumper-pad metadata on rerouted connection "${n6.internalConnectionName}"`);
};
a4(s4[0], r4.route[0]), a4(s4.at(-1), r4.route.at(-1)), t6[n6.hdRouteIndex] = { ...r4, route: s4, vias: structuredClone(i6.vias) };
}
return { hdRoutes: t6, postProcessingErrors: [] };
}
var r4 = class extends Error {
connectionNames;
reason;
constructor(e49) {
super(`PostProcessingSolver: differential pair ${e49.connectionNames.join("/")} ${e49.message}`), this.name = "DifferentialPairRoutingError", this.connectionNames = [e49.connectionNames[0], e49.connectionNames[1]], this.reason = e49.reason;
}
};
var s4 = class extends Error {
connectionNames;
reason;
constructor(e49) {
super(e49.message), this.name = "PostProcessingConstraintError", this.connectionNames = [...e49.connectionNames], this.reason = e49.reason;
}
};
var a4 = class extends Error {
reason = "grid-capacity-exhausted";
constructor(e49) {
super(e49), this.name = "PostProcessingGridCapacityError";
}
};
var c4 = (e49) => {
const t6 = 75000 * e49.simpleRouteJson.differentialPairs.length;
if (!Number.isSafeInteger(t6))
throw new Error("PostProcessingSolver: derived rerouting iteration bound exceeds the safe integer range");
const n6 = Math.min(t6, 80000);
return Math.max(1, n6);
};
var l4 = (e49) => structuredClone(e49);
var h4 = (e49, t6, n6) => {
const o6 = (e50) => {
const n7 = -(t6.ccwRotationDegrees ?? 0) * Math.PI / 180, o7 = e50.x - t6.center.x, i7 = e50.y - t6.center.y;
return { x: o7 * Math.cos(n7) - i7 * Math.sin(n7), y: o7 * Math.sin(n7) + i7 * Math.cos(n7) };
}, i6 = o6(e49.start), r6 = o6(e49.end), s6 = t6.width / 2 + n6, a6 = t6.height / 2 + n6;
if (Math.abs(i6.x) <= s6 && Math.abs(i6.y) <= a6 || Math.abs(r6.x) <= s6 && Math.abs(r6.y) <= a6)
return true;
const c6 = [{ x: -s6, y: -a6 }, { x: s6, y: -a6 }, { x: s6, y: a6 }, { x: -s6, y: a6 }];
return c6.some((e50, t7) => R3(i6, r6, e50, c6[(t7 + 1) % c6.length]) <= 0.0000001);
};
var d4 = (e49) => {
const t6 = [], n6 = [];
for (const o7 of e49.immutableTraces) {
const i7 = w3(o7, e49.layerCount);
t6.push(...i7.segments), n6.push(...i7.vias);
}
const o6 = Array.from({ length: e49.layerCount }, () => []);
for (const n7 of t6) {
const t7 = C3(n7.layer, e49.layerCount);
o6[t7].push(n7);
}
const i6 = (e50, t7) => Math.hypot(e50.x - t7.x, e50.y - t7.y) <= 0.00000001, r6 = (e50, t7, n7) => {
const o7 = n7.x - t7.x, i7 = n7.y - t7.y, r7 = o7 * o7 + i7 * i7, s7 = r7 === 0 ? 0 : Math.max(0, Math.min(1, ((e50.x - t7.x) * o7 + (e50.y - t7.y) * i7) / r7));
return Math.hypot(e50.x - t7.x - o7 * s7, e50.y - t7.y - i7 * s7);
}, s6 = (e50, t7, n7) => {
const o7 = -(t7.ccwRotationDegrees ?? 0) * Math.PI / 180, i7 = e50.x - t7.center.x, r7 = e50.y - t7.center.y, s7 = i7 * Math.cos(o7) - r7 * Math.sin(o7), a7 = i7 * Math.sin(o7) + r7 * Math.cos(o7);
return Math.abs(s7) <= t7.width / 2 + n7 && Math.abs(a7) <= t7.height / 2 + n7;
}, a6 = (t7, n7) => {
const o7 = C3(n7, e49.layerCount);
return k3(t7, e49.layerCount).includes(o7);
}, c6 = (t7, n7, o7) => {
const i7 = ((t8, n8, o8) => {
const i8 = Math.hypot(n8.x, n8.y);
if (i8 <= 0.0000000001)
throw new Error("PostProcessingSolver: cannot orient terminal fanout on a zero-length spine");
const r8 = -n8.y / i8 * e49.side * e49.centerlineSpacing / 2, s7 = n8.x / i8 * e49.side * e49.centerlineSpacing / 2, a7 = o8 === "start" ? [e49.firstStartTerminal, e49.secondStartTerminal] : [e49.firstEndTerminal, e49.secondEndTerminal], c7 = [e49.firstWidth, e49.secondWidth], l7 = [e49.firstConnectionName, e49.secondConnectionName];
return a7.map((e50, n9) => {
const i9 = n9 === 0 ? 1 : -1, a8 = { x: t8.x + r8 * i9, y: t8.y + s7 * i9 };
return { start: o8 === "start" ? e50 : a8, end: o8 === "start" ? a8 : e50, layer: t8.layer, width: c7[n9], connectionName: l7[n9], terminal: o8 };
});
})(t7, n7, o7), r7 = i7.map((e50) => o7 === "start" ? e50.end : e50.start);
return i7.every(l6) && r7.every((n8, o8) => e49.obstacles.every((r8) => !a6(r8, t7.layer) || !s6(n8, r8, 1.5 * i7[o8].width + (e49.terminalMiterMargin ?? 0)))) && R3(i7[0].start, i7[0].end, i7[1].start, i7[1].end) >= i7[0].width / 2 + i7[1].width / 2 - 0.0000001;
}, l6 = (t7) => {
const i7 = t7.width / 2, c7 = i7 + (e49.minTraceToPadEdgeClearance ?? t7.width), l7 = C3(t7.layer, e49.layerCount), h7 = Math.min(t7.start.x, t7.end.x), d6 = Math.max(t7.start.x, t7.end.x), u4 = Math.min(t7.start.y, t7.end.y), p4 = Math.max(t7.start.y, t7.end.y);
for (const n7 of [t7.start, t7.end])
if (n7.x - i7 < e49.bounds.minX || n7.x + i7 > e49.bounds.maxX || n7.y - i7 < e49.bounds.minY || n7.y + i7 > e49.bounds.maxY)
return false;
for (const n7 of e49.obstacles) {
if (!a6(n7, t7.layer))
continue;
const o7 = Math.hypot(n7.width / 2 + c7, n7.height / 2 + c7);
if (d6 < n7.center.x - o7 || h7 > n7.center.x + o7 || p4 < n7.center.y - o7 || u4 > n7.center.y + o7)
continue;
const [i8, r7] = t7.connectionName === e49.firstConnectionName ? [e49.firstStartTerminal, e49.firstEndTerminal] : [e49.secondStartTerminal, e49.secondEndTerminal], l8 = s6(i8, n7, 0) && (s6(t7.start, n7, c7) || s6(t7.end, n7, c7)) && Math.hypot(t7.end.x - i8.x, t7.end.y - i8.y) >= Math.hypot(t7.start.x - i8.x, t7.start.y - i8.y), m4 = s6(r7, n7, 0) && (s6(t7.start, n7, c7) || s6(t7.end, n7, c7)) && Math.hypot(t7.end.x - r7.x, t7.end.y - r7.y) <= Math.hypot(t7.start.x - r7.x, t7.start.y - r7.y);
if (!(n7.connectedTo.includes(t7.connectionName) && (l8 || m4)) && h4(t7, n7, c7))
return false;
}
for (const e50 of o6[l7]) {
const n7 = t7.width / 2 + e50.width / 2 + Math.max(t7.width, e50.width);
if (!(d6 + n7 < Math.min(e50.start.x, e50.end.x) || h7 - n7 > Math.max(e50.start.x, e50.end.x) || p4 + n7 < Math.min(e50.start.y, e50.end.y) || u4 - n7 > Math.max(e50.start.y, e50.end.y)) && R3(t7.start, t7.end, e50.start, e50.end) < n7)
return false;
}
for (const e50 of n6)
if (e50.layers.includes(t7.layer) && r6(e50, t7.start, t7.end) < t7.width / 2 + e50.diameter / 2 + t7.width)
return false;
return true;
}, h6 = (o7) => {
const i7 = o7.diameter / 2;
if (o7.x - i7 < e49.bounds.minX || o7.x + i7 > e49.bounds.maxX || o7.y - i7 < e49.bounds.minY || o7.y + i7 > e49.bounds.maxY)
return false;
for (const t7 of e49.obstacles) {
if (!o7.layers.some((e50) => a6(t7, e50)))
continue;
if (!(o7.terminal !== null && t7.connectedTo.includes(o7.connectionName) && s6(o7, t7, 0)) && s6(o7, t7, i7 + o7.diameter))
return false;
}
for (const e50 of t6) {
if (!o7.layers.includes(e50.layer))
continue;
const t7 = i7 + e50.width / 2 + Math.max(o7.diameter, e50.width);
if (r6(o7, e50.start, e50.end) < t7)
return false;
}
for (const e50 of n6) {
if (!e50.layers.some((e51) => o7.layers.includes(e51)))
continue;
const t7 = i7 + e50.diameter / 2 + Math.max(o7.diameter, e50.diameter);
if (Math.hypot(o7.x - e50.x, o7.y - e50.y) < t7)
return false;
}
return true;
};
return { isEdgeValid: (t7, n7) => {
if (t7.layer !== n7.layer || !((t8, n8) => {
const o8 = Math.hypot(n8.x - t8.x, n8.y - t8.y);
if (o8 === 0)
return [];
const r7 = -(n8.y - t8.y) / o8 * e49.side * e49.centerlineSpacing / 2, s7 = (n8.x - t8.x) / o8 * e49.side * e49.centerlineSpacing / 2, a7 = i6(t8, e49.start), c7 = i6(n8, e49.end), l7 = e49.terminalFanout ? a7 && c7 ? "both" : a7 ? "start" : c7 ? "end" : null : null, h7 = a7 && e49.terminalFanout ? e49.firstStartTerminal : { x: t8.x + r7, y: t8.y + s7 }, d6 = c7 && e49.terminalFanout ? e49.firstEndTerminal : { x: n8.x + r7, y: n8.y + s7 }, u4 = a7 && e49.terminalFanout ? e49.secondStartTerminal : { x: t8.x - r7, y: t8.y - s7 }, p4 = c7 && e49.terminalFanout ? e49.secondEndTerminal : { x: n8.x - r7, y: n8.y - s7 };
return [{ start: h7, end: d6, layer: t8.layer, width: e49.firstWidth, connectionName: e49.firstConnectionName, terminal: l7 }, { start: u4, end: p4, layer: t8.layer, width: e49.secondWidth, connectionName: e49.secondConnectionName, terminal: l7 }];
})(t7, n7).every(l6))
return false;
if (e49.terminalFanout || e49.terminalMiterMargin === undefined)
return true;
const o7 = { x: n7.x - t7.x, y: n7.y - t7.y };
return !(i6(t7, e49.start) && !c6(t7, o7, "start")) && !(i6(n7, e49.end) && !c6(n7, o7, "end"));
}, isTerminalFanoutValid: c6, isViaValid: (t7, n7, o7) => {
const r7 = Math.hypot(o7.x, o7.y);
if (r7 <= 0.0000000001)
throw new Error("PostProcessingSolver: cannot orient a coupled via on a zero-length spine");
const s7 = M3(t7.layer, n7, e49.layerCount), a7 = -o7.y / r7 * e49.side * e49.centerlineSpacing / 2, c7 = o7.x / r7 * e49.side * e49.centerlineSpacing / 2, l7 = i6(t7, e49.start) ? "start" : i6(t7, e49.end) ? "end" : null;
return [{ x: t7.x + a7, y: t7.y + c7, layers: s7, diameter: e49.firstViaDiameter, connectionName: e49.firstConnectionName, terminal: l7 }, { x: t7.x - a7, y: t7.y - c7, layers: s7, diameter: e49.secondViaDiameter, connectionName: e49.secondConnectionName, terminal: l7 }].every(h6);
} };
};
var u4 = (e49, t6, n6) => {
const o6 = 0.0000001, i6 = (e50, t7) => {
const n7 = -(t7.ccwRotationDegrees ?? 0) * Math.PI / 180, o7 = e50.x - t7.center.x, i7 = e50.y - t7.center.y;
return { x: o7 * Math.cos(n7) - i7 * Math.sin(n7), y: o7 * Math.sin(n7) + i7 * Math.cos(n7) };
}, r6 = (e50, t7, n7) => {
const o7 = n7.x - t7.x, i7 = n7.y - t7.y, r7 = o7 * o7 + i7 * i7, s7 = r7 === 0 ? 0 : Math.max(0, Math.min(1, ((e50.x - t7.x) * o7 + (e50.y - t7.y) * i7) / r7));
return Math.hypot(e50.x - (t7.x + s7 * o7), e50.y - (t7.y + s7 * i7));
}, s6 = (e50, t7, n7) => {
const o7 = C3(t7, n7);
return k3(e50, n7).includes(o7);
}, a6 = (e50, t7, n7) => {
const a7 = e50.width / 2;
if (e50.start.x - a7 < t7.bounds.minX - o6 || e50.start.x + a7 > t7.bounds.maxX + o6 || e50.start.y - a7 < t7.bounds.minY - o6 || e50.start.y + a7 > t7.bounds.maxY + o6 || e50.end.x - a7 < t7.bounds.minX - o6 || e50.end.x + a7 > t7.bounds.maxX + o6 || e50.end.y - a7 < t7.bounds.minY - o6 || e50.end.y + a7 > t7.bounds.maxY + o6)
return false;
for (const n8 of t7.obstacles) {
if (!s6(n8, e50.layer, t7.layerCount))
continue;
const r7 = e50.terminal === "both" ? [e50.start, e50.end] : e50.terminal === "start" ? [e50.start] : e50.terminal === "end" ? [e50.end] : [];
if (!(n8.connectedTo.includes(e50.connectionName) && r7.some((e51) => {
const t8 = i6(e51, n8);
return Math.abs(t8.x) <= n8.width / 2 + o6 && Math.abs(t8.y) <= n8.height / 2 + o6;
})) && h4(e50, n8, a7 + (t7.minTraceToPadEdgeClearance ?? e50.width)))
return false;
}
for (const t8 of n7.segments) {
if (t8.layer !== e50.layer)
continue;
const n8 = e50.width / 2 + t8.width / 2 + Math.max(e50.width, t8.width);
if (R3(e50.start, e50.end, t8.start, t8.end) < n8 - o6)
return false;
}
for (const t8 of n7.vias) {
if (!t8.layers.includes(e50.layer))
continue;
const n8 = e50.width / 2 + t8.diameter / 2 + e50.width;
if (r6(t8, e50.start, e50.end) < n8 - o6)
return false;
}
return true;
}, c6 = (e50, t7, n7) => {
const a7 = e50.diameter / 2;
if (e50.x - a7 < t7.bounds.minX - o6 || e50.x + a7 > t7.bounds.maxX + o6 || e50.y - a7 < t7.bounds.minY - o6 || e50.y + a7 > t7.bounds.maxY + o6)
return false;
for (const n8 of t7.obstacles) {
if (!e50.layers.some((e51) => s6(n8, e51, t7.layerCount)))
continue;
const r7 = i6(e50, n8);
if (!(e50.terminal !== null && n8.connectedTo.includes(e50.connectionName) && Math.abs(r7.x) <= n8.width / 2 + o6 && Math.abs(r7.y) <= n8.height / 2 + o6) && Math.abs(r7.x) <= n8.width / 2 + a7 + e50.diameter && Math.abs(r7.y) <= n8.height / 2 + a7 + e50.diameter)
return false;
}
for (const t8 of n7.segments) {
if (!e50.layers.includes(t8.layer))
continue;
const n8 = a7 + t8.width / 2 + Math.max(e50.diameter, t8.width);
if (r6(e50, t8.start, t8.end) < n8 - o6)
return false;
}
for (const t8 of n7.vias) {
if (!t8.layers.some((t9) => e50.layers.includes(t9)))
continue;
const n8 = a7 + t8.diameter / 2 + Math.max(e50.diameter, t8.diameter);
if (Math.hypot(e50.x - t8.x, e50.y - t8.y) < n8 - o6)
return false;
}
return true;
}, l6 = (e50) => {
for (let t7 = 0;t7 < e50.segments.length; t7++) {
const n7 = e50.segments[t7];
for (let i7 = t7 + 2;i7 < e50.segments.length; i7++) {
const r7 = e50.segments[i7];
if (n7.layer !== r7.layer)
continue;
if (!(e50.segments.slice(t7 + 1, i7).reduce((e51, t8) => e51 + Math.hypot(t8.end.x - t8.start.x, t8.end.y - t8.start.y), 0) <= n7.width + r7.width + o6) && R3(n7.start, n7.end, r7.start, r7.end) < n7.width / 2 + r7.width / 2 - o6)
return true;
}
}
for (const t7 of e50.vias)
for (const n7 of e50.segments) {
if (!t7.layers.includes(n7.layer))
continue;
if (!(Math.hypot(t7.x - n7.start.x, t7.y - n7.start.y) <= o6 || Math.hypot(t7.x - n7.end.x, t7.y - n7.end.y) <= o6) && r6(t7, n7.start, n7.end) < t7.diameter / 2 + n7.width / 2 - o6)
return true;
}
return false;
}, h6 = ((e50, t7) => {
const n7 = [], o7 = [];
for (const i7 of e50) {
const e51 = w3(i7, t7);
n7.push(...e51.segments), o7.push(...e51.vias);
}
return { segments: n7, vias: o7 };
})(n6.immutableTraces, n6.layerCount);
if (!((e50, t7) => {
for (const n7 of e50.segments)
for (const e51 of t7.segments) {
if (n7.layer !== e51.layer)
continue;
const t8 = n7.width / 2 + e51.width / 2;
if (R3(n7.start, n7.end, e51.start, e51.end) < t8 - o6)
return false;
}
for (const [n7, i7] of [[e50.vias, t7.segments], [t7.vias, e50.segments]])
for (const e51 of n7)
for (const t8 of i7)
if (e51.layers.includes(t8.layer) && r6(e51, t8.start, t8.end) < e51.diameter / 2 + t8.width / 2 - o6)
return false;
for (const n7 of e50.vias)
for (const e51 of t7.vias)
if (n7.layers.some((t8) => e51.layers.includes(t8)) && Math.hypot(n7.x - e51.x, n7.y - e51.y) < n7.diameter / 2 + e51.diameter / 2 - o6)
return false;
return true;
})(e49, t6) || l6(e49) || l6(t6))
return false;
for (const o7 of [e49, t6])
if (o7.segments.some((e50) => !a6(e50, n6, h6)) || o7.vias.some((e50) => !c6(e50, n6, h6)))
return false;
return true;
};
var p4 = [{ 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 }];
var m4 = class {
constructor(e49) {
this.input = e49;
const { bounds: t6, grid: n6 } = e49, o6 = { minX: t6.minX + n6.outerPerimeterWidth, maxX: t6.maxX - n6.outerPerimeterWidth, minY: t6.minY + n6.outerPerimeterWidth, maxY: t6.maxY - n6.outerPerimeterWidth }, i6 = this.createAxis(t6.minX, t6.maxX, n6.outerGridStep, [o6.minX, o6.maxX]), r6 = this.createAxis(t6.minY, t6.maxY, n6.outerGridStep, [o6.minY, o6.maxY]), s6 = this.createAxis(o6.minX, o6.maxX, n6.innerGridStep, [], e49.start.x), a6 = this.createAxis(o6.minY, o6.maxY, n6.innerGridStep, [], e49.start.y), c6 = this.createGrid(i6, r6, (e50) => e50.x <= o6.minX || e50.x >= o6.maxX || e50.y <= o6.minY || e50.y >= o6.maxY), l6 = this.createGrid(s6, a6, () => true);
this.connectLocalNeighbors(c6), this.connectLocalNeighbors(l6);
for (const e50 of ["left", "right", "bottom", "top"])
this.connectBoundaries(e50, c6, l6, o6);
const h6 = this.nodes.map((e50, t7) => t7);
this.connectEndpoint(e49.start, h6), this.connectEndpoint(e49.end, h6);
}
input;
nodes = [];
nodeIdByPoint = new Map;
endpointNodeIdByPoint = new Map;
getPlanarNeighbors(e49) {
const t6 = this.endpointNodeIdByPoint.get(this.exactKeyFor(e49)) ?? this.nodeIdByPoint.get(this.keyFor(e49));
if (t6 === undefined)
throw new Error(`PostProcessingSolver: coupled path point (${e49.x}, ${e49.y}) is not on the composite grid`);
return [...this.nodes[t6].neighborIds].map((t7) => ({ ...this.nodes[t7].point, layer: e49.layer }));
}
getNodeCount() {
return this.nodes.length;
}
getSearchStateCountUpperBound(e49) {
const t6 = this.nodes.reduce((e50, t7) => e50 + t7.neighborIds.size, 0) * e49 + 1;
if (!Number.isSafeInteger(t6))
throw new Error("PostProcessingSolver: composite-grid search-state bound exceeds the safe integer range");
return t6;
}
createAxis(e49, t6, n6, o6, i6 = e49) {
const r6 = [e49, t6, ...o6].map((e50) => ({ value: e50, fixed: true }));
for (let o7 = Math.ceil((e49 - i6) / n6);i6 + o7 * n6 < t6 - 0.00000001; o7++)
r6.push({ value: i6 + o7 * n6, fixed: false });
r6.sort((e50, t7) => e50.value - t7.value || Number(t7.fixed) - Number(e50.fixed));
const s6 = [];
for (const e50 of r6) {
const t7 = s6.at(-1);
!t7 || Math.abs(e50.value - t7.value) > 0.00000001 ? s6.push(e50) : e50.fixed && !t7.fixed && (s6[s6.length - 1] = e50);
}
return s6.map((e50) => e50.value);
}
createGrid(e49, t6, n6) {
return t6.map((t7) => e49.map((e50) => {
const o6 = { x: e50, y: t7 };
return n6(o6) ? this.addNode(o6) : null;
}));
}
connectLocalNeighbors(e49) {
for (let t6 = 0;t6 < e49.length; t6++)
for (let n6 = 0;n6 < (e49[t6]?.length ?? 0); n6++) {
const o6 = e49[t6][n6];
if (o6 !== null)
for (const i6 of p4) {
const r6 = e49[t6 + i6.y]?.[n6 + i6.x];
r6 != null && this.connect(o6, r6);
}
}
}
connectBoundaries(e49, t6, n6, o6) {
const i6 = e49 === "left" ? o6.minX : e49 === "right" ? o6.maxX : e49 === "bottom" ? o6.minY : o6.maxY, r6 = e49 === "left" || e49 === "right", s6 = (e50) => Math.abs((r6 ? e50.x : e50.y) - i6) <= 0.00000001, a6 = (e50) => {
const t7 = new Set;
for (const n7 of e50)
for (const e51 of n7)
e51 !== null && s6(this.nodes[e51].point) && t7.add(e51);
return [...t7].sort((e51, t8) => {
const n7 = this.nodes[e51].point, o7 = this.nodes[t8].point;
return (r6 ? n7.y - o7.y : n7.x - o7.x) || e51 - t8;
});
}, c6 = a6(t6), l6 = a6(n6);
if (c6.length === 0 || l6.length === 0)
throw new Error(`PostProcessingSolver: composite grid has no ${e49} boundary bridge candidates`);
for (const e50 of c6)
this.connect(e50, this.findNearestAlongBoundary(e50, l6, r6));
for (const e50 of l6)
this.connect(e50, this.findNearestAlongBoundary(e50, c6, r6));
}
findNearestAlongBoundary(e49, t6, n6) {
const o6 = this.nodes[e49].point;
let i6 = t6[0], r6 = Number.POSITIVE_INFINITY;
for (const e50 of t6) {
const t7 = this.nodes[e50].point, s6 = Math.abs(n6 ? o6.y - t7.y : o6.x - t7.x);
(s6 < r6 - 0.00000001 || Math.abs(s6 - r6) <= 0.00000001 && e50 < i6) && (r6 = s6, i6 = e50);
}
return i6;
}
connectEndpoint(e49, t6) {
const n6 = this.nodeIdByPoint.get(this.keyFor(e49)), o6 = n6 === undefined ? null : this.nodes[n6].point, i6 = o6?.x === e49.x && o6.y === e49.y ? n6 : this.nodes.push({ point: { x: e49.x, y: e49.y }, neighborIds: new Set }) - 1;
this.endpointNodeIdByPoint.set(this.exactKeyFor(e49), i6);
const r6 = (e50, n7) => {
const o7 = this.nodes[e50].point, i7 = t6.filter((t7) => t7 !== e50).map((e51) => ({ nodeId: e51, distance: Math.hypot(this.nodes[e51].point.x - o7.x, this.nodes[e51].point.y - o7.y) })).filter(({ distance: e51 }) => e51 > 0.0000000001).sort((e51, t7) => e51.distance - t7.distance || e51.nodeId - t7.nodeId).slice(0, n7);
if (i7.length === 0)
throw new Error("PostProcessingSolver: composite grid has no endpoint connection candidates");
for (const { nodeId: t7 } of i7)
this.connect(e50, t7);
};
r6(i6, 8);
for (const t7 of p4) {
const n7 = { x: e49.x + t7.x * this.input.grid.innerGridStep, y: e49.y + t7.y * this.input.grid.innerGridStep };
if (n7.x < this.input.bounds.minX || n7.x > this.input.bounds.maxX || n7.y < this.input.bounds.minY || n7.y > this.input.bounds.maxY)
continue;
const o7 = this.addNode(n7);
this.connect(i6, o7), r6(o7, 4);
}
}
addNode(e49) {
const t6 = this.keyFor(e49), n6 = this.nodeIdByPoint.get(t6);
if (n6 !== undefined)
return n6;
const o6 = this.nodes.length;
return this.nodes.push({ point: { x: e49.x, y: e49.y }, neighborIds: new Set }), this.nodeIdByPoint.set(t6, o6), o6;
}
connect(e49, t6) {
if (e49 === t6)
return;
const n6 = this.nodes[e49], o6 = this.nodes[t6];
n6.neighborIds.add(t6), o6.neighborIds.add(e49);
}
keyFor(e49) {
const t6 = Object.is(e49.x, -0) ? 0 : e49.x, n6 = Object.is(e49.y, -0) ? 0 : e49.y;
return `${t6.toFixed(12)}:${n6.toFixed(12)}`;
}
exactKeyFor(e49) {
return `${Object.is(e49.x, -0) ? 0 : e49.x}:${Object.is(e49.y, -0) ? 0 : e49.y}`;
}
};
var g4 = class {
constructor(e49) {
if (this.input = e49, this.startLayer = C3(e49.start.layer, e49.layerCount), this.endLayer = C3(e49.end.layer, e49.layerCount), this.grid = new m4(e49), this.maxSearchStates = this.grid.getSearchStateCountUpperBound(e49.layerCount), this.exploredStateLimit = Math.min(this.maxSearchStates, 20000), this.startLayer < 0 || this.endLayer < 0)
return this.queue = [], void (this.status = "exhausted");
const t6 = { point: e49.start, direction: null, cost: 0, estimate: this.estimate(e49.start), parent: null, sequence: 0 };
this.queue = [t6], this.bestCosts.set(this.keyFor(e49.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 this.status !== "searching";
}
getPath() {
return this.result;
}
getPreviewPath() {
return this.current ? this.createPath(this.current) : [this.input.start];
}
getExploredCount() {
return this.explored;
}
getProgress() {
return this.status !== "searching" ? 1 : Math.min(0.99, this.explored / this.exploredStateLimit);
}
getGridNodeCount() {
return this.grid.getNodeCount();
}
step() {
if (this.status !== "searching")
return;
const e49 = this.popQueue();
if (!e49)
return void (this.status = "exhausted");
const t6 = this.bestCosts.get(this.keyFor(e49.point, e49.direction));
if (t6 === undefined)
throw new Error("PostProcessingSolver: coupled path queue contains an untracked state");
if (e49.cost > t6 + 0.0000000001)
this.queue.length === 0 && (this.status = "exhausted");
else {
if (this.current = e49, this.explored++, this.explored > this.maxSearchStates)
throw new Error(`PostProcessingSolver: coupled path search exceeded its ${this.maxSearchStates}-state graph invariant limit`);
if (this.isEnd(e49.point)) {
const t7 = this.createPath(e49);
return t7[t7.length - 1] = this.input.end, this.result = this.simplifyPath(t7), void (this.status = "found");
}
this.explored >= this.exploredStateLimit ? this.status = "exhausted" : (this.enqueuePlanarNeighbors(e49), this.enqueueViaNeighbors(e49), this.queue.length === 0 && (this.status = "exhausted"));
}
}
isEnd(e49) {
return e49.layer === this.input.end.layer && e49.x === this.input.end.x && e49.y === this.input.end.y;
}
estimate(e49) {
return Math.hypot(e49.x - this.input.end.x, e49.y - this.input.end.y) + 3 * Math.abs(C3(e49.layer, this.input.layerCount) - this.endLayer);
}
keyFor(e49, t6) {
return `${Object.is(e49.x, -0) ? 0 : e49.x}:${Object.is(e49.y, -0) ? 0 : e49.y}:${e49.layer}:${t6?.key ?? "start"}`;
}
createDirection(e49, t6) {
const n6 = t6.x - e49.x, o6 = t6.y - e49.y, i6 = Math.hypot(n6, o6);
if (i6 <= 0.0000000001)
throw new Error("PostProcessingSolver: composite grid produced a zero-length planar edge");
const r6 = n6 / i6, s6 = o6 / i6;
return { x: r6, y: s6, key: `${r6.toFixed(6)}:${s6.toFixed(6)}` };
}
createPath(e49) {
const t6 = [];
let n6 = e49;
for (;n6; )
t6.push(n6.point), n6 = n6.parent;
return t6.reverse();
}
simplifyPath(e49) {
return e49.filter((t6, n6) => {
if (n6 === 0 || n6 === e49.length - 1)
return true;
const o6 = e49[n6 - 1], i6 = e49[n6 + 1], r6 = { x: t6.x - o6.x, y: t6.y - o6.y }, s6 = { x: i6.x - t6.x, y: i6.y - t6.y }, a6 = r6.x * s6.y - r6.y * s6.x, c6 = Math.hypot(r6.x, r6.y) * Math.hypot(s6.x, s6.y);
return Math.abs(a6) > 0.0000000001 * c6 || t6.layer !== o6.layer || t6.layer !== i6.layer;
});
}
hasHigherQueuePriority(e49, t6) {
return e49.estimate !== t6.estimate ? e49.estimate < t6.estimate : e49.cost !== t6.cost ? e49.cost < t6.cost : e49.point.x !== t6.point.x ? e49.point.x < t6.point.x : e49.point.y !== t6.point.y ? e49.point.y < t6.point.y : e49.point.layer !== t6.point.layer ? e49.point.layer < t6.point.layer : e49.sequence < t6.sequence;
}
pushQueue(e49) {
this.queue.push(e49);
let t6 = this.queue.length - 1;
for (;t6 > 0; ) {
const n6 = Math.floor((t6 - 1) / 2), o6 = this.queue[n6];
if (!this.hasHigherQueuePriority(e49, o6))
break;
this.queue[t6] = o6, t6 = n6;
}
this.queue[t6] = e49;
}
popQueue() {
const e49 = this.queue[0], t6 = this.queue.pop();
if (!e49 || !t6 || this.queue.length === 0)
return e49;
let n6 = 0;
for (;; ) {
const e50 = 2 * n6 + 1;
if (e50 >= this.queue.length)
break;
const o6 = e50 + 1;
let i6 = e50;
o6 < this.queue.length && this.hasHigherQueuePriority(this.queue[o6], this.queue[e50]) && (i6 = o6);
const r6 = this.queue[i6];
if (!this.hasHigherQueuePriority(r6, t6))
break;
this.queue[n6] = r6, n6 = i6;
}
return this.queue[n6] = t6, e49;
}
enqueuePlanarNeighbors(e49) {
for (const t6 of this.grid.getPlanarNeighbors(e49.point)) {
if (!this.input.isEdgeValid(e49.point, t6))
continue;
const n6 = this.createDirection(e49.point, t6), o6 = e49.direction === null || e49.direction.key === n6.key ? 0 : 0.18, i6 = e49.cost + Math.hypot(t6.x - e49.point.x, t6.y - e49.point.y) + o6, r6 = this.keyFor(t6, n6);
(this.bestCosts.get(r6) ?? Number.POSITIVE_INFINITY) <= i6 || (this.bestCosts.set(r6, i6), this.pushQueue({ point: t6, direction: n6, cost: i6, estimate: i6 + this.estimate(t6), parent: e49, sequence: this.nextSequence++ }));
}
}
enqueueViaNeighbors(e49) {
if (!e49.direction)
return;
const t6 = C3(e49.point.layer, this.input.layerCount);
for (const n6 of [t6 - 1, t6 + 1]) {
if (n6 < 0 || n6 >= this.input.layerCount)
continue;
const t7 = P3(n6, this.input.layerCount);
if (!this.input.isViaValid(e49.point, t7, e49.direction))
continue;
const o6 = { ...e49.point, layer: t7 }, i6 = e49.cost + 4, r6 = this.keyFor(o6, e49.direction);
(this.bestCosts.get(r6) ?? Number.POSITIVE_INFINITY) <= i6 || (this.bestCosts.set(r6, i6), this.pushQueue({ point: o6, direction: e49.direction, cost: i6, estimate: i6 + this.estimate(o6), parent: e49, sequence: this.nextSequence++ }));
}
}
};
var f4 = (e49) => {
const t6 = Math.min(e49.bounds.maxX - e49.bounds.minX, e49.bounds.maxY - e49.bounds.minY), n6 = e49.config?.innerGridStep ?? e49.defaultInnerGridStep, o6 = e49.config?.outerGridStep ?? 4 * n6, i6 = e49.config?.outerPerimeterWidth ?? Math.min(o6, t6 / 4);
if (!Number.isFinite(n6) || n6 < 0.0001)
throw new Error("PostProcessingSolver: routingGrid.innerGridStep must be finite and at least 0.0001");
if (!Number.isFinite(o6) || o6 <= n6)
throw new Error("PostProcessingSolver: routingGrid.outerGridStep must be finite and greater than innerGridStep");
if (!Number.isFinite(i6) || i6 <= 0 || 2 * i6 >= t6)
throw new Error("PostProcessingSolver: routingGrid.outerPerimeterWidth must be finite, positive, and less than half the smaller board extent");
const r6 = e49.bounds.maxX - e49.bounds.minX, s6 = e49.bounds.maxY - e49.bounds.minY;
if ((Math.ceil(r6 / o6) + 4) * (Math.ceil(s6 / o6) + 4) + (Math.ceil((r6 - 2 * i6) / n6) + 2) * (Math.ceil((s6 - 2 * i6) / n6) + 2) + 18 > 250000)
throw new a4("PostProcessingSolver: valid input exceeds the 250000-node optimization grid capacity");
return { innerGridStep: n6, outerGridStep: o6, outerPerimeterWidth: i6 };
};
var _4 = (e49) => {
const t6 = -e49.pathDirection.y, n6 = e49.pathDirection.x, o6 = Math.tan(e49.maximumTurnDegrees * Math.PI / 180), i6 = Math.max(0, ...e49.lanes.map(({ point: i7, polarity: r7 }) => {
const s7 = i7.x - e49.anchor.x, a7 = i7.y - e49.anchor.y, c6 = s7 * e49.escapeDirection.x + a7 * e49.escapeDirection.y, l6 = s7 * t6 + a7 * n6, h6 = r7 * e49.side * e49.centerlineSpacing / 2;
return c6 + Math.abs(l6 - h6) / o6;
})), r6 = e49.maxUncoupledLength ?? i6;
if (i6 > r6 + 0.00000001)
return null;
const s6 = Math.max(0.05, Math.min(0.25, e49.searchStep / 2)), a6 = Math.max(1, Math.ceil((r6 - i6) / s6) + 1);
for (let o7 = 0;o7 < a6; o7++) {
const a7 = Math.min(r6, i6 + o7 * s6), c6 = { x: e49.anchor.x + e49.escapeDirection.x * a7, y: e49.anchor.y + e49.escapeDirection.y * a7, layer: e49.anchor.layer };
if (e49.lanes.every(({ point: o8, polarity: i7 }) => {
const r7 = i7 * e49.side * e49.centerlineSpacing / 2, s7 = c6.x + t6 * r7, a8 = c6.y + n6 * r7;
return e49.maxUncoupledLength === undefined || Math.hypot(s7 - o8.x, a8 - o8.y) <= e49.maxUncoupledLength + 0.00000001;
}) && e49.isValid(c6))
return c6;
}
return null;
};
var y4 = [0.75, 0.5, 1, 0.25, 1.25];
var b4 = 100;
var x4 = class {
constructor(e49) {
this.input = e49, this.pairName = e49.pair.connectionNames.join("/"), this.prepared = this.prepare();
}
input;
pairName;
prepared;
candidates = [];
result = null;
search = null;
nextAttempt = 0;
exploredNodeCount = 0;
isComplete() {
return this.result !== null;
}
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 e49 = this.prepared.attempts.length, t6 = this.search?.getProgress() ?? 0;
return Math.min(0.99, (this.nextAttempt + t6) / e49);
}
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 e49 = this.prepared;
if (!this.search) {
const t7 = e49.attempts[this.nextAttempt];
return t7 ? void (this.search = new g4(t7.input)) : void this.complete();
}
if (this.search.step(), !this.search.isComplete())
return;
const t6 = this.search.getPath();
this.exploredNodeCount += this.search.getExploredCount();
const n6 = e49.attempts[this.nextAttempt];
if (!n6)
throw new Error(`PostProcessingSolver: differential pair ${this.pairName} lost its active attempt`);
if (this.search = null, this.nextAttempt++, !t6)
return;
const o6 = ((e50) => {
const t7 = (e51, t8) => Math.hypot(e51.x - t8.x, e51.y - t8.y) <= 0.00000001;
if (e50.path.length < 2)
throw new Error("PostProcessingSolver: coupled path has fewer than two stations");
const n7 = (n8, o8) => {
for (let i7 = n8 + o8;i7 >= 0 && i7 < e50.path.length; i7 += o8) {
const o9 = e50.path[i7];
if (!t7(o9, e50.path[n8]))
return o9;
}
return null;
}, o7 = (t8) => {
const o8 = e50.path[t8], i7 = n7(t8, -1), r7 = n7(t8, 1), s7 = (e51, t9) => {
const n8 = t9.x - e51.x, o9 = t9.y - e51.y, i8 = Math.hypot(n8, o9);
if (i8 <= 0.0000000001)
throw new Error("PostProcessingSolver: cannot offset a zero-length spine");
return { x: -o9 / i8, y: n8 / i8 };
}, a7 = e50.side * e50.centerlineSpacing / 2;
if (!i7 || !r7) {
const e51 = s7(i7 ?? o8, r7 ?? o8);
return { x: e51.x * a7, y: e51.y * a7 };
}
if (e50.terminalFanout && t8 === 1)
return s7(i7, o8);
if (e50.terminalFanout && t8 === e50.path.length - 2)
return s7(o8, r7);
if (e50.terminalFanout && e50.path[t8 + 1]?.layer !== o8.layer)
return s7(i7, o8);
const c7 = s7(i7, o8), l7 = s7(o8, r7), h7 = { x: c7.x + l7.x, y: c7.y + l7.y }, d7 = Math.hypot(h7.x, h7.y);
if (d7 <= 0.0000000001)
return null;
const u7 = h7.x / d7, p7 = h7.y / d7, m7 = a7 / (u7 * c7.x + p7 * c7.y);
return { x: u7 * m7, y: p7 * m7 };
}, i6 = e50.first.points[0], r6 = e50.first.points.at(-1), s6 = e50.reverseSecond ? e50.second.points.at(-1) : e50.second.points[0], a6 = e50.reverseSecond ? e50.second.points[0] : e50.second.points.at(-1), c6 = [[{ route_type: "wire", x: i6.x, y: i6.y, width: i6.width, layer: i6.layer }], [{ route_type: "wire", x: s6.x, y: s6.y, width: s6.width, layer: s6.layer }]], l6 = [e50.first.transitions[0], e50.second.transitions[0]];
let h6 = 0;
const d6 = e50.terminalFanout ? 1 : 0, u6 = e50.path.length - 2, p6 = e50.path[u6], m6 = e50.path[u6 - 1], g6 = e50.terminalFanout && p6?.layer === r6.layer && m6?.layer === p6.layer, f6 = e50.terminalFanout ? g6 ? u6 - 1 : e50.path.length - 1 : e50.path.length;
for (let n8 = d6;n8 < f6; n8++) {
const i7 = e50.path[n8], r7 = o7(n8);
if (!r7)
return null;
for (const o8 of [0, 1]) {
const s7 = o8 === 0 ? 1 : -1, a7 = { x: i7.x + r7.x * s7, y: i7.y + r7.y * s7 }, h7 = c6[o8], d7 = e50.path[n8 - 1];
if (d7 && d7.layer !== i7.layer) {
if (!t7(d7, i7))
throw new Error("PostProcessingSolver: a coupled layer transition moved in the plane");
const n9 = [...h7].reverse().find((e51) => e51.route_type === "wire");
if (!n9)
throw new Error("PostProcessingSolver: generated via has no preceding wire");
const r8 = l6[o8];
h7.push({ route_type: "via", x: n9.x, y: n9.y, from_layer: d7.layer, to_layer: i7.layer, via_diameter: r8?.via_diameter ?? (o8 === 0 ? e50.first.viaDiameter : e50.second.viaDiameter), ...r8?.via_hole_diameter !== undefined ? { via_hole_diameter: r8.via_hole_diameter } : {} }), h7.push({ route_type: "wire", x: n9.x, y: n9.y, width: o8 === 0 ? e50.first.width : e50.second.width, layer: i7.layer });
} else {
const n9 = h7.at(-1);
n9?.route_type === "wire" && t7(n9, a7) && n9.layer === i7.layer || h7.push({ route_type: "wire", ...a7, width: o8 === 0 ? e50.first.width : e50.second.width, layer: i7.layer });
}
}
e50.path[n8 - 1]?.layer !== i7.layer && n8 > 0 && h6++;
}
const _6 = (t8, n8) => {
const o8 = t8.at(-1);
if (!o8 || o8.route_type !== "wire")
throw new Error("PostProcessingSolver: terminal fanout has no preceding wire");
const i7 = t8.at(-2);
let r7 = false;
if (i7?.route_type === "wire" && i7.layer === o8.layer && o8.layer === n8.layer) {
const e51 = { x: o8.x - i7.x, y: o8.y - i7.y }, t9 = { x: n8.x - o8.x, y: n8.y - o8.y }, s7 = Math.hypot(e51.x, e51.y), a7 = Math.hypot(t9.x, t9.y);
if (s7 > 0.00000001 && a7 > 0.00000001 && Math.abs(e51.x * t9.x + e51.y * t9.y) <= 0.00000001) {
const t10 = { x: o8.x - e51.x / s7 * a7, y: o8.y - e51.y / s7 * a7 };
(t10.x - i7.x) * (e51.x / s7) + (t10.y - i7.y) * (e51.y / s7) > 0.00000001 && (o8.x = t10.x, o8.y = t10.y, r7 = true);
}
}
e50.terminalFanout && !r7 && o8.x !== n8.x && o8.y !== n8.y && t8.push({ route_type: "wire", x: n8.x, y: o8.y, width: n8.width, layer: n8.layer }), t8.push({ route_type: "wire", x: n8.x, y: n8.y, width: n8.width, layer: n8.layer });
};
_6(c6[0], r6), _6(c6[1], a6), e50.reverseSecond && (c6[1] = c6[1].reverse().map((e51) => e51.route_type === "via" ? { ...e51, from_layer: e51.to_layer, to_layer: e51.from_layer } : e51));
const y6 = (e51, t8) => {
const n8 = e51.filter((e53) => e53.route_type === "wire");
for (const e53 of n8)
delete e53.start_pcb_port_id, delete e53.end_pcb_port_id;
t8.startPortId && (n8[0].start_pcb_port_id = t8.startPortId), t8.endPortId && (n8.at(-1).end_pcb_port_id = t8.endPortId);
};
y6(c6[0], e50.first), y6(c6[1], e50.second);
const b6 = { ...e50.first.source, route: c6[0] }, x6 = { ...e50.second.source, route: c6[1] };
return { first: b6, second: x6, firstParsed: e48(b6, e50.layerCount), secondParsed: e48(x6, e50.layerCount), edgeGap: e50.edgeGap, centerlineDistance: e50.centerlineSpacing, bendCount: Math.max(0, e50.path.length - h6 - 2), viaPairCount: h6 };
})({ first: e49.first, second: e49.second, reverseSecond: e49.reverseSecond, path: t6, centerlineSpacing: n6.edgeGap + e49.first.width / 2 + e49.second.width / 2, edgeGap: n6.edgeGap, side: n6.side, layerCount: this.input.layerCount, terminalFanout: e49.terminalFanout });
o6 && u4(o6.firstParsed, o6.secondParsed, e49.context) && this.candidates.push(o6);
}
prepare() {
const e49 = this.input.traces.map((e50, t7) => ({ trace: e50, index: t7 })).filter(({ trace: e50 }) => e50.connection_name === this.input.pair.connectionNames[0]), t6 = this.input.traces.map((e50, t7) => ({ trace: e50, index: t7 })).filter(({ trace: e50 }) => e50.connection_name === this.input.pair.connectionNames[1]);
if (e49.length !== 1 || t6.length !== 1)
throw new r4({ connectionNames: this.input.pair.connectionNames, reason: "trace-resolution-failure", message: "must resolve each connection_name to exactly one non-branching trace" });
if (e49[0].index === t6[0].index)
throw new r4({ connectionNames: this.input.pair.connectionNames, reason: "trace-resolution-failure", message: "resolved both members to one trace" });
let n6, o6;
try {
n6 = e48(e49[0].trace, this.input.layerCount), o6 = e48(t6[0].trace, this.input.layerCount);
} catch (e50) {
throw new r4({ connectionNames: this.input.pair.connectionNames, reason: "invalid-routed-geometry", message: `has unsupported or invalid routed geometry: ${e50 instanceof Error ? e50.message : String(e50)}` });
}
const i6 = n6.points[0], r6 = n6.points.at(-1), s6 = Math.hypot(i6.x - o6.points[0].x, i6.y - o6.points[0].y) + Math.hypot(r6.x - o6.points.at(-1).x, r6.y - o6.points.at(-1).y), a6 = Math.hypot(i6.x - o6.points.at(-1).x, i6.y - o6.points.at(-1).y) + Math.hypot(r6.x - o6.points[0].x, r6.y - o6.points[0].y) + 0.00000001 < s6, c6 = a6 ? o6.points.at(-1) : o6.points[0], l6 = a6 ? o6.points[0] : o6.points.at(-1);
if (i6.layer !== c6.layer || r6.layer !== l6.layer)
throw new r4({ connectionNames: this.input.pair.connectionNames, reason: "terminal-layer-mismatch", message: "does not have common paired layers at both terminal stations" });
const h6 = { x: (i6.x + c6.x) / 2, y: (i6.y + c6.y) / 2, layer: i6.layer }, d6 = { x: (r6.x + l6.x) / 2, y: (r6.y + l6.y) / 2, layer: r6.layer }, u6 = Math.hypot(d6.x - h6.x, d6.y - h6.y);
if (u6 < 0.000001)
throw new r4({ connectionNames: this.input.pair.connectionNames, reason: "coincident-terminal-midpoints", message: "has coincident terminal-pair midpoints" });
const p6 = { x: -(d6.y - h6.y) / u6, y: (d6.x - h6.x) / u6 }, m6 = i6.x - c6.x, g6 = i6.y - c6.y, f6 = m6 * p6.x + g6 * p6.y >= 0 ? 1 : -1, _6 = (e50, t7) => {
const n7 = e50.x - t7.x, o7 = e50.y - t7.y, i7 = Math.hypot(n7, o7);
return i7 > 0.00000001 && Math.abs(n7 * p6.x + o7 * p6.y) / i7 < 0.5;
}, y6 = _6(i6, c6) && _6(r6, l6), b6 = { x: p6.y, y: -p6.x }, x6 = [i6, c6].some((e50) => (e50.x - h6.x) * b6.x + (e50.y - h6.y) * b6.y > 0.00000001), v4 = { immutableTraces: this.input.traces.filter((n7, o7) => o7 !== e49[0].index && o7 !== t6[0].index), obstacles: this.input.obstacles, bounds: this.input.bounds, layerCount: this.input.layerCount, minTraceToPadEdgeClearance: this.input.minTraceToPadEdgeClearance }, I4 = ((e50) => {
const { minimumCenterlineDistance: t7, maximumCenterlineDistance: n7 } = e50;
if (t7 === undefined && n7 === undefined)
return e50.legacyCenterlineDistances;
const o7 = [...t7 !== undefined && n7 !== undefined ? [(t7 + n7) / 2, t7, n7, t7 - 0.25, n7 + 0.25] : t7 !== undefined ? [t7, t7 + 0.25, t7 + 0.5, t7 - 0.25, t7 + 1] : [n7, n7 - 0.25, n7 - 0.5, n7 + 0.25, n7 - 1], ...e50.legacyCenterlineDistances];
return o7.filter((t8, n8) => t8 > e50.minimumPhysicalDistance && o7.findIndex((e51) => Math.abs(e51 - t8) < 0.00000001) === n8);
})({ minimumCenterlineDistance: this.input.pair.minimumCenterlineDistance, maximumCenterlineDistance: this.input.pair.maximumCenterlineDistance, minimumPhysicalDistance: n6.width / 2 + o6.width / 2, legacyCenterlineDistances: y4.map((e50) => e50 + n6.width / 2 + o6.width / 2) }).flatMap((e50) => {
const t7 = e50 - n6.width / 2 - o6.width / 2;
return [f6, f6 === 1 ? -1 : 1].flatMap((s7) => {
const a7 = f4({ config: this.input.routingGrid, bounds: this.input.bounds, defaultInnerGridStep: Math.max(0.25, Math.min(0.5, e50 / 2)) }), u7 = (t8, a8) => d4({ ...v4, start: t8, end: a8, firstConnectionName: n6.source.connection_name, secondConnectionName: o6.source.connection_name, firstStartTerminal: i6, firstEndTerminal: r6, secondStartTerminal: c6, secondEndTerminal: l6, firstWidth: n6.width, secondWidth: o6.width, firstViaDiameter: n6.transitions[0]?.via_diameter ?? n6.viaDiameter, secondViaDiameter: o6.transitions[0]?.via_diameter ?? o6.viaDiameter, centerlineSpacing: e50, side: s7, terminalFanout: y6, terminalMiterMargin: this.input.pair.maxUncoupledLength === undefined ? undefined : e50 / 2 });
let m7 = this.input.pair.maxUncoupledLength === undefined ? ((e51, t8) => {
if (!x6 || y6)
return h6;
const n7 = [{ terminal: i6, offset: t8 * e51 / 2 }, { terminal: c6, offset: -t8 * e51 / 2 }], o7 = Math.tan(55 * Math.PI / 180), r7 = Math.max(...n7.map(({ terminal: e53, offset: t9 }) => {
const n8 = (e53.x - h6.x) * b6.x + (e53.y - h6.y) * b6.y, i7 = (e53.x - h6.x) * p6.x + (e53.y - h6.y) * p6.y;
return n8 + Math.abs(i7 - t9) / o7;
}));
return { x: h6.x + b6.x * r7, y: h6.y + b6.y * r7, layer: h6.layer };
})(e50, s7) : h6, g7 = d6;
if (!y6 && this.input.pair.maxUncoupledLength !== undefined) {
const t8 = u7(h6, d6), n7 = _4({ anchor: h6, escapeDirection: b6, pathDirection: b6, centerlineSpacing: e50, side: s7, lanes: [{ point: i6, polarity: 1 }, { point: c6, polarity: -1 }], maxUncoupledLength: this.input.pair.maxUncoupledLength, maximumTurnDegrees: 55, searchStep: a7.innerGridStep, isValid: (e51) => t8.isTerminalFanoutValid(e51, b6, "start") }), o7 = _4({ anchor: d6, escapeDirection: { x: -b6.x, y: -b6.y }, pathDirection: b6, centerlineSpacing: e50, side: s7, lanes: [{ point: r6, polarity: 1 }, { point: l6, polarity: -1 }], maxUncoupledLength: this.input.pair.maxUncoupledLength, maximumTurnDegrees: 45, searchStep: a7.innerGridStep, isValid: (e51) => t8.isTerminalFanoutValid(e51, b6, "end") });
if (!n7 || !o7)
return [];
m7 = n7, g7 = o7;
if ((g7.x - m7.x) * b6.x + (g7.y - m7.y) * b6.y <= a7.innerGridStep)
return [];
}
const f7 = u7(m7, g7);
return [{ edgeGap: t7, side: s7, input: { start: m7, end: g7, bounds: this.input.bounds, layerCount: this.input.layerCount, grid: a7, ...f7 } }];
});
});
return { first: n6, second: o6, reverseSecond: a6, terminalFanout: y6, context: v4, attempts: I4 };
}
complete() {
if (this.candidates.length === 0)
throw new r4({ 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((e49, t6) => this.score(e49) - this.score(t6) || e49.edgeGap - t6.edgeGap), this.result = { status: "accepted", candidate: this.candidates[0] };
}
score(e49) {
return (this.input.pair.minimumCenterlineDistance !== undefined || this.input.pair.maximumCenterlineDistance !== undefined ? Math.max(0, (this.input.pair.minimumCenterlineDistance ?? Number.NEGATIVE_INFINITY) - e49.centerlineDistance) * b4 + Math.max(0, e49.centerlineDistance - (this.input.pair.maximumCenterlineDistance ?? Number.POSITIVE_INFINITY)) * b4 : e49.edgeGap < 0.5 ? (0.5 - e49.edgeGap) * b4 : e49.edgeGap > 1 ? (e49.edgeGap - 1) * b4 : 0) + t4(e49.firstParsed) + t4(e49.secondParsed) + 0.15 * e49.bendCount + 8 * e49.viaPairCount;
}
};
var v4 = (e49) => {
const t6 = { lines: [], points: [], rects: [], circles: [] };
t6.rects.push({ center: { x: (e49.bounds.minX + e49.bounds.maxX) / 2, y: (e49.bounds.minY + e49.bounds.maxY) / 2 }, width: e49.bounds.maxX - e49.bounds.minX, height: e49.bounds.maxY - e49.bounds.minY, fill: "rgba(30, 70, 120, 0.04)", stroke: "rgba(30, 70, 120, 0.55)", layer: `z${Array.from({ length: e49.layerCount }, (e50, t7) => t7).join(",")}` });
for (const n6 of e49.obstacles) {
const o6 = k3(n6, e49.layerCount);
t6.rects.push({ center: n6.center, width: n6.width, height: n6.height, ccwRotationDegrees: n6.ccwRotationDegrees, fill: "rgba(220, 60, 60, 0.16)", stroke: "rgba(190, 40, 40, 0.75)", layer: `z${o6.join(",")}` });
}
for (let n6 = 0;n6 < (e49.previewPath?.length ?? 0) - 1; n6++) {
const o6 = e49.previewPath[n6], i6 = e49.previewPath[n6 + 1];
if (o6.layer !== i6.layer)
continue;
const r6 = C3(o6.layer, e49.layerCount);
t6.lines.push({ points: [o6, i6], strokeColor: "#16a34a", strokeWidth: 0.08, strokeDash: [0.18, 0.12], layer: `z${r6}` });
}
for (const n6 of e49.traces) {
if (e49.activeConnectionNames?.includes(n6.connection_name))
continue;
const o6 = "#2563eb";
let i6 = null;
for (const r6 of n6.route)
if (r6.route_type === "wire") {
if (i6 && i6.layer === r6.layer) {
const n7 = C3(r6.layer, e49.layerCount);
t6.lines.push({ points: [i6, r6], strokeColor: o6, strokeWidth: Math.max(i6.width, r6.width), ...n7 === 0 ? {} : { strokeDash: [0.2, 0.16] }, layer: `z${n7}` });
}
i6 = r6;
} else if (r6.route_type === "via") {
const n7 = M3(r6.from_layer, r6.to_layer, e49.layerCount).map((t7) => C3(t7, e49.layerCount));
if (t6.circles.push({ center: r6, radius: (r6.via_diameter ?? i6?.width ?? 0.2) / 2, fill: "rgba(37, 99, 235, 0.45)", stroke: o6, layer: `z${n7.join(",")}` }), i6) {
const e50 = i6.width;
i6 = { x: r6.x, y: r6.y, layer: r6.to_layer, width: e50 };
}
}
}
return t6;
};
var I4 = class extends De {
constructor(e49) {
super(), this.params = e49, this.outputTraces = l4(e49.simpleRouteJson.traces), this.MAX_ITERATIONS = c4(e49);
}
params;
outputTraces;
reroutedPairs = [];
failures = [];
nextPairIndex = 0;
activeConnectionNames = null;
activeSession = null;
getSolverName() {
return "DifferentialPairReroutingSolver";
}
_step() {
const e49 = this.params.simpleRouteJson.differentialPairs[this.nextPairIndex];
if (!e49)
return void this.finish();
this.activeConnectionNames = e49.connectionNames;
try {
if (!this.activeSession)
return this.activeSession = new x4({ pair: e49, 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 (t7) {
if (!(t7 instanceof r4))
throw t7;
return void this.skipFailedPair(e49, t7);
}
if (this.stats = this.activeSession.getStats(), !this.activeSession.isComplete())
return;
const t6 = this.activeSession.getResult();
this.activeSession = null;
for (const e50 of [t6.candidate.first, t6.candidate.second]) {
const t7 = this.outputTraces.findIndex((t8) => t8.connection_name === e50.connection_name);
if (t7 < 0)
throw new Error(`DifferentialPairReroutingSolver: accepted replacement for unknown connection "${e50.connection_name}"`);
this.outputTraces[t7] = e50;
}
this.reroutedPairs.push(e49), this.nextPairIndex++, this.nextPairIndex !== this.params.simpleRouteJson.differentialPairs.length ? this.stats = { phase: "accepted", pair: e49.connectionNames.join("/"), pairIndex: this.nextPairIndex - 1, pairCount: this.params.simpleRouteJson.differentialPairs.length } : this.finish();
}
finish() {
this.activeConnectionNames = null, this.solved = true, this.stats = { phase: "complete", acceptedPairCount: this.reroutedPairs.length, skippedPairCount: this.failures.length };
}
skipFailedPair(e49, t6) {
this.failures.push({ connectionNames: [...e49.connectionNames], reason: t6.reason, message: t6.message }), this.activeSession = null, this.nextPairIndex++, this.nextPairIndex !== this.params.simpleRouteJson.differentialPairs.length ? this.stats = { phase: "skipped", pair: e49.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: l4(this.outputTraces), reroutedPairs: this.reroutedPairs.map((e49) => ({ ...e49, connectionNames: [...e49.connectionNames] })), failures: this.failures.map((e49) => ({ ...e49, connectionNames: [...e49.connectionNames] })) };
}
computeProgress() {
return this.solved ? 1 : this.params.simpleRouteJson.differentialPairs.length === 0 ? 0 : (this.nextPairIndex + (this.activeSession?.getProgress() ?? 0)) / this.params.simpleRouteJson.differentialPairs.length;
}
visualize() {
return v4({ 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 });
}
};
var S4 = 0.00000001;
var C4 = class extends De {
constructor(e49) {
super(), this.input = e49, this.traces = l4(e49.traces), this.MAX_ITERATIONS = Math.max(1, e49.reroutedPairs.length + 1);
}
input;
traces;
nextPairIndex = 0;
getSolverName() {
return "FortyFiveDegreeSimplificationSolver";
}
_step() {
const e49 = this.input.reroutedPairs[this.nextPairIndex];
if (!e49)
return this.solved = true, void (this.stats = { phase: "complete", simplifiedPairCount: this.nextPairIndex });
this.traces = ((e50) => {
const t6 = e50.pair.connectionNames.join("/"), n6 = e50.pair.connectionNames.map((t7) => e50.traces.map((e51, t8) => ({ trace: e51, index: t8 })).filter(({ trace: e51 }) => e51.connection_name === t7));
if (n6[0].length !== 1 || n6[1].length !== 1)
throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${t6} must resolve to exactly two traces`);
const o6 = n6[0][0].index, i6 = n6[1][0].index;
if (o6 === i6)
throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${t6} resolved both members to one trace`);
const r6 = structuredClone(e50.traces), s6 = { immutableTraces: r6.filter((e51, t7) => t7 !== o6 && t7 !== i6), obstacles: e50.obstacles, bounds: e50.bounds, layerCount: e50.layerCount, minTraceToPadEdgeClearance: e50.minTraceToPadEdgeClearance }, a6 = (n7) => {
const r7 = e48(n7[o6], e50.layerCount), s7 = e48(n7[i6], e50.layerCount);
let a7 = 0;
for (const [e51, n8] of [[r7.segments, s7.segments], [s7.segments, r7.segments]])
for (const o7 of e51) {
if (o7.terminal !== null)
continue;
const e53 = n8.filter((e54) => e54.layer === o7.layer);
if (e53.length === 0)
throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${t6} lost common-layer interior copper`);
a7 = Math.max(a7, Math.min(...e53.map((e54) => R3(o7.start, o7.end, e54.start, e54.end))));
}
return a7;
}, c6 = (t7) => {
const n7 = e48(t7[o6], e50.layerCount), r7 = e48(t7[i6], e50.layerCount);
let s7 = Number.POSITIVE_INFINITY;
for (const [e51, t8] of [[n7.segments, r7.segments], [r7.segments, n7.segments]])
for (const n8 of e51)
if (n8.terminal === null)
for (const e53 of t8)
e53.layer === n8.layer && (s7 = Math.min(s7, R3(n8.start, n8.end, e53.start, e53.end) - n8.width / 2 - e53.width / 2));
return Number.isFinite(s7) ? s7 : null;
}, l6 = (t7) => {
const n7 = e48(t7[o6], e50.layerCount), r7 = e48(t7[i6], e50.layerCount);
return u4(n7, r7, s6);
};
if (!l6(r6))
throw new Error(`FortyFiveDegreeSimplificationSolver: rerouted pair ${t6} has invalid complete copper before simplification`);
if (e50.pair.maxUncoupledLength !== undefined && e50.pair.minimumCenterlineDistance !== undefined && e50.pair.maximumCenterlineDistance !== undefined && Math.abs(e50.pair.minimumCenterlineDistance - e50.pair.maximumCenterlineDistance) <= S4)
return r6;
const h6 = e48(r6[o6], e50.layerCount), d6 = e48(r6[i6], e50.layerCount), u6 = Math.abs(t4(h6) - t4(d6)), p6 = c6(r6), m6 = e50.pair.maximumCenterlineDistance ?? 1 + h6.width / 2 + d6.width / 2, g6 = Math.min(a6(r6), m6), f6 = (e51) => {
if (!l6(e51))
return false;
if (a6(e51) > g6 + S4)
return false;
const t7 = c6(e51);
return p6 === null || t7 === null || t7 >= p6 - S4;
}, _6 = (e51, t7) => {
const n7 = Math.abs(t7.x - e51.x), o7 = Math.abs(t7.y - e51.y), i7 = t7.x >= e51.x ? 1 : -1, r7 = t7.y >= e51.y ? 1 : -1, s7 = [], a7 = { x: t7.x - i7 * o7, y: e51.y };
(a7.x - e51.x) * i7 >= -1e-8 && (a7.x - t7.x) * i7 <= S4 && s7.push([e51, a7, t7]);
const c7 = { x: e51.x, y: t7.y - r7 * n7 };
(c7.y - e51.y) * r7 >= -1e-8 && (c7.y - t7.y) * r7 <= S4 && s7.push([e51, c7, t7]);
const l7 = { x: e51.x + i7 * Math.min(n7, o7), y: e51.y + r7 * Math.min(n7, o7) };
return s7.push([e51, l7, t7]), s7.map((e53, t8) => {
const n8 = e53.filter((t9, n9) => n9 === 0 || Math.hypot(t9.x - e53[n9 - 1].x, t9.y - e53[n9 - 1].y) > S4), o8 = n8.slice(0, -1).map((e54, t9) => {
const o9 = n8[t9 + 1], i8 = Math.abs(o9.x - e54.x), r8 = Math.abs(o9.y - e54.y);
return { length: Math.hypot(i8, r8), straight: i8 <= S4 || r8 <= S4 ? Math.hypot(i8, r8) : 0 };
});
return { points: n8, usableStraightLength: Math.max(0, ...o8.map((e54) => e54.straight)), bendCount: Math.max(0, n8.length - 2), priority: t8 };
}).filter((e53, t8, n8) => n8.findIndex((t9) => JSON.stringify(t9.points) === JSON.stringify(e53.points)) === t8).sort((e53, t8) => t8.usableStraightLength - e53.usableStraightLength || e53.bendCount - t8.bendCount || e53.priority - t8.priority);
}, y6 = (e51) => {
const t7 = [];
for (let n7 = 0;n7 < e51.route.length - 1; n7++) {
const o7 = e51.route[n7];
if (o7?.route_type === "wire")
for (let i7 = e51.route.length - 1;i7 >= n7 + 1; i7--) {
if (n7 === 0 || i7 === e51.route.length - 1)
continue;
const r7 = e51.route[i7];
r7?.route_type === "wire" && r7.layer === o7.layer && (e51.route.slice(n7 + 1, i7).some((e53) => e53.route_type !== "wire" || e53.layer !== o7.layer) || t7.push({ startIndex: n7, endIndex: i7, skippedPointCount: i7 - n7 - 1 }));
}
}
return t7.sort((e53, t8) => t8.skippedPointCount - e53.skippedPointCount || e53.startIndex - t8.startIndex || t8.endIndex - e53.endIndex);
}, b6 = (e51, t7, n7) => {
const o7 = e51.route[t7.startIndex], i7 = e51.route[t7.endIndex], r7 = Math.max(o7.width, i7.width), s7 = n7.points.slice(1, -1).map((e53) => ({ route_type: "wire", ...e53, width: r7, layer: o7.layer }));
return { ...e51, route: [...e51.route.slice(0, t7.startIndex + 1), ...s7, ...e51.route.slice(t7.endIndex)] };
};
for (const e51 of [o6, i6]) {
let t7 = true;
for (;t7; ) {
t7 = false;
const n7 = r6[e51];
for (const s7 of y6(n7)) {
const a7 = n7.route[s7.startIndex], c7 = n7.route[s7.endIndex], l7 = n7.route.slice(s7.startIndex, s7.endIndex + 1), h7 = l7.slice(0, -1).every((e53, t8) => {
const n8 = l7[t8 + 1], o7 = Math.abs(n8.x - e53.x), i7 = Math.abs(n8.y - e53.y);
return o7 <= S4 || i7 <= S4 || Math.abs(o7 - i7) <= S4;
});
for (const d7 of _6(a7, c7)) {
if (d7.points.length >= l7.length && h7)
continue;
const a8 = b6(n7, s7, d7), c8 = [...r6];
if (c8[e51] = a8, JSON.stringify(a8.route) === JSON.stringify(n7.route))
continue;
if (f6(c8)) {
r6[e51] = a8, t7 = true;
break;
}
const u7 = e51 === o6 ? i6 : o6, p7 = r6[u7], m7 = y6(p7).find((e53) => e53.startIndex === s7.startIndex && e53.endIndex === s7.endIndex);
if (!m7)
continue;
const g7 = p7.route[m7.startIndex], x7 = p7.route[m7.endIndex];
for (const n8 of _6(g7, x7)) {
const o7 = b6(p7, m7, n8), i7 = [...c8];
if (i7[u7] = o7, f6(i7)) {
r6[e51] = a8, r6[u7] = o7, t7 = true;
break;
}
}
if (t7)
break;
}
if (t7)
break;
}
}
}
if (!f6(r6))
throw new Error(`FortyFiveDegreeSimplificationSolver: pair ${t6} produced invalid complete copper`);
const x6 = e48(r6[o6], e50.layerCount), v6 = e48(r6[i6], e50.layerCount), I6 = Math.abs(t4(x6) - t4(v6));
return Math.abs(I6 - u6) > e50.pair.lengthTolerance + S4 ? structuredClone(e50.traces) : r6;
})({ traces: this.traces, pair: e49, obstacles: this.input.obstacles, bounds: this.input.bounds, layerCount: this.input.layerCount, minTraceToPadEdgeClearance: this.input.minTraceToPadEdgeClearance }), this.nextPairIndex++, this.stats = { phase: "simplifying", pair: e49.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: l4(this.traces), reroutedPairs: this.input.reroutedPairs.map((e49) => ({ ...e49, connectionNames: [...e49.connectionNames] })) };
}
computeProgress() {
return this.solved ? 1 : this.input.reroutedPairs.length === 0 ? 0 : this.nextPairIndex / this.input.reroutedPairs.length;
}
visualize() {
return v4({ 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 });
}
};
var P4 = (e49, t6) => Math.abs(e49 - t6) <= 0.0000001;
var M4 = (e49, t6) => P4(e49.x, t6.x) && P4(e49.y, t6.y);
var w4 = (e49) => {
const t6 = e49.candidatePair.map((t7, n6) => {
const o6 = e49.originalPair[n6];
return { ...t7, segments: t7.segments.filter((e50) => !o6.segments.some((t8) => {
return o7 = e50, (n7 = t8).layer === o7.layer && !!P4(n7.width, o7.width) && !!M4(n7.start, o7.start) && !!M4(n7.end, o7.end);
var n7, o7;
})), vias: t7.vias.filter((e50) => !o6.vias.some((t8) => {
return !!M4(n7 = t8, o7 = e50) && !!P4(n7.diameter, o7.diameter) && n7.layers.length === o7.layers.length && !!n7.layers.every((e51) => o7.layers.includes(e51));
var n7, o7;
})) };
});
return [t6[0], t6[1]];
};
var N4 = class extends De {
constructor(e49) {
super(), this.input = e49;
}
input;
output = null;
visualizationTraces = null;
getSolverName() {
return "HdRouteReconstructionSolver";
}
_step() {
this.visualizationTraces = ((e49) => {
const { simpleRouteJson: t6 } = e49.params;
if (e49.result.matchedHdRoutes.length !== e49.binding.solverParams.hdRoutes.length)
throw new Error("PostProcessingSolver: LengthMatchingSolver changed the search route count");
const n6 = structuredClone(e49.binding.baseTraces);
for (const o6 of e49.binding.traceBindings) {
const i6 = e49.result.matchedHdRoutes[o6.matchedRouteIndex];
if (!i6)
throw new Error(`PostProcessingSolver: missing matched route at index ${o6.matchedRouteIndex}`);
const r6 = n6[o6.traceIndex];
if (!r6)
throw new Error(`PostProcessingSolver: missing simplified trace binding at index ${o6.traceIndex}`);
if (r6.connection_name !== i6.connectionName)
throw new Error(`PostProcessingSolver: route binding changed connection "${r6.connection_name}" to "${i6.connectionName}"`);
if (i6.route.length < 2)
throw new Error(`PostProcessingSolver: matched connection "${i6.connectionName}" has incomplete geometry`);
const s6 = i6.route[0], a6 = i6.route.at(-1);
if (Math.hypot(s6.x - o6.startEndpoint.x, s6.y - o6.startEndpoint.y) > 0.00000001 || s6.z !== o6.startEndpoint.z || Math.hypot(a6.x - o6.endEndpoint.x, a6.y - o6.endEndpoint.y) > 0.00000001 || a6.z !== o6.endEndpoint.z)
throw new Error(`PostProcessingSolver: matched connection "${i6.connectionName}" moved a preserved endpoint`);
const c6 = [];
let l6 = 0;
const h6 = (e50) => ({ route_type: "wire", x: e50.x, y: e50.y, width: e50.traceThickness ?? i6.traceThickness, layer: P3(e50.z, t6.layerCount) });
c6.push(h6(i6.route[0]));
for (let e50 = 1;e50 < i6.route.length; e50++) {
const n7 = i6.route[e50 - 1], r7 = i6.route[e50];
if (n7.z === r7.z) {
c6.push(h6(r7));
continue;
}
if (Math.hypot(n7.x - r7.x, n7.y - r7.y) > 0.00000001)
throw new Error(`PostProcessingSolver: matched connection "${i6.connectionName}" moves while changing layers`);
const s7 = o6.viaTemplates[l6++];
if (!s7)
throw new Error(`PostProcessingSolver: matched connection "${i6.connectionName}" added an unbound via`);
if (Math.hypot(s7.x - r7.x, s7.y - r7.y) > 0.00000001)
throw new Error(`PostProcessingSolver: matched connection "${i6.connectionName}" moved a preserved via`);
const a7 = P3(n7.z, t6.layerCount), d7 = P3(r7.z, t6.layerCount), u6 = new Set([s7.from_layer, s7.to_layer]);
if (!u6.has(a7) || !u6.has(d7))
throw new Error(`PostProcessingSolver: matched connection "${i6.connectionName}" changed a preserved via span`);
c6.push({ ...s7 }), c6.push(h6(r7));
}
if (l6 !== o6.viaTemplates.length)
throw new Error(`PostProcessingSolver: matched connection "${i6.connectionName}" removed a preserved via`);
const d6 = c6.filter((e50) => e50.route_type === "wire");
for (const e50 of d6)
delete e50.start_pcb_port_id, delete e50.end_pcb_port_id;
o6.startPortId && (d6[0].start_pcb_port_id = o6.startPortId), o6.endPortId && (d6.at(-1).end_pcb_port_id = o6.endPortId), n6[o6.traceIndex] = { ...r6, route: c6 };
}
for (const o6 of e49.binding.solverParams.differentialPairs) {
const i6 = o6.connectionNames.join("/"), r6 = o6.connectionNames.map((e50) => n6.map((e51, t7) => ({ trace: e51, index: t7 })).filter(({ trace: t7 }) => t7.connection_name === e50));
if (r6[0].length !== 1 || r6[1].length !== 1)
throw new Error(`PostProcessingSolver: reconstructed pair ${i6} does not resolve to complete copper`);
const s6 = r6[0][0], a6 = r6[1][0], c6 = o6.connectionNames.map((t7) => {
const n7 = e49.binding.baseTraces.filter((e50) => e50.connection_name === t7);
if (n7.length !== 1)
throw new Error(`PostProcessingSolver: original pair ${i6} does not resolve to complete copper`);
return n7[0];
}), l6 = e48(s6.trace, t6.layerCount), h6 = e48(a6.trace, t6.layerCount), d6 = e48(c6[0], t6.layerCount), u6 = e48(c6[1], t6.layerCount), p6 = Math.abs(t4(l6) - t4(h6));
if (p6 > o6.lengthTolerance + 0.0000001)
throw new s4({ message: `PostProcessingSolver: reconstructed pair ${i6} exceeds length tolerance ${o6.lengthTolerance} with error ${p6}`, connectionNames: [...o6.connectionNames], reason: "length-tolerance-unsatisfied" });
const m6 = { immutableTraces: n6.filter((e50, t7) => t7 !== s6.index && t7 !== a6.index), obstacles: t6.obstacles, bounds: t6.bounds, layerCount: t6.layerCount, minTraceToPadEdgeClearance: t6.minTraceToPadEdgeClearance }, g6 = u4(l6, h6, { ...m6, obstacles: [] }), f6 = w4({ candidatePair: [l6, h6], originalPair: [d6, u6] }), _6 = u4(f6[0], f6[1], { ...m6, immutableTraces: [] });
if (!g6 || !_6)
throw new s4({ message: `PostProcessingSolver: length matching produced invalid complete copper for pair ${i6}`, connectionNames: [...o6.connectionNames], reason: "invalid-final-copper" });
}
return n6;
})(this.input), this.output = i4({ ...this.input, rejectInsideJumperPad: true }), this.stats = { phase: "complete", routeCount: this.output.hdRoutes.length }, this.solved = true;
}
getConstructorParams() {
return [this.input];
}
getOutput() {
if (!this.output || !this.solved)
throw new Error("HdRouteReconstructionSolver: getOutput() called before completion");
return structuredClone(this.output);
}
visualize() {
const e49 = this.visualizationTraces ?? this.input.simplified.traces, { obstacles: t6, bounds: n6, layerCount: o6 } = this.input.params.simpleRouteJson;
return v4({ traces: e49, obstacles: t6, bounds: n6, layerCount: o6, activeConnectionNames: null, previewPath: null });
}
};
var T4 = class extends ze {
differentialPairReroutingSolver;
fortyFiveDegreeSimplificationSolver;
lengthMatchingSolver;
hdRouteReconstructionSolver;
lengthMatchingBinding = null;
model;
fallbackOutput = null;
postProcessingErrors = [];
pipelineDef = [Le("differentialPairReroutingSolver", I4, (e49) => [e49.model.params]), Le("fortyFiveDegreeSimplificationSolver", C4, (e49) => {
const t6 = e49.getStageOutput("differentialPairReroutingSolver");
if (!t6)
throw new Error("PostProcessingSolver: rerouting stage completed without output");
const { obstacles: n6, bounds: o6, layerCount: i6, minTraceToPadEdgeClearance: r6 } = e49.model.params.simpleRouteJson;
return [{ ...t6, obstacles: n6, bounds: o6, layerCount: i6, minTraceToPadEdgeClearance: r6 }];
}), Le("lengthMatchingSolver", Q3, (e49) => {
const t6 = e49.getStageOutput("fortyFiveDegreeSimplificationSolver");
if (!t6)
throw new Error("PostProcessingSolver: 45-degree simplification stage completed without output");
return e49.lengthMatchingBinding = n4({ result: t6, params: e49.model.params }), [e49.lengthMatchingBinding.solverParams];
}), Le("hdRouteReconstructionSolver", N4, (e49) => {
const t6 = e49.getStageOutput("fortyFiveDegreeSimplificationSolver"), n6 = e49.getStageOutput("lengthMatchingSolver");
if (!t6 || !n6 || !e49.lengthMatchingBinding)
throw new Error("PostProcessingSolver: reconstruction stage is missing a required binding or output");
return [{ binding: e49.lengthMatchingBinding, result: n6, simplified: t6, params: e49.model.params, model: e49.model }];
}, { onSolved: (e49) => {
const t6 = e49.getStageOutput("differentialPairReroutingSolver");
if (!t6)
throw new Error("PostProcessingSolver: cannot summarize missing rerouting output");
e49.stats = { phase: "complete", acceptedPairCount: t6.reroutedPairs.length }, t6.failures.length > 0 && (e49.stats.skippedPairCount = t6.failures.length, e49.stats.postProcessingErrorCount = t6.failures.length);
} })];
constructor(e49) {
super(structuredClone(e49));
let t6 = null;
try {
(function(e50) {
if (!e50 || typeof e50 != "object")
throw new Error("PostProcessingSolver: params must be an object");
if (!Array.isArray(e50.hdRoutes))
throw new Error("PostProcessingSolver: hdRoutes must be an array");
if (!Array.isArray(e50.differentialPairs))
throw new Error("PostProcessingSolver: differentialPairs must be an array");
if (!Array.isArray(e50.obstacles))
throw new Error("PostProcessingSolver: obstacles must be an array");
if (e50.minTraceToPadEdgeClearance !== undefined && (!Number.isFinite(e50.minTraceToPadEdgeClearance) || e50.minTraceToPadEdgeClearance < 0))
throw new Error("PostProcessingSolver: minTraceToPadEdgeClearance must be finite and nonnegative");
if (!Number.isInteger(e50.layerCount) || e50.layerCount < 1)
throw new Error("PostProcessingSolver: layerCount must be a positive integer");
for (const t8 of e50.obstacles) {
if (!t8 || typeof t8 != "object" || t8.type !== "rect" || !t8.center || !Number.isFinite(t8.center.x) || !Number.isFinite(t8.center.y) || !Number.isFinite(t8.width) || t8.width <= 0 || !Number.isFinite(t8.height) || t8.height <= 0 || !Array.isArray(t8.layers) || t8.layers.some((e51) => typeof e51 != "string") || !Array.isArray(t8.connectedTo) || t8.connectedTo.some((e51) => typeof e51 != "string" || e51.length === 0) || t8.ccwRotationDegrees !== undefined && !Number.isFinite(t8.ccwRotationDegrees))
throw new Error("PostProcessingSolver: obstacle declaration is invalid");
k3(t8, e50.layerCount);
}
const { minX: t7, maxX: n7, minY: o6, maxY: i6 } = e50.bounds ?? {};
if (![t7, n7, o6, i6].every(Number.isFinite) || t7 >= n7 || o6 >= i6)
throw new Error("PostProcessingSolver: bounds must have finite positive extents");
const r6 = new Set(e50.differentialPairs.flatMap((e51) => e51.connectionNames));
for (const t8 of e50.hdRoutes) {
if (!t8 || typeof t8 != "object" || typeof t8.connectionName != "string" || t8.connectionName.length === 0 || t8.rootConnectionName !== undefined && (typeof t8.rootConnectionName != "string" || t8.rootConnectionName.length === 0) || !Number.isFinite(t8.traceThickness) || t8.traceThickness <= 0 || !Number.isFinite(t8.viaDiameter) || t8.viaDiameter < 0 || t8.viaDiameter === 0 && r6.has(t8.connectionName) || !Array.isArray(t8.route) || !Array.isArray(t8.vias) || t8.jumpers !== undefined && !Array.isArray(t8.jumpers))
throw new Error("PostProcessingSolver: HD route declaration is invalid");
if (t8.startPcbPortId !== undefined && (typeof t8.startPcbPortId != "string" || t8.startPcbPortId.length === 0) || t8.endPcbPortId !== undefined && (typeof t8.endPcbPortId != "string" || t8.endPcbPortId.length === 0))
throw new Error(`PostProcessingSolver: HD route "${t8.connectionName}" has invalid terminal metadata`);
for (const n8 of t8.route)
if (!n8 || typeof n8 != "object" || !Number.isFinite(n8.x) || !Number.isFinite(n8.y) || !Number.isInteger(n8.z) || n8.z < 0 || n8.z >= e50.layerCount || n8.traceThickness !== undefined && (!Number.isFinite(n8.traceThickness) || n8.traceThickness <= 0))
throw new Error(`PostProcessingSolver: HD route "${t8.connectionName}" has an invalid route point`);
for (const n8 of t8.vias)
if (!n8 || typeof n8 != "object" || !Number.isFinite(n8.x) || !Number.isFinite(n8.y) || n8.zLayers !== undefined && (!Array.isArray(n8.zLayers) || n8.zLayers.some((t9) => !Number.isInteger(t9) || t9 < 0 || t9 >= e50.layerCount)))
throw new Error(`PostProcessingSolver: HD route "${t8.connectionName}" has an invalid via`);
if (t8.vias.length > 0 && t8.viaDiameter <= 0)
throw new Error(`PostProcessingSolver: HD route "${t8.connectionName}" has a non-positive via diameter`);
for (const e51 of t8.jumpers ?? [])
if (!(e51 && typeof e51 == "object" && e51.route_type === "jumper" && Number.isFinite(e51.start?.x) && Number.isFinite(e51.start?.y) && Number.isFinite(e51.end?.x) && Number.isFinite(e51.end?.y) && ["0603", "1206", "1206x4_pair"].includes(e51.footprint)))
throw new Error(`PostProcessingSolver: HD route "${t8.connectionName}" has an invalid jumper`);
}
const s6 = new Set;
for (const t8 of e50.differentialPairs) {
if (!t8 || typeof t8 != "object" || !Array.isArray(t8.connectionNames) || t8.connectionNames.length !== 2 || t8.connectionNames[0] === t8.connectionNames[1] || !t8.connectionNames.every((e51) => typeof e51 == "string" && e51.length > 0) || !Number.isFinite(t8.lengthTolerance) || t8.lengthTolerance < 0)
throw new Error("PostProcessingSolver: differential pair declaration is invalid");
for (const e51 of [t8.minimumCenterlineDistance, t8.maximumCenterlineDistance])
if (e51 !== undefined && (!Number.isFinite(e51) || e51 <= 0))
throw new Error("PostProcessingSolver: differential pair centerline distances must be positive finite numbers");
if (t8.maxUncoupledLength !== undefined && (!Number.isFinite(t8.maxUncoupledLength) || t8.maxUncoupledLength < 0))
throw new Error("PostProcessingSolver: differential pair maxUncoupledLength must be a non-negative finite number");
if (t8.minimumCenterlineDistance !== undefined && t8.maximumCenterlineDistance !== undefined && t8.minimumCenterlineDistance > t8.maximumCenterlineDistance)
throw new Error("PostProcessingSolver: differential pair minimumCenterlineDistance cannot exceed maximumCenterlineDistance");
for (const e51 of t8.connectionNames) {
if (s6.has(e51))
throw new Error(`PostProcessingSolver: connection "${e51}" belongs to multiple differential pairs`);
s6.add(e51);
}
}
for (const t8 of [0.25, 0.5])
f4({ config: e50.routingGrid, bounds: e50.bounds, defaultInnerGridStep: t8 });
})(e49);
} catch (e50) {
if (!(e50 instanceof a4))
throw e50;
t6 = e50;
}
if (this.model = o4(e49), t6)
return void this.finishWithBestEffortOutput({ stage: "differentialPairReroutingSolver", message: t6.message, reason: t6.reason });
const n6 = c4(this.model.params) + Math.max(1, e49.differentialPairs.length + 1) + 1e5 + 10;
if (!Number.isSafeInteger(n6))
throw new Error("PostProcessingSolver: derived pipeline iteration bound exceeds the safe integer range");
this.MAX_ITERATIONS = n6;
}
getSolverName() {
return "PostProcessingSolver";
}
getConstructorParams() {
return [structuredClone(this.inputProblem)];
}
_step() {
const e49 = this.getCurrentStageName();
try {
super._step();
} catch (t7) {
const n6 = this.classifyOptimizationFailure(t7, e49);
if (!n6)
throw t7;
return void this.finishWithBestEffortOutput(n6);
}
if (!this.failed)
return;
const t6 = this.classifyIterationFailure(this.error, e49);
if (!t6)
throw new Error(this.error ?? "PostProcessingSolver failed without an error message");
this.finishWithBestEffortOutput(t6);
}
tryFinalAcceptance() {
const e49 = this.getCurrentStageName();
e49 !== "differentialPairReroutingSolver" && e49 !== "lengthMatchingSolver" || this.finishWithBestEffortOutput({ stage: e49, message: "PostProcessingSolver reached its iteration limit", reason: "iteration-limit-exhausted" });
}
classifyOptimizationFailure(e49, t6) {
return t6 === "lengthMatchingSolver" && e49 instanceof V3 ? { stage: t6, message: e49.message, connectionName: e49.connectionName, reason: e49.reason } : t6 === "hdRouteReconstructionSolver" && e49 instanceof s4 || t6 === "differentialPairReroutingSolver" && e49 instanceof r4 && e49.reason === "no-valid-candidate" ? { stage: t6, message: e49.message, connectionNames: [...e49.connectionNames], reason: e49.reason } : null;
}
classifyIterationFailure(e49, t6) {
return t6 !== "differentialPairReroutingSolver" && t6 !== "lengthMatchingSolver" ? null : e49 && e49.endsWith("ran out of iterations") ? { stage: t6, message: e49, reason: "iteration-limit-exhausted" } : null;
}
createBestEffortOutput(e49) {
let t6 = this.lengthMatchingBinding;
if (!t6) {
const e50 = this.getStageOutput("fortyFiveDegreeSimplificationSolver") ?? this.fortyFiveDegreeSimplificationSolver?.getBestEffortOutput(), n7 = this.getStageOutput("differentialPairReroutingSolver") ?? this.differentialPairReroutingSolver?.getBestEffortOutput(), o6 = e50 ?? n7;
o6 && (t6 = n4({ result: o6, params: this.model.params }));
}
if (!t6)
return { output: { hdRoutes: structuredClone(this.inputProblem.hdRoutes), postProcessingErrors: [] }, source: "input-hd-routes" };
let n6 = this.getStageOutput("lengthMatchingSolver");
return n6 || (n6 = this.lengthMatchingSolver?.getBestEffortOutput()), n6 && e49.reason !== "invalid-final-copper" || (n6 = { matchedHdRoutes: t6.solverParams.hdRoutes }), { output: i4({ binding: t6, result: n6, model: this.model }), source: "best-effort-hd-routes" };
}
finishWithBestEffortOutput(e49) {
const t6 = this.createBestEffortOutput(e49), n6 = { type: "post_processing_error", ...e49, returnedRouteSource: t6.source };
this.postProcessingErrors.push(n6), this.fallbackOutput = t6.output, this.activeSubSolver = null, this.error = null, this.failed = false, this.solved = true, 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 e49 = this.fallbackOutput ?? this.getStageOutput("hdRouteReconstructionSolver");
if (!e49)
throw new Error("PostProcessingSolver: completed pipeline is missing reconstruction output");
const t6 = this.getStageOutput("differentialPairReroutingSolver") ?? this.differentialPairReroutingSolver?.getBestEffortOutput(), n6 = t6?.failures ?? [];
let o6 = "input-hd-routes";
(t6?.reroutedPairs.length ?? 0) > 0 && (o6 = "best-effort-hd-routes");
const i6 = [...n6.map((e50) => ({ type: "post_processing_error", stage: "differentialPairReroutingSolver", message: e50.message, connectionNames: [...e50.connectionNames], reason: e50.reason, returnedRouteSource: o6 })), ...this.postProcessingErrors], r6 = structuredClone(e49);
return r6.postProcessingErrors = structuredClone(i6), r6;
}
initialVisualize() {
if (this.fallbackOutput)
return { lines: this.fallbackOutput.hdRoutes.map((e50) => ({ points: e50.route.map(({ x: e51, y: t7 }) => ({ x: e51, y: t7 })), strokeWidth: e50.traceThickness })) };
const { traces: e49, obstacles: t6, bounds: n6, layerCount: o6 } = this.model.params.simpleRouteJson;
return v4({ traces: structuredClone(e49), obstacles: t6, bounds: n6, layerCount: o6, activeConnectionNames: null, previewPath: null });
}
finalVisualize() {
if (this.fallbackOutput)
return this.initialVisualize();
const e49 = o4({ ...this.inputProblem, hdRoutes: this.getOutput().hdRoutes }), { traces: t6, obstacles: n6, bounds: o6, layerCount: i6 } = e49.params.simpleRouteJson;
return v4({ traces: t6, obstacles: n6, bounds: o6, layerCount: i6, activeConnectionNames: null, previewPath: null });
}
};
var R4 = class e49 {
static generators = new Map;
static register(t6) {
e49.generators.set(t6.componentKind, t6);
}
static create(t6) {
const n6 = t6.detectedComponent.componentKind, o6 = e49.generators.get(n6);
if (!o6)
throw new Error(`No topology generator registered for component kind "${n6}"`);
return new o6(t6);
}
};
var E4 = (e50) => [e50.obstacle.obstacleId ?? e50.obstacle.componentId ?? "obstacle", e50.start.x.toFixed(4), e50.start.y.toFixed(4), e50.end.x.toFixed(4), e50.end.y.toFixed(4), e50.expansionDirection.x, e50.expansionDirection.y].join(":");
var A4 = (e50) => {
let t6 = 0;
for (const n6 of e50)
t6 = 31 * t6 + n6.charCodeAt(0) >>> 0;
return t6;
};
var O4 = (e50, t6) => `hsla(${A4(E4(e50)) % 360},72%,36%,${t6})`;
var k4 = (e50) => {
const t6 = e50.expansionDirection;
return t6.x < 0 ? "left" : t6.x > 0 ? "right" : t6.y < 0 ? "bottom" : "top";
};
var D4 = (e50) => ({ x: (e50.start.x + e50.end.x) / 2, y: (e50.start.y + e50.end.y) / 2 });
var L4 = (e50) => {
const t6 = /^bga-gapfill-(\d+)-/.exec(e50.capacityMeshNodeId);
return t6 ? Number.parseInt(t6[1], 10) : null;
};
var z4 = (e50, t6) => {
const n6 = D4(e50), o6 = D4(t6), i6 = n6.y - o6.y;
if (Math.abs(i6) > 0.000001)
return i6;
const r6 = n6.x - o6.x;
return Math.abs(r6) > 0.000001 ? r6 : E4(e50).localeCompare(E4(t6));
};
var B4 = (e50) => {
const t6 = [...e50].sort(z4), n6 = [];
let o6 = t6.shift();
for (;o6 && (n6.push(o6), t6.length !== 0); ) {
const e51 = D4(o6);
let n7 = 0, i6 = Number.POSITIVE_INFINITY;
for (let o7 = 0;o7 < t6.length; o7++) {
const r6 = t6[o7], s6 = D4(r6), a6 = (s6.x - e51.x) ** 2 + (s6.y - e51.y) ** 2;
a6 < i6 - 0.000000001 ? (i6 = a6, n7 = o7) : Math.abs(a6 - i6) <= 0.000000001 && z4(r6, t6[n7]) < 0 && (n7 = o7);
}
o6 = t6.splice(n7, 1)[0];
}
return n6;
};
var F4 = (e50, t6) => {
const n6 = E4(e50), o6 = t6.findIndex((e51) => E4(e51) === n6);
return o6 >= 0 ? `E${o6 + 1}` : `E${A4(n6).toString(36).slice(0, 4)}`;
};
var j4 = (e50) => e50.flatMap((e51) => {
const t6 = Vt(e51);
return [{ obstacle: e51, start: { x: t6.minX, y: t6.minY }, end: { x: t6.minX, y: t6.maxY }, expansionDirection: { x: -1, y: 0 } }, { obstacle: e51, start: { x: t6.maxX, y: t6.minY }, end: { x: t6.maxX, y: t6.maxY }, expansionDirection: { x: 1, y: 0 } }, { obstacle: e51, start: { x: t6.minX, y: t6.minY }, end: { x: t6.maxX, y: t6.minY }, expansionDirection: { x: 0, y: -1 } }, { obstacle: e51, start: { x: t6.minX, y: t6.maxY }, end: { x: t6.maxX, y: t6.maxY }, expansionDirection: { x: 0, y: 1 } }];
});
var $4 = 0.001;
var Y4 = 0.001;
var X4 = class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
inputProblem;
meshIndex;
allEdges = [];
queueEdges = [];
disconnectedEdges = [];
currentEdge = null;
lastSearchBounds = null;
lastCandidateMeshNodes = [];
lastMatchedMeshNode = null;
_setup() {
const e50 = Math.max(this.inputProblem.meshNodes.length, 1);
this.meshIndex = new je(e50);
for (const e51 of this.inputProblem.meshNodes) {
const t7 = Vt(e51);
this.meshIndex.add(t7.minX, t7.minY, t7.maxX, t7.maxY);
}
this.meshIndex.finish();
const t6 = j4(this.inputProblem.unmarkedComponentObstacles);
this.queueEdges = t6, this.allEdges = B4(t6), this.currentEdge = null, this.lastSearchBounds = null, this.lastCandidateMeshNodes = [], this.lastMatchedMeshNode = null;
}
_step() {
const e50 = this.queueEdges.shift();
if (!e50)
return this.currentEdge = null, this.lastSearchBounds = null, this.lastCandidateMeshNodes = [], this.lastMatchedMeshNode = null, void (this.solved = true);
this.currentEdge = e50, this.lastMatchedMeshNode = null;
const t6 = Math.abs(e50.start.x - e50.end.x) <= $4, n6 = t6 ? { minX: e50.start.x - Y4, maxX: e50.start.x + Y4, minY: Math.min(e50.start.y, e50.end.y), maxY: Math.max(e50.start.y, e50.end.y) } : { minX: Math.min(e50.start.x, e50.end.x), maxX: Math.max(e50.start.x, e50.end.x), minY: e50.start.y - Y4, maxY: e50.start.y + Y4 };
this.lastSearchBounds = n6;
const o6 = this.meshIndex.search(n6.minX, n6.minY, n6.maxX, n6.maxY);
this.lastCandidateMeshNodes = o6.map((e51) => this.inputProblem.meshNodes[e51]);
let i6 = false;
for (const n7 of o6) {
const o7 = this.inputProblem.meshNodes[n7], r6 = Vt(o7);
if (t6) {
if (!(Math.min(r6.maxY, Math.max(e50.start.y, e50.end.y)) - Math.max(r6.minY, Math.min(e50.start.y, e50.end.y)) > $4))
continue;
if (e50.expansionDirection.x === -1 && Math.abs(r6.maxX - e50.start.x) <= $4) {
i6 = true, this.lastMatchedMeshNode = o7;
break;
}
if (e50.expansionDirection.x === 1 && Math.abs(r6.minX - e50.start.x) <= $4) {
i6 = true, this.lastMatchedMeshNode = o7;
break;
}
continue;
}
if (Math.min(r6.maxX, Math.max(e50.start.x, e50.end.x)) - Math.max(r6.minX, Math.min(e50.start.x, e50.end.x)) > $4) {
if (e50.expansionDirection.y === -1 && Math.abs(r6.maxY - e50.start.y) <= $4) {
i6 = true, this.lastMatchedMeshNode = o7;
break;
}
if (e50.expansionDirection.y === 1 && Math.abs(r6.minY - e50.start.y) <= $4) {
i6 = true, this.lastMatchedMeshNode = o7;
break;
}
}
}
i6 || this.disconnectedEdges.push(e50);
}
getOutput() {
return this.disconnectedEdges;
}
visualize() {
const e50 = this.disconnectedEdges, t6 = this.allEdges.length > 0 ? this.allEdges : [...e50, ...this.currentEdge ? [this.currentEdge] : []], n6 = this.currentEdge ? O4(this.currentEdge, 0.88) : "rgba(40,40,40,0.4)", o6 = this.inputProblem.meshNodes.map((e51) => ({ ...mF(e51, { rectMargin: 0.01 }), fill: e51._containsObstacle ? "rgba(120,120,120,0.18)" : "rgba(120,120,120,0.08)", stroke: e51._containsObstacle ? "rgba(120,120,120,0.42)" : "rgba(120,120,120,0.24)" })), i6 = this.lastSearchBounds && this.currentEdge ? [{ center: (r6 = this.lastSearchBounds, { x: (r6.minX + r6.maxX) / 2, y: (r6.minY + r6.maxY) / 2 }), width: this.lastSearchBounds.maxX - this.lastSearchBounds.minX, height: this.lastSearchBounds.maxY - this.lastSearchBounds.minY, fill: O4(this.currentEdge, 0.1), stroke: O4(this.currentEdge, 0.36), label: [F4(this.currentEdge, t6), "search band"].join(" ") }] : [];
var r6;
const s6 = this.lastCandidateMeshNodes.map((e51) => ({ ...mF(e51, { rectMargin: 0.018 }), fill: e51 === this.lastMatchedMeshNode ? "rgba(0,180,90,0.24)" : this.currentEdge ? O4(this.currentEdge, 0.16) : "rgba(80,120,160,0.16)", stroke: e51 === this.lastMatchedMeshNode ? "rgba(0,150,80,0.88)" : n6, label: [e51 === this.lastMatchedMeshNode ? "matched" : "candidate", e51.capacityMeshNodeId, `z:${e51.availableZ.join(",")}`].join(`
`) })), a6 = this.inputProblem.unmarkedComponentObstacles.map((e51) => ({ center: e51.center, width: e51.width, height: e51.height, fill: "rgba(160,160,160,0.10)", stroke: "rgba(160,160,160,0.40)", label: e51.obstacleId ?? e51.componentId ?? "obstacle" })), c6 = e50.map((e51) => ({ points: [e51.start, e51.end], strokeColor: O4(e51, 0.14), strokeWidth: 0.01, strokeDash: "5 4", label: [F4(e51, t6), k4(e51), "disconnected"].join(" ") })), l6 = [], h6 = [];
if (this.currentEdge) {
const e51 = D4(this.currentEdge);
l6.push({ points: [this.currentEdge.start, this.currentEdge.end], strokeColor: O4(this.currentEdge, 1), strokeWidth: 0.06, label: [F4(this.currentEdge, t6), k4(this.currentEdge), "checking"].join(" ") }, { points: [e51, { x: e51.x + 0.16 * this.currentEdge.expansionDirection.x, y: e51.y + 0.16 * this.currentEdge.expansionDirection.y }], strokeColor: O4(this.currentEdge, 0.82), strokeWidth: 0.02, strokeDash: "3 3" }), h6.push({ ...e51, color: O4(this.currentEdge, 1), label: F4(this.currentEdge, t6) });
}
return { rects: [...o6, ...i6, ...s6, ...a6], lines: [...c6, ...l6], points: h6 };
}
};
var W4 = 0.001;
var V4 = 0.001;
var H4 = 0.000001;
var G4 = class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
inputProblem;
meshIndex;
meshBounds;
expandedNodes = [];
_setup() {
const e50 = Math.max(this.inputProblem.meshNodes.length, 1);
this.meshIndex = new je(e50);
let { POSITIVE_INFINITY: t6, NEGATIVE_INFINITY: n6, POSITIVE_INFINITY: o6, NEGATIVE_INFINITY: i6 } = Number;
for (const e51 of this.inputProblem.meshNodes) {
const r6 = Vt(e51);
this.meshIndex.add(r6.minX, r6.minY, r6.maxX, r6.maxY), t6 = Math.min(t6, r6.minX), n6 = Math.max(n6, r6.maxX), o6 = Math.min(o6, r6.minY), i6 = Math.max(i6, r6.maxY);
}
this.meshIndex.finish(), this.meshBounds = this.inputProblem.meshNodes.length ? { minX: t6, maxX: n6, minY: o6, maxY: i6 } : { minX: 0, maxX: 0, minY: 0, maxY: 0 };
}
getObstacleAvailableZ(e50) {
return e50.__zLayers ?? e50.layers.map((e51) => go(e51, this.inputProblem.layerCount));
}
getSharedOverlapArea(e50, t6) {
if (!e50.availableZ.some((e51) => t6.availableZ.includes(e51)))
return 0;
const n6 = Vt(e50), o6 = Vt(t6), i6 = Math.min(n6.maxX, o6.maxX) - Math.max(n6.minX, o6.minX), r6 = Math.min(n6.maxY, o6.maxY) - Math.max(n6.minY, o6.minY);
return i6 <= H4 || r6 <= H4 ? 0 : i6 * r6;
}
getNodeObstacleOverlapArea(e50, t6) {
const n6 = this.getObstacleAvailableZ(t6);
if (!e50.availableZ.some((e51) => n6.includes(e51)))
return 0;
const o6 = Vt(e50), i6 = Vt(t6), r6 = Math.min(o6.maxX, i6.maxX) - Math.max(o6.minX, i6.minX), s6 = Math.min(o6.maxY, i6.maxY) - Math.max(o6.minY, i6.minY);
return r6 <= H4 || s6 <= H4 ? 0 : r6 * s6;
}
getClosestMeshNode(e50, t6) {
const n6 = Math.abs(e50.start.x - e50.end.x) <= W4, o6 = this.getObstacleAvailableZ(e50.obstacle), i6 = n6 ? e50.expansionDirection.x < 0 ? { minX: this.meshBounds.minX, maxX: e50.start.x, minY: Math.min(e50.start.y, e50.end.y) - V4, maxY: Math.max(e50.start.y, e50.end.y) + V4 } : { minX: e50.start.x, maxX: this.meshBounds.maxX, minY: Math.min(e50.start.y, e50.end.y) - V4, maxY: Math.max(e50.start.y, e50.end.y) + V4 } : e50.expansionDirection.y < 0 ? { minX: Math.min(e50.start.x, e50.end.x) - V4, maxX: Math.max(e50.start.x, e50.end.x) + V4, minY: this.meshBounds.minY, maxY: e50.start.y } : { minX: Math.min(e50.start.x, e50.end.x) - V4, maxX: Math.max(e50.start.x, e50.end.x) + V4, minY: e50.start.y, maxY: this.meshBounds.maxY }, r6 = this.meshIndex.search(i6.minX, i6.minY, i6.maxX, i6.maxY);
let s6 = null, a6 = Number.POSITIVE_INFINITY;
const c6 = [...r6.map((e51) => this.inputProblem.meshNodes[e51]), ...t6];
for (const t7 of c6) {
if (t7._containsObstacle)
continue;
if (!t7.availableZ.some((e51) => o6.includes(e51)))
continue;
const i7 = Vt(t7);
if ((n6 ? Math.min(Math.max(e50.start.y, e50.end.y), i7.maxY) - Math.max(Math.min(e50.start.y, e50.end.y), i7.minY) : Math.min(Math.max(e50.start.x, e50.end.x), i7.maxX) - Math.max(Math.min(e50.start.x, e50.end.x), i7.minX)) <= W4)
continue;
const r7 = n6 ? e50.expansionDirection.x < 0 ? e50.start.x - i7.maxX : i7.minX - e50.start.x : e50.expansionDirection.y < 0 ? e50.start.y - i7.maxY : i7.minY - e50.start.y;
r7 < W4 || (r7 >= a6 || (a6 = r7, s6 = t7));
}
return s6;
}
createExpandedNode(e50, t6, n6) {
const o6 = Vt(t6), i6 = this.getObstacleAvailableZ(e50.obstacle);
if (Math.abs(e50.start.x - e50.end.x) <= W4) {
const r7 = Math.max(Math.min(e50.start.y, e50.end.y), o6.minY), s7 = Math.min(Math.max(e50.start.y, e50.end.y), o6.maxY), a7 = e50.expansionDirection.x < 0 ? o6.maxX : e50.start.x, c7 = e50.expansionDirection.x < 0 ? e50.start.x : o6.minX;
return c7 - a7 <= W4 || s7 - r7 <= W4 ? null : { capacityMeshNodeId: `bga-gapfill-${n6}-${e50.obstacle.obstacleId ?? "no-obstacle"}-${t6.capacityMeshNodeId}`, center: { x: (a7 + c7) / 2, y: (r7 + s7) / 2 }, width: c7 - a7, height: s7 - r7, layer: `z${i6.join(",")}`, availableZ: i6 };
}
const r6 = Math.max(Math.min(e50.start.x, e50.end.x), o6.minX), s6 = Math.min(Math.max(e50.start.x, e50.end.x), o6.maxX), a6 = e50.expansionDirection.y < 0 ? o6.maxY : e50.start.y, c6 = e50.expansionDirection.y < 0 ? e50.start.y : o6.minY;
return s6 - r6 <= W4 || c6 - a6 <= W4 ? null : { capacityMeshNodeId: `bga-gapfill-${n6}-${e50.obstacle.obstacleId ?? "no-obstacle"}-${t6.capacityMeshNodeId}`, center: { x: (r6 + s6) / 2, y: (a6 + c6) / 2 }, width: s6 - r6, height: c6 - a6, layer: `z${i6.join(",")}`, availableZ: i6 };
}
overlapsExistingGeometry(e50, t6) {
for (const t7 of this.inputProblem.meshNodes)
if (this.getSharedOverlapArea(e50, t7) > 0)
return true;
for (const n6 of t6)
if (this.getSharedOverlapArea(e50, n6) > 0)
return true;
for (const t7 of this.inputProblem.edgesWithObstacle)
if (this.getNodeObstacleOverlapArea(e50, t7.obstacle) > 0)
return true;
return false;
}
_step() {
const e50 = [];
for (const [t6, n6] of this.inputProblem.edgesWithObstacle.entries()) {
const o6 = this.getClosestMeshNode(n6, e50);
if (!o6)
continue;
const i6 = this.createExpandedNode(n6, o6, t6);
i6 && (this.overlapsExistingGeometry(i6, e50) || e50.push(i6));
}
this.expandedNodes = e50, this.solved = true;
}
getOutput() {
return this.expandedNodes;
}
visualize() {
const e50 = this.inputProblem.edgesWithObstacle, t6 = B4(e50);
return { rects: [...this.inputProblem.meshNodes.map((e51) => ({ ...mF(e51, { rectMargin: 0.01 }), fill: e51._containsObstacle ? "rgba(255,0,0,0.16)" : "rgba(0,120,255,0.08)", stroke: e51._containsObstacle ? "rgba(255,0,0,0.35)" : "rgba(0,120,255,0.28)" })), ...this.expandedNodes.map((n6) => {
const o6 = L4(n6), i6 = o6 === null ? null : e50[o6] ?? null;
return { ...mF(n6, { rectMargin: 0.012, zOffset: 0.01 }), fill: i6 ? O4(i6, 0.24) : "rgba(0,160,100,0.24)", stroke: i6 ? O4(i6, 0.72) : "rgba(0,160,100,0.68)", label: [i6 ? F4(i6, t6) : "E?", "expanded", n6.capacityMeshNodeId, `z:${n6.availableZ.join(",")}`].join(`
`) };
})], lines: [...this.inputProblem.edgesWithObstacle.map((e51) => ({ points: [e51.start, e51.end], strokeColor: O4(e51, 0.9), strokeWidth: 0.034, label: [F4(e51, t6), k4(e51)].join(" ") })), ...this.inputProblem.edgesWithObstacle.map((e51) => {
const t7 = D4(e51);
return { points: [t7, { x: t7.x + 0.16 * e51.expansionDirection.x, y: t7.y + 0.16 * e51.expansionDirection.y }], strokeColor: O4(e51, 0.7), strokeWidth: 0.016, strokeDash: "3 3" };
})], points: this.inputProblem.edgesWithObstacle.map((e51) => ({ ...D4(e51), color: O4(e51, 0.95), label: F4(e51, t6) })) };
}
};
var U4 = 0.001;
var Z4 = class extends ze {
constructor(e50) {
super(e50), this.inputProblem = e50;
}
inputProblem;
detectEdgesNotConnectedToMesh;
expandUnconnectedEdgesToMesh;
pipelineDef = [Le("detectEdgesNotConnectedToMesh", X4, (e50) => [e50.inputProblem]), Le("expandUnconnectedEdgesToMesh", G4, (e50) => [{ meshNodes: e50.inputProblem.meshNodes, edgesWithObstacle: e50.detectEdgesNotConnectedToMesh.getOutput(), layerCount: e50.inputProblem.layerCount }])];
getOutput() {
return [...this.inputProblem.meshNodes, ...this.expandUnconnectedEdgesToMesh.getOutput()];
}
getExpandedNodes() {
return this.expandUnconnectedEdgesToMesh.getOutput();
}
getObstacleLayer(e50) {
return `z${(e50.obstacle.__zLayers ?? e50.obstacle.layers.map((e51) => go(e51, this.inputProblem.layerCount))).join(",")}`;
}
getObstacleRects() {
return this.inputProblem.unmarkedComponentObstacles.map((e50) => {
const t6 = e50.__zLayers ?? e50.layers.map((e51) => go(e51, this.inputProblem.layerCount));
return { center: e50.center, width: e50.width, height: e50.height, fill: "rgba(150,150,150,0.08)", stroke: "rgba(90,90,90,0.42)", label: e50.obstacleId ?? e50.componentId ?? "bga obstacle", layer: `z${t6.join(",")}` };
});
}
getBaseMeshRects() {
return this.inputProblem.meshNodes.map((e50) => ({ ...mF(e50, { rectMargin: 0.025, zOffset: 0.01 }), fill: e50._containsObstacle ? "rgba(210,60,60,0.14)" : "rgba(80,120,160,0.08)", stroke: e50._containsObstacle ? "rgba(190,40,40,0.42)" : "rgba(80,120,160,0.28)", label: `mesh ${e50.capacityMeshNodeId}
z:${e50.availableZ.join(",")}` }));
}
initialVisualize() {
const e50 = j4(this.inputProblem.unmarkedComponentObstacles), t6 = B4(e50), n6 = [...e50.map((e51) => ({ points: [e51.start, e51.end], strokeColor: O4(e51, 0.72), strokeWidth: 0.018, strokeDash: "0.05 0.035", layer: this.getObstacleLayer(e51), label: [F4(e51, t6), k4(e51)].join(" ") })), ...e50.map((e51) => {
const t7 = D4(e51);
return { points: [t7, { x: t7.x + 0.18 * e51.expansionDirection.x, y: t7.y + 0.18 * e51.expansionDirection.y }], strokeColor: O4(e51, 0.64), strokeWidth: 0.012, strokeDash: "0.035 0.025", layer: this.getObstacleLayer(e51) };
})];
return { title: "BGA GapFill: candidate obstacle edges", rects: [...this.getBaseMeshRects(), ...this.getObstacleRects()], lines: n6 };
}
finalVisualize() {
const e50 = this.getStageOutput("detectEdgesNotConnectedToMesh") ?? [], t6 = this.getStageOutput("expandUnconnectedEdgesToMesh") ?? [], n6 = B4(j4(this.inputProblem.unmarkedComponentObstacles)), o6 = new Map;
for (const e51 of t6) {
const t7 = L4(e51);
t7 !== null && o6.set(t7, e51);
}
const i6 = t6.map((t7) => {
const o7 = L4(t7), i7 = o7 === null ? null : e50[o7] ?? null, r7 = i7 ? (({ expandedNode: e51, edge: t8, meshNodes: n7 }) => {
const o8 = Vt(e51), i8 = Math.abs(t8.start.x - t8.end.x) <= U4;
return n7.filter((n8) => {
if (n8._containsObstacle)
return false;
if (!e51.availableZ.some((e53) => n8.availableZ.includes(e53)))
return false;
const r8 = Vt(n8);
return i8 ? !(Math.min(o8.maxY, r8.maxY) - Math.max(o8.minY, r8.minY) <= U4) && (t8.expansionDirection.x < 0 ? Math.abs(r8.maxX - o8.minX) <= U4 : Math.abs(r8.minX - o8.maxX) <= U4) : !(Math.min(o8.maxX, r8.maxX) - Math.max(o8.minX, r8.minX) <= U4) && (t8.expansionDirection.y < 0 ? Math.abs(r8.maxY - o8.minY) <= U4 : Math.abs(r8.minY - o8.maxY) <= U4);
}).map((e53) => e53.capacityMeshNodeId);
})({ expandedNode: t7, edge: i7, meshNodes: this.inputProblem.meshNodes }) : [], s7 = i7 ? F4(i7, n6) : "E?", a7 = i7 === null ? "rgba(0,160,100,0.72)" : O4(i7, 0.72);
return { ...mF(t7, { rectMargin: 0.012, zOffset: 0.01 }), fill: i7 === null ? "rgba(0,160,100,0.24)" : O4(i7, 0.16), stroke: a7, label: [`${s7} gap fill`, r7.length > 0 ? `to ${r7.join(",")}` : "target mesh not adjacent", `z:${t7.availableZ.join(",")}`].join(`
`) };
}), r6 = e50.map((e51, t7) => {
const i7 = o6.get(t7);
return { points: [e51.start, e51.end], strokeColor: i7 ? O4(e51, 0.68) : "rgba(80,80,80,0.14)", strokeWidth: i7 ? 0.026 : 0.008, ...i7 ? {} : { strokeDash: "5 4" }, layer: this.getObstacleLayer(e51), label: [[F4(e51, n6), k4(e51)].join(" "), i7 ? "filled" : "no fill created"].join(`
`) };
}), s6 = e50.flatMap((e51, t7) => {
const n7 = D4(e51), i7 = o6.get(t7);
return i7 ? [{ points: [n7, i7.center], strokeColor: O4(e51, 0.42), strokeWidth: 0.012, strokeDash: "0.035 0.025", layer: this.getObstacleLayer(e51) }] : [];
}), a6 = e50.flatMap((e51, t7) => o6.has(t7) ? [{ ...D4(e51), color: O4(e51, 0.82), label: F4(e51, n6), layer: this.getObstacleLayer(e51) }] : []);
return { title: "BGA GapFill: disconnected edges and created mesh", rects: [...this.getBaseMeshRects(), ...this.getObstacleRects(), ...i6], lines: [...r6, ...s6], points: a6 };
}
};
function q4(e50, t6) {
const n6 = [];
for (let o6 = 0;o6 < e50.length; o6++) {
const i6 = e50[o6];
n6.push(i6);
const r6 = e50[o6 + 1];
if (r6 === undefined)
continue;
const s6 = Math.round((r6 - i6) / t6);
if (!(s6 <= 1))
for (let e51 = 1;e51 < s6; e51++) {
const t7 = e51 / s6;
n6.push(Number((i6 + (r6 - i6) * t7).toFixed(6)));
}
}
return n6;
}
var J4 = 0.001;
function Q4(e50) {
const t6 = [];
for (let n7 = 1;n7 < e50.length; n7++) {
const o7 = e50[n7] - e50[n7 - 1];
o7 > J4 && t6.push(o7);
}
if (t6.length === 0)
return null;
const n6 = Math.min(...t6), o6 = t6.filter((e51) => e51 <= 1.5 * n6).sort((e51, t7) => e51 - t7), i6 = Math.floor(o6.length / 2);
return o6.length % 2 == 0 ? (o6[i6 - 1] + o6[i6]) / 2 : o6[i6];
}
function K4(e50) {
return [...new Set(e50)].sort((e51, t6) => e51 - t6);
}
function e92(e50) {
return Number(e50.toFixed(6));
}
var t9 = class e51 {
static fromObstacles(t6) {
if (t6.length === 0)
return null;
const n6 = K4(t6.map((e50) => e50.center.x)), o6 = K4(t6.map((e50) => e50.center.y)), i6 = Q4(n6), r6 = Q4(o6);
return i6 === null || r6 === null ? null : new e51({ obstacles: t6, xCoordinates: q4(n6, i6), yCoordinates: q4(o6, r6), pitchX: i6, pitchY: r6 });
}
xCoordinates;
yCoordinates;
pitchX;
pitchY;
originX;
originY;
rowCount;
colCount;
padWidth;
padHeight;
slots = new Map;
constructor(e50) {
this.xCoordinates = e50.xCoordinates, this.yCoordinates = e50.yCoordinates, this.pitchX = e50.pitchX, this.pitchY = e50.pitchY, this.originX = this.xCoordinates[0], this.originY = this.yCoordinates[0], this.colCount = this.xCoordinates.length, this.rowCount = this.yCoordinates.length, this.padWidth = e50.obstacles[0].width, this.padHeight = e50.obstacles[0].height;
for (const t6 of e50.obstacles) {
const e53 = this.getSlotForObstacle(t6);
e53 && this.slots.set(this.getSlotKey(e53.row, e53.col), { ...e53, obstacle: t6 });
}
}
getSlotKey(e50, t6) {
return `${e50}:${t6}`;
}
getAxisIndex(e50, t6) {
let n6 = -1, o6 = Number.POSITIVE_INFINITY;
for (let i6 = 0;i6 < e50.length; i6++) {
const r6 = Math.abs(e50[i6] - t6);
r6 < o6 && (o6 = r6, n6 = i6);
}
return o6 <= J4 ? n6 : null;
}
getAxisCoordinate(e50, t6) {
return e50[t6];
}
hasPadAt(e50, t6) {
return this.slots.has(this.getSlotKey(e50, t6));
}
getSlotForObstacle(e50) {
const t6 = this.getAxisIndex(this.yCoordinates, e50.center.y), n6 = this.getAxisIndex(this.xCoordinates, e50.center.x);
return t6 === null || n6 === null || t6 < 0 || t6 >= this.rowCount || n6 < 0 || n6 >= this.colCount ? null : { row: t6, col: n6 };
}
getSlotCenter(e50, t6) {
return { x: this.getAxisCoordinate(this.xCoordinates, t6), y: this.getAxisCoordinate(this.yCoordinates, e50) };
}
getHorizontalGap(e50, t6) {
const n6 = this.getSlotCenter(e50, t6), o6 = this.getSlotCenter(e50, t6 + 1), i6 = Math.abs(o6.x - n6.x);
return { orientation: "horizontal", row: e50, col: t6, center: { x: e92((n6.x + o6.x) / 2), y: n6.y }, width: i6 - this.padWidth, height: this.padHeight, isBetweenTwoPads: this.hasPadAt(e50, t6) && this.hasPadAt(e50, t6 + 1) };
}
getVerticalGap(e50, t6) {
const n6 = this.getSlotCenter(e50, t6), o6 = this.getSlotCenter(e50 + 1, t6), i6 = Math.abs(o6.y - n6.y);
return { orientation: "vertical", row: e50, col: t6, center: { x: n6.x, y: e92((n6.y + o6.y) / 2) }, width: this.padWidth, height: i6 - this.padHeight, isBetweenTwoPads: this.hasPadAt(e50, t6) && this.hasPadAt(e50 + 1, t6) };
}
getDiagonalGap(e50, t6) {
const n6 = this.getSlotCenter(e50, t6), o6 = this.getSlotCenter(e50 + 1, t6 + 1), i6 = Math.abs(o6.x - n6.x), r6 = Math.abs(o6.y - n6.y);
return { orientation: "diagonal", row: e50, col: t6, center: { x: e92((n6.x + o6.x) / 2), y: e92((n6.y + o6.y) / 2) }, width: i6 - this.padWidth, height: r6 - this.padHeight, isBetweenTwoPads: this.hasPadAt(e50, t6) && this.hasPadAt(e50 + 1, t6 + 1) };
}
getDiagonalGaps() {
const e50 = [];
for (let t6 = 0;t6 < this.rowCount - 1; t6++)
for (let n6 = 0;n6 < this.colCount - 1; n6++)
e50.push(this.getDiagonalGap(t6, n6));
return e50.filter((e53) => e53.width > J4 && e53.height > J4);
}
getAxisGaps() {
const e50 = [];
for (let t6 = 0;t6 < this.rowCount; t6++)
for (let n6 = 0;n6 < this.colCount - 1; n6++)
e50.push(this.getHorizontalGap(t6, n6));
for (let t6 = 0;t6 < this.rowCount - 1; t6++)
for (let n6 = 0;n6 < this.colCount; n6++)
e50.push(this.getVerticalGap(t6, n6));
return e50.filter((e53) => e53.width > J4 && e53.height > J4);
}
getMissingSlots() {
const e50 = [];
for (let t6 = 0;t6 < this.rowCount; t6++)
for (let n6 = 0;n6 < this.colCount; n6++)
this.hasPadAt(t6, n6) || e50.push({ row: t6, col: n6, center: this.getSlotCenter(t6, n6), width: this.padWidth, height: this.padHeight });
return e50;
}
};
function n9(e50) {
if ([e50.point.pointId, e50.point.pcb_port_id].filter((e53) => typeof e53 == "string").some((t7) => e50.obstacle.connectedTo.includes(t7)))
return true;
if (e50.obstacle.connectedTo.length === 0)
return false;
if (jt(e50.point, e50.obstacle) > 0.001)
return false;
const t6 = Co(e50.point).map((t7) => go(t7, e50.layerCount)), n6 = e50.obstacle.layers.map((t7) => go(t7, e50.layerCount));
return t6.some((e53) => n6.includes(e53));
}
function o9(e50) {
return e50.obstacleId ?? [e50.componentId ?? "no-component", e50.center.x, e50.center.y, e50.width, e50.height, e50.layers.join(",")].join(":");
}
function i9({ componentId: e50, orientationKey: t6, row: n6, col: o6, center: i6, width: r6, height: s6 }) {
return ["cmn", t6, e50, n6, o6, i6.x, i6.y, r6, s6].join("_");
}
function r9(e50) {
const { componentId: t6, bgaGap: n6, freeLayers: o6, multiLayerThreshold: i6 } = e50, r6 = n6.width > i6 && n6.height > i6;
let s6 = "d";
n6.orientation === "horizontal" && (s6 = "h"), n6.orientation === "vertical" && (s6 = "v");
const a6 = i9({ componentId: t6, orientationKey: s6, row: n6.row, col: n6.col, center: n6.center, width: n6.width, height: n6.height });
return n6.orientation === "diagonal" && r6 || !n6.isBetweenTwoPads && r6 ? [{ center: n6.center, width: n6.width, height: n6.height, availableZ: [...o6], capacityMeshNodeId: `${a6}_all`, layer: "" }] : o6.map((e53) => ({ center: n6.center, width: n6.width, height: n6.height, availableZ: [e53], capacityMeshNodeId: `${a6}_${e53}`, layer: "" }));
}
function s9(e50) {
const { componentId: t6, obstacle: n6, freeLayers: o6, layerCount: i6 } = e50, r6 = n6.layers.map((e53) => go(e53, i6)), s6 = o6.filter((e53) => !r6.includes(e53)), a6 = o9(n6);
return s6.map((e53) => ({ capacityMeshNodeId: `free-${t6}-${a6}-${e53}`, center: n6.center, width: n6.width, height: n6.height, layer: `z${e53}`, availableZ: [e53] }));
}
function a9(e50, t6, n6) {
const o6 = t6.layers.map((e53) => go(e53, n6.layerCount)), i6 = o9(t6), r6 = function(e53) {
for (const t7 of e53.srj.connections)
for (const n7 of t7.pointsToConnect)
if (n9({ point: n7, obstacle: e53.obstacle, layerCount: e53.srj.layerCount }))
return t7.__rootConnectionNames?.[0] ?? t7.name;
}({ obstacle: t6, srj: n6 });
return { capacityMeshNodeId: `obstacle-${e50}-${i6}-${o6.join(",")}-${t6.center.x}-${t6.center.y}`, _containsObstacle: true, ...r6 ? { _containsTarget: true, _targetConnectionName: r6 } : {}, center: t6.center, width: t6.width, height: t6.height, layer: `z${o6.join(",")}`, availableZ: o6 };
}
var c9 = class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
inputProblem;
componentObstacles = [];
meshNodes = [];
getConstructorParams() {
return [this.inputProblem];
}
_step() {
const { srj: e50, componentBounds: t6, componentId: n6, markedComponentObstacles: o6, unmarkedComponentObstacles: i6 } = this.inputProblem, r6 = e50.obstacles.filter((e53) => e53.isCopperPour === true).filter((e53) => Wt(Vt(e53), t6)).flatMap((t7) => t7.layers.map((t8) => go(t8, e50.layerCount))), s6 = Array.from({ length: e50.layerCount }, (e53, t7) => t7).filter((e53) => !r6.includes(e53));
if (this.componentObstacles = o6, o6.length === 0 || s6.length === 0)
return void (this.solved = true);
const a6 = t9.fromObstacles(o6);
if (!a6)
return void (this.solved = true);
const c6 = a6.getAxisGaps(), l6 = a6.getDiagonalGaps(), h6 = a6.getMissingSlots(), d6 = 1.2 * (this.inputProblem.viaDiameter ?? Xo(e50).padDiameter);
this.meshNodes = [...c6.flatMap((e53) => r9({ componentId: n6, bgaGap: e53, freeLayers: s6, multiLayerThreshold: d6 })), ...l6.flatMap((e53) => r9({ componentId: n6, bgaGap: e53, freeLayers: s6, multiLayerThreshold: d6 })), ...h6.flatMap((e53) => function(e54) {
const { componentId: t7, missingBgaSlot: n7, freeLayers: o7, multiLayerThreshold: i7 } = e54, r7 = i9({ componentId: t7, orientationKey: "missing", row: n7.row, col: n7.col, center: n7.center, width: n7.width, height: n7.height });
return n7.width > i7 && n7.height > i7 ? [{ center: n7.center, width: n7.width, height: n7.height, availableZ: [...o7], capacityMeshNodeId: `${r7}_all`, layer: "" }] : o7.map((e55) => ({ center: n7.center, width: n7.width, height: n7.height, availableZ: [e55], capacityMeshNodeId: `${r7}_${e55}`, layer: "" }));
}({ componentId: n6, missingBgaSlot: e53, freeLayers: s6, multiLayerThreshold: d6 })), ...o6.flatMap((t7) => [...s9({ componentId: n6, obstacle: t7, freeLayers: s6, layerCount: e50.layerCount }), a9(n6, t7, e50)]), ...i6.flatMap((t7) => [a9(n6, t7, e50)])], this.meshNodes = function(e53) {
const t7 = new Map;
return e53.map((e54) => {
const n7 = t7.get(e54.capacityMeshNodeId) ?? 0;
return t7.set(e54.capacityMeshNodeId, n7 + 1), n7 === 0 ? e54 : { ...e54, capacityMeshNodeId: `${e54.capacityMeshNodeId}__dup${n7}` };
});
}(this.meshNodes), this.solved = true;
}
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((e50) => ({ center: e50.center, width: e50.width, height: e50.height, fill: "rgba(255,0,0,0.18)", stroke: "rgba(255,0,0,0.52)", label: `pad ${e50.obstacleId ?? "obstacle"}` })), ...this.inputProblem.unmarkedComponentObstacles.map((e50) => ({ center: e50.center, width: e50.width, height: e50.height, fill: "rgba(255,140,0,0.14)", stroke: "rgba(255,140,0,0.42)", label: `foreign ${e50.obstacleId ?? "obstacle"}` })), ...this.meshNodes.map((e50) => ({ ...mF(e50, { rectMargin: 0.01 }), fill: e50._containsObstacle ? "rgba(255,0,0,0.14)" : e50.capacityMeshNodeId.includes("missing") ? "rgba(0,200,120,0.18)" : "rgba(0,120,255,0.12)", stroke: e50._containsObstacle ? "rgba(255,0,0,0.36)" : e50.capacityMeshNodeId.includes("missing") ? "rgba(0,200,120,0.52)" : "rgba(0,120,255,0.38)" }))] };
}
};
function l9(e50) {
return e50.capacityMeshNodeId.startsWith("bga-gapfill-");
}
function h9(e50) {
return JSON.stringify({ availableZ: [...e50.availableZ].sort((e53, t6) => e53 - t6), _containsTarget: e50._containsTarget ?? false, _targetConnectionName: e50._targetConnectionName ?? null, _depth: e50._depth ?? null, _strawNode: e50._strawNode ?? false, _strawParentCapacityMeshNodeId: e50._strawParentCapacityMeshNodeId ?? null, _qfpRegionType: e50._qfpRegionType ?? null, _isNarrowQfpPadGap: e50._isNarrowQfpPadGap ?? false, _soicRegionType: e50._soicRegionType ?? null, _offBoardConnectionId: e50._offBoardConnectionId ?? null, _offboardNetName: e50._offboardNetName ?? null, _isVirtualOffboard: e50._isVirtualOffboard ?? false, _containsObstacle: e50._containsObstacle ?? false });
}
function d9(e50, t6) {
const n6 = Vt(e50);
for (const o6 of t6) {
if (!e50.availableZ.some((e53) => o6.availableZ.includes(e53)))
continue;
const t7 = Vt(o6);
if (Wt(n6, t7))
return true;
}
return false;
}
function u9(e50) {
const t6 = e50[0];
if (!t6)
throw new Error("createMergedNode requires at least one source node");
let { POSITIVE_INFINITY: n6, NEGATIVE_INFINITY: o6, POSITIVE_INFINITY: i6, NEGATIVE_INFINITY: r6 } = Number;
for (const t7 of e50) {
const e53 = Vt(t7);
n6 = Math.min(n6, e53.minX), o6 = Math.max(o6, e53.maxX), i6 = Math.min(i6, e53.minY), r6 = Math.max(r6, e53.maxY);
}
return { ...t6, capacityMeshNodeId: `merge:${e50.map((e53) => e53.capacityMeshNodeId).join(":")}`, center: { x: (n6 + o6) / 2, y: (i6 + r6) / 2 }, width: o6 - n6, height: r6 - i6 };
}
function p9(e50, t6, n6) {
return { center: e50.center, width: e50.width, height: e50.height, fill: t6, stroke: t6, label: n6 };
}
var m9 = class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
inputProblem;
obstacleNodes = [];
passthroughNodes = [];
mergedNodes = [];
pendingGroups = [];
totalGroupCount = 0;
processedGroupCount = 0;
debugFilteredNodes = [];
debugMergeEvents = [];
currentGroupKey = null;
currentRootNodeId = null;
lastMergedNodeId = null;
_setup() {
this.obstacleNodes = this.inputProblem.meshNodes.filter((e53) => e53._containsObstacle === true), 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 e50 = new Map;
for (const t6 of this.inputProblem.meshNodes) {
if (t6._containsObstacle === true) {
this.passthroughNodes.push(t6), this.debugFilteredNodes.push({ type: "preserved-obstacle", node: t6, reason: "contains-obstacle" });
continue;
}
if (l9(t6)) {
this.passthroughNodes.push(t6);
continue;
}
if (t6.availableZ.length !== this.inputProblem.layerCount) {
this.passthroughNodes.push(t6);
continue;
}
let n6 = false;
for (let e53 = 0;e53 < this.inputProblem.layerCount; e53 += 1)
if (!t6.availableZ.includes(e53)) {
n6 = true;
break;
}
if (n6) {
this.passthroughNodes.push(t6);
continue;
}
if (d9(t6, this.obstacleNodes)) {
this.passthroughNodes.push(t6), this.debugFilteredNodes.push({ type: "preserved-overlap", node: t6, reason: "overlaps-obstacle" });
continue;
}
const o6 = h9(t6), i6 = e50.get(o6);
i6 ? i6.push(t6) : e50.set(o6, [t6]);
}
for (const [t6, n6] of e50.entries())
n6.length <= 1 ? this.passthroughNodes.push(...n6) : this.pendingGroups.push({ groupKey: t6, nodes: n6 });
this.pendingGroups.sort((e53, t6) => t6.nodes.length - e53.nodes.length), this.totalGroupCount = this.pendingGroups.length, this.updateStats("setup");
}
_step() {
const e50 = this.pendingGroups.shift();
if (!e50)
return this.currentGroupKey = null, this.currentRootNodeId = null, this.solved = true, void this.updateStats("done");
const t6 = e50.nodes[0];
this.currentGroupKey = e50.groupKey, this.currentRootNodeId = t6 ? t6.capacityMeshNodeId : null;
const n6 = function(e53) {
if (!e53.nodes[0])
return { outputNodes: [], mergeEvents: [] };
let { POSITIVE_INFINITY: t7, POSITIVE_INFINITY: n7, POSITIVE_INFINITY: o7, POSITIVE_INFINITY: i6 } = Number;
for (const r7 of e53.nodes) {
t7 = Math.min(t7, r7.width), n7 = Math.min(n7, r7.height);
const e54 = Vt(r7);
o7 = Math.min(o7, e54.minX), i6 = Math.min(i6, e54.minY);
}
const r6 = new Map, s6 = [];
for (const a7 of e53.nodes) {
const e54 = Vt(a7), c7 = Math.round((e54.minX - o7) / t7), l7 = Math.round((e54.minY - i6) / n7), h6 = Math.max(1, Math.round(a7.width / t7)), d6 = Math.max(1, Math.round(a7.height / n7));
for (let e55 = 0;e55 < d6; e55 += 1)
for (let t8 = 0;t8 < h6; t8 += 1)
r6.set(`${c7 + t8},${l7 + e55}`, a7);
s6.push({ col: c7, row: l7 });
}
s6.sort((e54, t8) => e54.row - t8.row || e54.col - t8.col);
const a6 = new Set, c6 = [], l6 = [];
for (const o8 of s6) {
const i7 = `${o8.col},${o8.row}`;
if (a6.has(i7))
continue;
let s7 = 0;
for (;; ) {
const e54 = `${o8.col + s7},${o8.row}`;
if (!r6.has(e54))
break;
if (a6.has(e54))
break;
s7 += 1;
}
let h6 = s7, d6 = 1, u6 = 1, p6 = 1;
for (let e54 = 1;; e54 += 1) {
const i8 = o8.row + e54 - 1;
let s8 = 0;
for (;s8 < h6; ) {
const e55 = `${o8.col + s8},${i8}`;
if (!r6.has(e55))
break;
if (a6.has(e55))
break;
s8 += 1;
}
if (s8 === 0)
break;
h6 = Math.min(h6, s8);
for (let o10 = h6;o10 >= 1; o10 -= 1) {
const i10 = o10 * t7, r7 = e54 * n7, s10 = Math.min(i10, r7);
if ((s10 <= 0.000001 ? Number.POSITIVE_INFINITY : Math.max(i10, r7) / s10) > 4)
continue;
const a7 = o10 * e54;
a7 > p6 && (p6 = a7, d6 = o10, u6 = e54);
break;
}
}
const m6 = new Map;
for (let e54 = 0;e54 < u6; e54 += 1)
for (let t8 = 0;t8 < d6; t8 += 1) {
const n8 = `${o8.col + t8},${o8.row + e54}`, i8 = r6.get(n8);
i8 && (a6.add(n8), m6.set(i8.capacityMeshNodeId, i8));
}
const g6 = [...m6.values()];
if (g6.length <= 1) {
const e54 = g6[0];
e54 && c6.push(e54);
continue;
}
const f6 = u9(g6);
c6.push(f6), l6.push({ type: "merge", groupKey: e53.groupKey, sourceNodes: g6, mergedNode: f6 });
}
return { outputNodes: c6, mergeEvents: l6 };
}(e50);
this.mergedNodes.push(...n6.outputNodes), this.processedGroupCount += 1, this.debugMergeEvents.push(...n6.mergeEvents);
const o6 = n6.mergeEvents[n6.mergeEvents.length - 1];
o6 && (this.lastMergedNodeId = o6.mergedNode.capacityMeshNodeId), this.updateStats(n6.mergeEvents.length > 0 ? "merged-group" : "passthrough-group");
}
computeProgress() {
return this.totalGroupCount === 0 ? 1 : this.processedGroupCount / this.totalGroupCount;
}
updateStats(e50) {
const t6 = new Set(this.debugMergeEvents.map((e53) => e53.groupKey)), n6 = { lastAction: e50, totalGroupCount: this.totalGroupCount, processedGroupCount: this.processedGroupCount, pendingGroupCount: this.pendingGroups.length, mergedNodeCount: this.mergedNodes.length, passthroughNodeCount: this.passthroughNodes.length, gapFillNodeCount: this.passthroughNodes.filter(l9).length, preservedObstacleNodeCount: this.debugFilteredNodes.filter((e53) => e53.type === "preserved-obstacle").length, preservedOverlapNodeCount: this.debugFilteredNodes.filter((e53) => e53.type === "preserved-overlap").length, mergeCount: this.debugMergeEvents.length, mergedGroupCount: t6.size, currentGroupKey: this.currentGroupKey, currentRootNodeId: this.currentRootNodeId, lastMergedNodeId: this.lastMergedNodeId };
this.stats = n6;
}
getConstructorParams() {
return [this.inputProblem];
}
getOutput() {
return [...this.mergedNodes, ...this.passthroughNodes];
}
visualize() {
const e50 = this.getOutput(), t6 = this.currentRootNodeId ? e50.find((e53) => e53.capacityMeshNodeId === this.currentRootNodeId) ?? null : null, n6 = this.lastMergedNodeId ? e50.find((e53) => e53.capacityMeshNodeId === this.lastMergedNodeId) ?? null : null;
return { rects: [...this.debugFilteredNodes.map((e53) => p9(e53.node, e53.type === "preserved-obstacle" ? "rgba(255,64,64,0.35)" : "rgba(255,160,64,0.35)", e53.reason)), ...this.passthroughNodes.map((e53) => p9(e53, e53._containsObstacle ? "rgba(255,0,0,0.35)" : l9(e53) ? "rgba(0,120,255,0.18)" : "rgba(160,160,160,0.12)")), ...this.mergedNodes.map((e53) => p9(e53, "rgba(120,120,120,0.14)")), ...t6 ? [p9(t6, "rgba(255,215,0,0.35)", "active-group")] : [], ...n6 ? [p9(n6, "rgba(0,200,120,0.28)", "merged")] : []] };
}
};
var g9 = class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
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 = true);
const e50 = this.obstacleQueue[this.obstacleQueueIndex], t6 = e50.layers.map((e53) => go(e53, this.inputProblem.layerCount)), n6 = [];
for (const o6 of this.meshNodes) {
if (o6._containsObstacle) {
n6.push(o6);
continue;
}
if (!t6.some((e53) => o6.availableZ.includes(e53))) {
n6.push(o6);
continue;
}
if (!Wt(Vt(o6), Vt(e50))) {
n6.push(o6);
continue;
}
if (o6.availableZ.length === 1)
continue;
const i6 = o6.availableZ.filter((e53) => !t6.includes(e53));
for (const e53 of i6) {
const t7 = { ...o6, capacityMeshNodeId: `${o6.capacityMeshNodeId}:z${e53}`, availableZ: [e53], layer: `z${e53}` };
n6.push(t7);
}
}
this.meshNodes = n6, this.obstacleQueueIndex += 1, this.stats = { obstaclesProcessed: this.obstacleQueueIndex, obstacleCount: this.obstacleQueue.length, meshNodeCount: this.meshNodes.length };
}
computeProgress() {
return this.obstacleQueue.length === 0 ? 1 : this.obstacleQueueIndex / this.obstacleQueue.length;
}
getConstructorParams() {
return [this.inputProblem];
}
getOutput() {
return this.meshNodes;
}
visualize() {
const e50 = this.obstacleQueueIndex < this.obstacleQueue.length ? this.obstacleQueue[this.obstacleQueueIndex] ?? null : null, t6 = this.obstacleQueue.slice(0, this.obstacleQueueIndex), n6 = e50 ? this.obstacleQueue.slice(this.obstacleQueueIndex + 1) : [];
return { rects: [...t6.map((e53) => ({ center: e53.center, width: e53.width, height: e53.height, fill: "rgba(160,160,160,0.10)", stroke: "rgba(160,160,160,0.35)", label: `processed ${e53.obstacleId ?? "obstacle"}` })), ...e50 ? [{ center: e50.center, width: e50.width, height: e50.height, fill: "rgba(255,140,0,0.22)", stroke: "rgba(255,140,0,0.75)", label: `active ${e50.obstacleId ?? "obstacle"}` }] : [], ...n6.map((e53) => ({ center: e53.center, width: e53.width, height: e53.height, fill: "rgba(255,0,0,0.05)", stroke: "rgba(255,0,0,0.22)", label: `pending ${e53.obstacleId ?? "obstacle"}` })), ...this.meshNodes.map((e53) => ({ ...mF(e53, { rectMargin: 0.01 }), fill: e53._containsObstacle ? "rgba(255,0,0,0.18)" : "rgba(0,120,255,0.12)", stroke: e53._containsObstacle ? "rgba(255,0,0,0.45)" : "rgba(0,120,255,0.45)" }))] };
}
};
R4.register(class extends ze {
constructor(e50) {
super(e50), this.inputProblem = e50;
}
inputProblem;
static componentKind = "bga";
initialTopologySolver;
removeMeshNodeOverlappingWithUnmarkedObstacle;
gapfillDueToNodeRemoval;
mergeMeshNodes;
markedComponentObstacles = [];
unmarkedComponentObstacles = [];
pipelineDef = [Le("initialTopologySolver", c9, (e50) => [{ srj: e50.inputProblem.inputSrj, componentBounds: e50.inputProblem.detectedComponent.bounds, componentId: e50.inputProblem.detectedComponent.componentId, markedComponentObstacles: e50.markedComponentObstacles, unmarkedComponentObstacles: e50.unmarkedComponentObstacles, viaDiameter: e50.inputProblem.viaDiameter }]), Le("removeMeshNodeOverlappingWithUnmarkedObstacle", g9, (e50) => [{ meshNodes: e50.initialTopologySolver.getOutput(), obstacles: e50.unmarkedComponentObstacles, layerCount: e50.inputProblem.inputSrj.layerCount }]), Le("gapfillDueToNodeRemoval", Z4, (e50) => [{ meshNodes: e50.removeMeshNodeOverlappingWithUnmarkedObstacle.getOutput(), unmarkedComponentObstacles: e50.unmarkedComponentObstacles, layerCount: e50.inputProblem.inputSrj.layerCount }]), Le("mergeMeshNodes", m9, (e50) => [{ meshNodes: e50.gapfillDueToNodeRemoval.getOutput(), layerCount: e50.inputProblem.inputSrj.layerCount }])];
_setup() {
const e50 = this.inputProblem.detectedComponent.bounds, t6 = this.inputProblem.detectedComponent.componentId, n6 = [], o6 = [];
for (const i6 of this.inputProblem.inputSrj.obstacles) {
const r6 = Vt(i6);
Wt(e50, r6) && (i6.componentId !== t6 ? o6.push(i6) : n6.push(i6));
}
this.markedComponentObstacles = n6, this.unmarkedComponentObstacles = o6;
}
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((e50) => ({ center: e50.center, width: e50.width, height: e50.height, fill: "rgba(255,0,0,0.18)", stroke: "rgba(255,0,0,0.52)", label: `pad ${e50.obstacleId ?? "obstacle"}` })), ...this.unmarkedComponentObstacles.map((e50) => ({ center: e50.center, width: e50.width, height: e50.height, fill: "rgba(255,140,0,0.14)", stroke: "rgba(255,140,0,0.42)", label: `foreign ${e50.obstacleId ?? "obstacle"}` }))] };
}
finalVisualize() {
return { rects: this.getOutput().routingRegions.map((e50) => ({ ...mF(e50, { rectMargin: 0.01 }), fill: e50._containsObstacle ? "rgba(255,0,0,0.16)" : "rgba(0,120,255,0.12)", stroke: e50._containsObstacle ? "rgba(255,0,0,0.36)" : "rgba(0,120,255,0.42)" })) };
}
});
var f9 = 0.000001;
function _9(e50, t6) {
return e50.__zLayers && e50.__zLayers.length > 0 ? fo(e50.__zLayers, t6) : _o(e50.layers, t6);
}
function y9(e50) {
const t6 = [...e50].sort((e53, t7) => e53 - t7), n6 = [];
for (let e53 = 1;e53 < t6.length; e53++) {
const o7 = t6[e53] - t6[e53 - 1];
o7 > f9 && n6.push(o7);
}
const o6 = n6.length > 0 ? Math.max(f9, Math.min(...n6) / 4) : 0.001, i6 = [];
for (const e53 of t6) {
const t7 = i6[i6.length - 1];
(t7 === undefined || Math.abs(e53 - t7) > o6) && i6.push(e53);
}
return i6;
}
function b9(e50) {
return Array.from({ length: Math.max(0, e50) }, (e53, t6) => t6);
}
var x9 = 0.000001;
function v9(e50) {
return e50.maxX - e50.minX > x9 && e50.maxY - e50.minY > x9;
}
function I9(e50) {
return function(e53) {
const t6 = Math.min(e53.width, e53.height), n6 = Math.max(e53.width, e53.height);
return t6 <= 0 ? 0 : n6 / t6;
}(e50) >= 1.5;
}
function S9(e50, t6) {
const n6 = [{ side: "top", distance: Math.abs(e50.center.y - t6.minY) }, { side: "right", distance: Math.abs(t6.maxX - e50.center.x) }, { side: "bottom", distance: Math.abs(t6.maxY - e50.center.y) }, { side: "left", distance: Math.abs(e50.center.x - t6.minX) }];
return n6.sort((e53, t7) => e53.distance - t7.distance), n6[0].side;
}
function C9(e50, t6) {
return e50.map((e53, n6) => ({ key: `pad:${e53.obstacleId ?? n6}`, bounds: At(e53), regionType: "pad", obstacleZ: _9(e53, t6) }));
}
function P9(e50, t6) {
return e50.map((e53, n6) => ({ key: `thermal-pad:${e53.obstacleId ?? n6}`, bounds: At(e53), regionType: "pad", obstacleZ: _9(e53, t6) }));
}
function M9(e50, t6) {
return !!v9(e50) && Math.min(e50.maxX - e50.minX, e50.maxY - e50.minY) <= t6;
}
function w9({ side: e50, sideObstacles: t6, bounds: n6, innerBounds: o6, narrowThreshold: i6 }) {
const r6 = [];
for (let s6 = 0;s6 < t6.length - 1; s6++) {
const a6 = At(t6[s6]), c6 = At(t6[s6 + 1]);
let l6;
l6 = e50 === "top" ? { minX: a6.maxX, maxX: c6.minX, minY: n6.minY, maxY: o6.minY } : e50 === "right" ? { minX: o6.maxX, maxX: n6.maxX, minY: a6.maxY, maxY: c6.minY } : e50 === "bottom" ? { minX: a6.maxX, maxX: c6.minX, minY: o6.maxY, maxY: n6.maxY } : { minX: n6.minX, maxX: o6.minX, minY: a6.maxY, maxY: c6.minY }, r6.push({ key: `${e50}-gap-${s6}`, bounds: l6, regionType: "pad-gap", isNarrowPadGap: M9(l6, i6) });
}
return r6;
}
function N9({ side: e50, sideObstacles: t6, thermalPadBounds: n6, narrowThreshold: o6 }) {
const i6 = [];
for (let r6 = 0;r6 < t6.length; r6++) {
const s6 = At(t6[r6]), a6 = t6[r6 - 1] ? At(t6[r6 - 1]) : null, c6 = t6[r6 + 1] ? At(t6[r6 + 1]) : null;
let l6;
l6 = e50 === "top" ? { minX: a6 ? (a6.maxX + s6.minX) / 2 : s6.minX, maxX: c6 ? (s6.maxX + c6.minX) / 2 : s6.maxX, minY: s6.maxY, maxY: n6.minY } : e50 === "right" ? { minX: n6.maxX, maxX: s6.minX, minY: a6 ? (a6.maxY + s6.minY) / 2 : s6.minY, maxY: c6 ? (s6.maxY + c6.minY) / 2 : s6.maxY } : e50 === "bottom" ? { minX: a6 ? (a6.maxX + s6.minX) / 2 : s6.minX, maxX: c6 ? (s6.maxX + c6.minX) / 2 : s6.maxX, minY: n6.maxY, maxY: s6.minY } : { minX: s6.maxX, maxX: n6.minX, minY: a6 ? (a6.maxY + s6.minY) / 2 : s6.minY, maxY: c6 ? (s6.maxY + c6.minY) / 2 : s6.maxY }, i6.push({ key: `inner-${e50}-pad-${r6}`, bounds: l6, regionType: "pad-gap", isNarrowPadGap: M9(l6, o6) });
}
return i6;
}
function T9({ bounds: e50, innerBounds: t6, sideGroups: n6 }) {
const o6 = n6.top[0] ? At(n6.top[0]) : null, i6 = n6.top.at(-1) ? At(n6.top.at(-1)) : null, r6 = n6.right[0] ? At(n6.right[0]) : null, s6 = n6.right.at(-1) ? At(n6.right.at(-1)) : null, a6 = n6.bottom[0] ? At(n6.bottom[0]) : null, c6 = n6.bottom.at(-1) ? At(n6.bottom.at(-1)) : null, l6 = n6.left[0] ? At(n6.left[0]) : null, h6 = n6.left.at(-1) ? At(n6.left.at(-1)) : null;
return [{ key: "corner-nw-outer", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-nw-top", regionType: "corner", bounds: { minX: t6.minX, maxX: o6?.minX ?? t6.minX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-nw-left", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: t6.minY, maxY: l6?.minY ?? t6.minY } }, { key: "corner-ne-outer", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-ne-top", regionType: "corner", bounds: { minX: i6?.maxX ?? t6.maxX, maxX: t6.maxX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-ne-right", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: t6.minY, maxY: r6?.minY ?? t6.minY } }, { key: "corner-se-outer", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-se-right", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: s6?.maxY ?? t6.maxY, maxY: t6.maxY } }, { key: "corner-se-bottom", regionType: "corner", bounds: { minX: c6?.maxX ?? t6.maxX, maxX: t6.maxX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-sw-outer", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-sw-bottom", regionType: "corner", bounds: { minX: t6.minX, maxX: a6?.minX ?? t6.minX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-sw-left", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: h6?.maxY ?? t6.maxY, maxY: t6.maxY } }];
}
function R9({ innerBounds: e50, thermalPadBounds: t6, sideGroups: n6 }) {
const o6 = n6.top[0] ? At(n6.top[0]) : null, i6 = n6.top.at(-1) ? At(n6.top.at(-1)) : null, r6 = n6.right[0] ? At(n6.right[0]) : null, s6 = n6.right.at(-1) ? At(n6.right.at(-1)) : null, a6 = n6.bottom[0] ? At(n6.bottom[0]) : null, c6 = n6.bottom.at(-1) ? At(n6.bottom.at(-1)) : null, l6 = n6.left[0] ? At(n6.left[0]) : null, h6 = n6.left.at(-1) ? At(n6.left.at(-1)) : null;
return [{ key: "inner-corner-nw-core", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: e50.minY, maxY: t6.minY } }, { key: "inner-corner-nw-top", regionType: "corner", bounds: { minX: t6.minX, maxX: o6?.minX ?? t6.minX, minY: e50.minY, maxY: t6.minY } }, { key: "inner-corner-nw-left", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: t6.minY, maxY: l6?.minY ?? t6.minY } }, { key: "inner-corner-ne-core", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: e50.minY, maxY: t6.minY } }, { key: "inner-corner-ne-top", regionType: "corner", bounds: { minX: i6?.maxX ?? t6.maxX, maxX: t6.maxX, minY: e50.minY, maxY: t6.minY } }, { key: "inner-corner-ne-right", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: t6.minY, maxY: r6?.minY ?? t6.minY } }, { key: "inner-corner-se-core", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: t6.maxY, maxY: e50.maxY } }, { key: "inner-corner-se-right", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: s6?.maxY ?? t6.maxY, maxY: t6.maxY } }, { key: "inner-corner-se-bottom", regionType: "corner", bounds: { minX: c6?.maxX ?? t6.maxX, maxX: t6.maxX, minY: t6.maxY, maxY: e50.maxY } }, { key: "inner-corner-sw-core", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: t6.maxY, maxY: e50.maxY } }, { key: "inner-corner-sw-bottom", regionType: "corner", bounds: { minX: t6.minX, maxX: a6?.minX ?? t6.minX, minY: t6.maxY, maxY: e50.maxY } }, { key: "inner-corner-sw-left", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: h6?.maxY ?? t6.maxY, maxY: t6.maxY } }];
}
R4.register(class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
inputProblem;
static componentKind = "qfp_thermalpad";
output = null;
getConstructorParams() {
return [this.inputProblem];
}
_step() {
if (this.output)
return void (this.solved = true);
const { layerCount: e50, obstacles: t6 } = this.inputProblem.inputSrj, { bounds: n6, componentId: o6 } = this.inputProblem.detectedComponent, i6 = b9(e50), r6 = t6.filter((e53) => e53.componentId === o6), s6 = r6.length > 0 ? r6 : t6, { padRingObstacles: a6, thermalPadObstacles: c6 } = function(e53) {
return { padRingObstacles: e53.filter(I9), thermalPadObstacles: e53.filter((e54) => !I9(e54)) };
}(s6), l6 = function(e53, t7) {
const n7 = { top: [], right: [], bottom: [], left: [] };
for (const o7 of e53)
n7[S9(o7, t7)].push(o7);
return n7.top.sort((e54, t8) => e54.center.x - t8.center.x), n7.bottom.sort((e54, t8) => e54.center.x - t8.center.x), n7.left.sort((e54, t8) => e54.center.y - t8.center.y), n7.right.sort((e54, t8) => e54.center.y - t8.center.y), n7;
}(a6, n6), h6 = function({ bounds: e53, sideGroups: t7 }) {
return { minX: t7.left.length > 0 ? Math.max(...t7.left.map((e54) => At(e54).maxX)) : e53.minX, maxX: t7.right.length > 0 ? Math.min(...t7.right.map((e54) => At(e54).minX)) : e53.maxX, minY: t7.top.length > 0 ? Math.max(...t7.top.map((e54) => At(e54).maxY)) : e53.minY, maxY: t7.bottom.length > 0 ? Math.min(...t7.bottom.map((e54) => At(e54).minY)) : e53.maxY };
}({ bounds: n6, sideGroups: l6 }), d6 = function(e53) {
return e53.length === 0 ? null : e53.reduce((e54, t7) => {
const n7 = At(t7);
return { minX: Math.min(e54.minX, n7.minX), maxX: Math.max(e54.maxX, n7.maxX), minY: Math.min(e54.minY, n7.minY), maxY: Math.max(e54.maxY, n7.maxY) };
}, At(e53[0]));
}(c6);
if (!d6)
return this.failed = true, void (this.error = "QfpThermalPadTopologyGeneratorSolver requires a thermal pad");
const u6 = o6, p6 = this.inputProblem.viaDiameter ?? Xo(this.inputProblem.inputSrj).padDiameter, m6 = this.inputProblem.obstacleMargin ?? this.inputProblem.inputSrj.defaultObstacleMargin ?? 0.15, g6 = p6 + 2 * m6, f6 = this.inputProblem.inputSrj.minTraceWidth + 2 * m6, _6 = [...C9(a6, e50), ...P9(c6, e50), ...w9({ side: "top", sideObstacles: l6.top, bounds: n6, innerBounds: h6, narrowThreshold: f6 }), ...w9({ side: "right", sideObstacles: l6.right, bounds: n6, innerBounds: h6, narrowThreshold: f6 }), ...w9({ side: "bottom", sideObstacles: l6.bottom, bounds: n6, innerBounds: h6, narrowThreshold: f6 }), ...w9({ side: "left", sideObstacles: l6.left, bounds: n6, innerBounds: h6, narrowThreshold: f6 }), ...N9({ side: "top", sideObstacles: l6.top, thermalPadBounds: d6, narrowThreshold: f6 }), ...N9({ side: "right", sideObstacles: l6.right, thermalPadBounds: d6, narrowThreshold: f6 }), ...N9({ side: "bottom", sideObstacles: l6.bottom, thermalPadBounds: d6, narrowThreshold: f6 }), ...N9({ side: "left", sideObstacles: l6.left, thermalPadBounds: d6, narrowThreshold: f6 }), ...R9({ innerBounds: h6, thermalPadBounds: d6, sideGroups: l6 }), ...T9({ bounds: n6, innerBounds: h6, sideGroups: l6 })].flatMap((e53) => function({ nodeId: e54, bounds: t7, availableZ: n7, multiLayerThreshold: o7, regionType: i7, isNarrowPadGap: r7 = false, obstacleZ: s7 = [] }) {
if (!v9(t7))
return [];
const a7 = function(e55) {
return { center: { x: (e55.minX + e55.maxX) / 2, y: (e55.minY + e55.maxY) / 2 }, width: e55.maxX - e55.minX, height: e55.maxY - e55.minY };
}(t7), c7 = Math.min(a7.width, a7.height) > o7, l7 = c7 ? [{ availableZ: n7.filter((e55) => !s7.includes(e55)), containsObstacle: false }, { availableZ: n7.filter((e55) => s7.includes(e55)), containsObstacle: true }].filter((e55) => e55.availableZ.length > 0) : n7.map((e55) => ({ availableZ: [e55], containsObstacle: s7.includes(e55) }));
return l7.map((t8) => ({ capacityMeshNodeId: l7.length === 1 ? e54 : c7 ? `${e54}:${t8.containsObstacle ? "obstacle" : "free"}` : `${e54}:z${t8.availableZ[0]}`, center: a7.center, width: a7.width, height: a7.height, layer: `z${t8.availableZ.join(",")}`, availableZ: t8.availableZ, _qfpRegionType: i7, _isNarrowQfpPadGap: r7, _containsObstacle: t8.containsObstacle }));
}({ nodeId: `qfp_thermalpad:${u6}:${e53.key}`, bounds: e53.bounds, availableZ: i6, multiLayerThreshold: g6, regionType: e53.regionType, isNarrowPadGap: e53.isNarrowPadGap, obstacleZ: e53.obstacleZ }));
this.output = { routingRegions: _6 }, this.stats = { componentId: o6, layerCount: e50, viaDiameter: p6, obstacleMargin: m6, multiLayerThreshold: g6, narrowPadGapThreshold: f6, thermalPadCount: c6.length, perimeterPadCount: a6.length, innerCornerRectCount: _6.filter((e53) => e53.capacityMeshNodeId.includes(":inner-corner-")).length, narrowPadGapNodeCount: _6.filter((e53) => e53._isNarrowQfpPadGap).length, topPadCount: l6.top.length, rightPadCount: l6.right.length, bottomPadCount: l6.bottom.length, leftPadCount: l6.left.length, multiLayerNodeCount: _6.filter((e53) => e53.availableZ.length > 1).length, totalMeshNodeCount: _6.length }, this.solved = true;
}
getOutput() {
if (!this.output)
throw new Error("QfpThermalPadTopologyGeneratorSolver has not solved yet");
return this.output;
}
});
var E9 = 0.000001;
function A9(e50) {
return e50.maxX - e50.minX > E9 && e50.maxY - e50.minY > E9;
}
function O9(e50, t6) {
const n6 = [{ side: "top", distance: Math.abs(e50.center.y - t6.minY) }, { side: "right", distance: Math.abs(t6.maxX - e50.center.x) }, { side: "bottom", distance: Math.abs(t6.maxY - e50.center.y) }, { side: "left", distance: Math.abs(e50.center.x - t6.minX) }];
return n6.sort((e53, t7) => e53.distance - t7.distance), n6[0].side;
}
function k9(e50, t6) {
return e50.map((e53, n6) => ({ key: `pad:${e53.obstacleId ?? n6}`, bounds: At(e53), regionType: "pad", obstacleZ: _9(e53, t6), connectedTo: [...e53.connectedTo] }));
}
function D9(e50, t6) {
return !!A9(e50) && Math.min(e50.maxX - e50.minX, e50.maxY - e50.minY) <= t6;
}
function L9({ side: e50, sideObstacles: t6, bounds: n6, centralBounds: o6, narrowThreshold: i6 }) {
const r6 = [];
for (let s6 = 0;s6 < t6.length - 1; s6++) {
const a6 = At(t6[s6]), c6 = At(t6[s6 + 1]);
let l6;
l6 = e50 === "top" ? { minX: a6.maxX, maxX: c6.minX, minY: n6.minY, maxY: o6.minY } : e50 === "right" ? { minX: o6.maxX, maxX: n6.maxX, minY: a6.maxY, maxY: c6.minY } : e50 === "bottom" ? { minX: a6.maxX, maxX: c6.minX, minY: o6.maxY, maxY: n6.maxY } : { minX: n6.minX, maxX: o6.minX, minY: a6.maxY, maxY: c6.minY }, r6.push({ key: `${e50}-gap-${s6}`, bounds: l6, regionType: "pad-gap", isNarrowPadGap: D9(l6, i6) });
}
return r6;
}
function z9({ bounds: e50, centralBounds: t6, sideGroups: n6 }) {
const o6 = n6.top[0] ? At(n6.top[0]) : null, i6 = n6.top.at(-1) ? At(n6.top.at(-1)) : null, r6 = n6.right[0] ? At(n6.right[0]) : null, s6 = n6.right.at(-1) ? At(n6.right.at(-1)) : null, a6 = n6.bottom[0] ? At(n6.bottom[0]) : null, c6 = n6.bottom.at(-1) ? At(n6.bottom.at(-1)) : null, l6 = n6.left[0] ? At(n6.left[0]) : null, h6 = n6.left.at(-1) ? At(n6.left.at(-1)) : null;
return [{ key: "corner-nw-outer", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-nw-top", regionType: "corner", bounds: { minX: t6.minX, maxX: o6?.minX ?? t6.minX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-nw-left", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: t6.minY, maxY: l6?.minY ?? t6.minY } }, { key: "corner-ne-outer", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-ne-top", regionType: "corner", bounds: { minX: i6?.maxX ?? t6.maxX, maxX: t6.maxX, minY: e50.minY, maxY: t6.minY } }, { key: "corner-ne-right", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: t6.minY, maxY: r6?.minY ?? t6.minY } }, { key: "corner-se-outer", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-se-right", regionType: "corner", bounds: { minX: t6.maxX, maxX: e50.maxX, minY: s6?.maxY ?? t6.maxY, maxY: t6.maxY } }, { key: "corner-se-bottom", regionType: "corner", bounds: { minX: c6?.maxX ?? t6.maxX, maxX: t6.maxX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-sw-outer", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-sw-bottom", regionType: "corner", bounds: { minX: t6.minX, maxX: a6?.minX ?? t6.minX, minY: t6.maxY, maxY: e50.maxY } }, { key: "corner-sw-left", regionType: "corner", bounds: { minX: e50.minX, maxX: t6.minX, minY: h6?.maxY ?? t6.maxY, maxY: t6.maxY } }];
}
R4.register(class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
inputProblem;
static componentKind = "qfp";
output = null;
getConstructorParams() {
return [this.inputProblem];
}
_step() {
if (this.output)
return void (this.solved = true);
const { layerCount: e50, obstacles: t6 } = this.inputProblem.inputSrj, { bounds: n6, componentId: o6 } = this.inputProblem.detectedComponent, i6 = b9(e50), r6 = t6.filter((e53) => e53.componentId === o6), s6 = r6.length > 0 ? r6 : t6, a6 = function(e53, t7) {
const n7 = { top: [], right: [], bottom: [], left: [] };
for (const o7 of e53)
n7[O9(o7, t7)].push(o7);
return n7.top.sort((e54, t8) => e54.center.x - t8.center.x), n7.bottom.sort((e54, t8) => e54.center.x - t8.center.x), n7.left.sort((e54, t8) => e54.center.y - t8.center.y), n7.right.sort((e54, t8) => e54.center.y - t8.center.y), n7;
}(s6, n6), c6 = function({ bounds: e53, sideGroups: t7 }) {
return { minX: t7.left.length > 0 ? Math.max(...t7.left.map((e54) => At(e54).maxX)) : e53.minX, maxX: t7.right.length > 0 ? Math.min(...t7.right.map((e54) => At(e54).minX)) : e53.maxX, minY: t7.top.length > 0 ? Math.max(...t7.top.map((e54) => At(e54).maxY)) : e53.minY, maxY: t7.bottom.length > 0 ? Math.min(...t7.bottom.map((e54) => At(e54).minY)) : e53.maxY };
}({ bounds: n6, sideGroups: a6 }), l6 = o6, h6 = this.inputProblem.viaDiameter ?? Xo(this.inputProblem.inputSrj).padDiameter, d6 = this.inputProblem.obstacleMargin ?? this.inputProblem.inputSrj.defaultObstacleMargin ?? 0.15, u6 = h6 + 2 * d6, p6 = this.inputProblem.inputSrj.minTraceWidth + 2 * d6, m6 = [{ key: "center", bounds: c6, regionType: "center" }, ...k9(s6, e50), ...L9({ side: "top", sideObstacles: a6.top, bounds: n6, centralBounds: c6, narrowThreshold: p6 }), ...L9({ side: "right", sideObstacles: a6.right, bounds: n6, centralBounds: c6, narrowThreshold: p6 }), ...L9({ side: "bottom", sideObstacles: a6.bottom, bounds: n6, centralBounds: c6, narrowThreshold: p6 }), ...L9({ side: "left", sideObstacles: a6.left, bounds: n6, centralBounds: c6, narrowThreshold: p6 }), ...z9({ bounds: n6, centralBounds: c6, sideGroups: a6 })].flatMap((e53) => function({ nodeId: e54, bounds: t7, availableZ: n7, multiLayerThreshold: o7, regionType: i7, isNarrowPadGap: r7 = false, obstacleZ: s7 = [], connectedTo: a7 }) {
if (!A9(t7))
return [];
const c7 = function(e55) {
return { center: { x: (e55.minX + e55.maxX) / 2, y: (e55.minY + e55.maxY) / 2 }, width: e55.maxX - e55.minX, height: e55.maxY - e55.minY };
}(t7), l7 = Math.min(c7.width, c7.height) > o7, h7 = l7 ? [{ availableZ: n7.filter((e55) => !s7.includes(e55)), containsObstacle: false }, { availableZ: n7.filter((e55) => s7.includes(e55)), containsObstacle: true }].filter((e55) => e55.availableZ.length > 0) : n7.map((e55) => ({ availableZ: [e55], containsObstacle: s7.includes(e55) }));
return h7.map((t8) => ({ capacityMeshNodeId: h7.length === 1 ? e54 : l7 ? `${e54}:${t8.containsObstacle ? "obstacle" : "free"}` : `${e54}:z${t8.availableZ[0]}`, center: c7.center, width: c7.width, height: c7.height, layer: `z${t8.availableZ.join(",")}`, availableZ: t8.availableZ, _qfpRegionType: i7, _isNarrowQfpPadGap: r7, _containsObstacle: t8.containsObstacle, _connectedTo: t8.containsObstacle ? a7 : undefined }));
}({ nodeId: `qfp:${l6}:${e53.key}`, bounds: e53.bounds, availableZ: i6, multiLayerThreshold: u6, regionType: e53.regionType, isNarrowPadGap: e53.isNarrowPadGap, obstacleZ: e53.obstacleZ, connectedTo: e53.connectedTo }));
this.output = { routingRegions: m6 }, this.stats = { componentId: o6, layerCount: e50, viaDiameter: h6, obstacleMargin: d6, multiLayerThreshold: u6, narrowPadGapThreshold: p6, narrowPadGapNodeCount: m6.filter((e53) => e53._isNarrowQfpPadGap).length, topPadCount: a6.top.length, rightPadCount: a6.right.length, bottomPadCount: a6.bottom.length, leftPadCount: a6.left.length, multiLayerNodeCount: m6.filter((e53) => e53.availableZ.length > 1).length, totalMeshNodeCount: m6.length }, this.solved = true;
}
getOutput() {
if (!this.output)
throw new Error("QfpTopologyGeneratorSolver has not solved yet");
return this.output;
}
});
var B9 = 0.000001;
function F9({ nodeId: e50, bounds: t6, availableZ: n6, multiLayerThreshold: o6, regionType: i6, obstacleZ: r6 = [], connectedTo: s6 }) {
if (!function(e53) {
return e53.maxX - e53.minX > B9 && e53.maxY - e53.minY > B9;
}(t6))
return [];
const a6 = function(e53) {
return { center: { x: (e53.minX + e53.maxX) / 2, y: (e53.minY + e53.maxY) / 2 }, width: e53.maxX - e53.minX, height: e53.maxY - e53.minY };
}(t6), c6 = Math.min(a6.width, a6.height) > o6, l6 = c6 ? [{ availableZ: n6.filter((e53) => !r6.includes(e53)), containsObstacle: false }, { availableZ: n6.filter((e53) => r6.includes(e53)), containsObstacle: true }].filter((e53) => e53.availableZ.length > 0) : n6.map((e53) => ({ availableZ: [e53], containsObstacle: r6.includes(e53) }));
return l6.map((t7) => ({ capacityMeshNodeId: l6.length === 1 ? e50 : c6 ? `${e50}:${t7.containsObstacle ? "obstacle" : "free"}` : `${e50}:z${t7.availableZ[0]}`, center: a6.center, width: a6.width, height: a6.height, layer: `z${t7.availableZ.join(",")}`, availableZ: t7.availableZ, _soicRegionType: i6, _containsObstacle: t7.containsObstacle, _connectedTo: t7.containsObstacle ? s6 : undefined }));
}
function j9(e50, t6) {
let n6 = 0, o6 = Number.POSITIVE_INFINITY;
for (let i6 = 0;i6 < t6.length; i6++) {
const r6 = Math.abs(e50 - t6[i6]);
r6 < o6 && (n6 = i6, o6 = r6);
}
return n6;
}
function $9(e50, t6) {
return e50.map((e53, n6) => ({ key: `pad:${e53.obstacleId ?? n6}`, bounds: At(e53), regionType: "pad", obstacleZ: _9(e53, t6), connectedTo: [...e53.connectedTo] }));
}
function Y9(e50, t6) {
if (e50.componentId !== t6.componentId)
return false;
const { bounds: n6 } = t6;
return e50.center.x >= n6.minX && e50.center.x <= n6.maxX && e50.center.y >= n6.minY && e50.center.y <= n6.maxY;
}
function X9({ detectedComponent: e50, inputSrj: t6 }) {
const n6 = t6.obstacles.filter((t7) => Y9(t7, e50)), o6 = Array.from({ length: t6.layerCount }, (e53, t7) => t7), i6 = o6.map((e53) => Po(e53, t6.layerCount)), r6 = Array.from(new Set(n6.flatMap((e53) => e53.connectedTo))), { bounds: s6 } = e50;
return { obstacleId: `${e50.componentId}_component_bounds`, componentId: e50.componentId, type: "rect", layers: i6, __zLayers: o6, center: { x: (s6.minX + s6.maxX) / 2, y: (s6.minY + s6.maxY) / 2 }, width: s6.maxX - s6.minX, height: s6.maxY - s6.minY, connectedTo: r6 };
}
function W9(e50) {
if (e50.length === 0)
return { minX: 0, maxX: 0, minY: 0, maxY: 0 };
let { POSITIVE_INFINITY: t6, NEGATIVE_INFINITY: n6, POSITIVE_INFINITY: o6, NEGATIVE_INFINITY: i6 } = Number;
for (const r6 of e50) {
const e53 = At(r6);
t6 = Math.min(t6, e53.minX), n6 = Math.max(n6, e53.maxX), o6 = Math.min(o6, e53.minY), i6 = Math.max(i6, e53.maxY);
}
return { minX: t6, maxX: n6, minY: o6, maxY: i6 };
}
function V9(e50) {
const t6 = e50.componentDetectionOutput ?? [], n6 = function({ detectedComponents: e53, inputSrj: t7 }) {
return e53.map((e54) => {
const n7 = t7.obstacles.filter((t8) => Y9(t8, e54));
return { componentId: e54.componentId, componentKind: e54.componentKind, memberObstacleIds: n7.map((t8, n8) => t8.obstacleId ?? `${e54.componentId}:member:${n8}`), memberObstacles: n7, replacementObstacle: X9({ detectedComponent: e54, inputSrj: t7 }) };
});
}({ detectedComponents: t6, inputSrj: e50.inputSrj }), o6 = e50.globalNoConnectionSrj ?? (t6.length > 0 ? function({ detectedComponents: e53, inputSrj: t7 }) {
return { ...structuredClone(t7), obstacles: [...t7.obstacles.filter((t8) => !e53.some((e54) => Y9(t8, e54))), ...e53.map((e54) => X9({ detectedComponent: e54, inputSrj: t7 }))] };
}({ detectedComponents: t6, inputSrj: e50.inputSrj }) : e50.inputSrj) ?? e50.brokenSrj?.componentsAsObstaclesSrj, i6 = e50.components ?? n6 ?? e50.brokenSrj?.components ?? [];
if (!o6)
throw new Error("MultiGraphTopologyPlannerSolver requires globalNoConnectionSrj or detected components");
return { globalNoConnectionSrj: o6, components: i6 };
}
function H9({ rects: e50, components: t6 }) {
return e50 && t6.length !== 0 ? e50.filter((e53) => !function(e54) {
return typeof e54.label == "string" && e54.label.startsWith("node ");
}(e53) || !t6.some((t7) => function({ rect: e54, obstacle: t8 }) {
if (!e54.center || e54.width === undefined || e54.height === undefined)
return false;
const n6 = 0.000000001, o6 = Vt({ center: e54.center, width: e54.width, height: e54.height }), i6 = Vt({ center: t8.center, width: t8.width, height: t8.height });
return G9({ bounds: o6, outerBounds: i6, epsilon: n6 });
}({ rect: e53, obstacle: t7.replacementObstacle }))) : e50;
}
function G9({ bounds: e50, outerBounds: t6, epsilon: n6 }) {
return e50.minX >= t6.minX - n6 && e50.maxX <= t6.maxX + n6 && e50.minY >= t6.minY - n6 && e50.maxY <= t6.maxY + n6;
}
R4.register(class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
inputProblem;
static componentKind = "soic";
output = null;
getConstructorParams() {
return [this.inputProblem];
}
_step() {
if (this.output)
return void (this.solved = true);
const { layerCount: e50, obstacles: t6 } = this.inputProblem.inputSrj, { bounds: n6, componentId: o6 } = this.inputProblem.detectedComponent, i6 = b9(e50), r6 = t6.filter((e53) => e53.componentId === o6), s6 = r6.length > 0 ? r6 : t6, a6 = function(e53) {
const t7 = y9(e53.map((e54) => e54.center.y)).length;
return y9(e53.map((e54) => e54.center.x)).length === 2 && t7 !== 2 ? "vertical-columns" : "horizontal-rows";
}(s6), c6 = function({ obstacles: e53, orientation: t7 }) {
const n7 = { left: [], right: [], top: [], bottom: [] };
if (t7 === "vertical-columns") {
const t8 = y9(e53.map((e54) => e54.center.x));
for (const o8 of e53)
n7[j9(o8.center.x, t8) === 0 ? "left" : "right"].push(o8);
return n7.left.sort((e54, t10) => e54.center.y - t10.center.y), n7.right.sort((e54, t10) => e54.center.y - t10.center.y), n7;
}
const o7 = y9(e53.map((e54) => e54.center.y));
for (const t8 of e53)
n7[j9(t8.center.y, o7) === 0 ? "top" : "bottom"].push(t8);
return n7.top.sort((e54, t8) => e54.center.x - t8.center.x), n7.bottom.sort((e54, t8) => e54.center.x - t8.center.x), n7;
}({ obstacles: s6, orientation: a6 }), l6 = function({ bounds: e53, orientation: t7, sideGroups: n7 }) {
return t7 === "vertical-columns" ? { minX: Math.max(...n7.left.map((e54) => At(e54).maxX)), maxX: Math.min(...n7.right.map((e54) => At(e54).minX)), minY: e53.minY, maxY: e53.maxY } : { minX: e53.minX, maxX: e53.maxX, minY: Math.max(...n7.top.map((e54) => At(e54).maxY)), maxY: Math.min(...n7.bottom.map((e54) => At(e54).minY)) };
}({ bounds: n6, orientation: a6, sideGroups: c6 }), h6 = o6, d6 = this.inputProblem.viaDiameter ?? Xo(this.inputProblem.inputSrj).padDiameter, u6 = this.inputProblem.obstacleMargin ?? this.inputProblem.inputSrj.defaultObstacleMargin ?? 0.15, p6 = 2 * (d6 + u6), m6 = a6 === "vertical-columns" ? ["left", "right"] : ["top", "bottom"], g6 = [{ key: "center", bounds: l6, regionType: "center" }, ...$9(s6, e50), ...m6.flatMap((e53) => function({ side: e54, sideObstacles: t7, bounds: n7, centralBounds: o7 }) {
const i7 = [];
for (let r7 = 0;r7 < t7.length - 1; r7++) {
const s7 = At(t7[r7]), a7 = At(t7[r7 + 1]);
let c7;
c7 = e54 === "left" ? { minX: n7.minX, maxX: o7.minX, minY: s7.maxY, maxY: a7.minY } : e54 === "right" ? { minX: o7.maxX, maxX: n7.maxX, minY: s7.maxY, maxY: a7.minY } : e54 === "top" ? { minX: s7.maxX, maxX: a7.minX, minY: n7.minY, maxY: o7.minY } : { minX: s7.maxX, maxX: a7.minX, minY: o7.maxY, maxY: n7.maxY }, i7.push({ key: `${e54}-gap-${r7}`, bounds: c7, regionType: "pad-gap" });
}
return i7;
}({ side: e53, sideObstacles: c6[e53], bounds: n6, centralBounds: l6 }))], f6 = g6.flatMap((e53) => F9({ nodeId: `soic:${h6}:${e53.key}`, bounds: e53.bounds, availableZ: i6, multiLayerThreshold: p6, regionType: e53.regionType, obstacleZ: e53.obstacleZ, connectedTo: e53.connectedTo }));
this.output = { routingRegions: f6 }, this.stats = { componentId: o6, layerCount: e50, orientation: a6, viaDiameter: d6, obstacleMargin: u6, multiLayerThreshold: p6, firstSidePadCount: c6[m6[0]].length, secondSidePadCount: c6[m6[1]].length, multiLayerNodeCount: f6.filter((e53) => e53.availableZ.length > 1).length, totalMeshNodeCount: f6.length }, this.solved = true;
}
getOutput() {
if (!this.output)
throw new Error("SoicTopologyGeneratorSolver has not solved yet");
return this.output;
}
});
var U9 = class extends De {
constructor(e50) {
super(), this.inputProblem = e50;
}
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 = true, 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 = true);
const e50 = this.inputProblem.componentKinds[this.currentIndex], t6 = this.inputProblem.componentSrjs[this.currentIndex], n6 = { inputSrj: t6, detectedComponent: { componentId: this.inputProblem.componentIds[this.currentIndex], componentKind: e50, bounds: { __type: "rect", ...t6.bounds } }, viaDiameter: this.inputProblem.viaDiameter, obstacleMargin: this.inputProblem.obstacleMargin };
this.activeSubSolver = R4.create(n6);
}
getOutput() {
return { componentMeshNodes: this.componentMeshNodes };
}
visualize() {
if (this.activeSubSolver)
return this.activeSubSolver.visualize();
const e50 = this.inputProblem.componentSrjs[this.currentIndex] ?? null, t6 = this.componentMeshNodes.flatMap((e53) => e53);
return { rects: [...e50 ? [{ center: { x: (e50.bounds.minX + e50.bounds.maxX) / 2, y: (e50.bounds.minY + e50.bounds.maxY) / 2 }, width: e50.bounds.maxX - e50.bounds.minX, height: e50.bounds.maxY - e50.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}` }, ...e50.obstacles.map((e53) => ({ center: e53.center, width: e53.width, height: e53.height, fill: "rgba(255,140,0,0.10)", stroke: "rgba(255,140,0,0.30)", label: e53.obstacleId ?? e53.componentId ?? "obstacle" }))] : [], ...t6.map((e53) => ({ ...mF(e53, { rectMargin: 0.01 }), fill: e53._containsObstacle ? "rgba(255,0,0,0.14)" : "rgba(0,120,255,0.12)", stroke: e53._containsObstacle ? "rgba(255,0,0,0.34)" : "rgba(0,120,255,0.38)" }))] };
}
};
var Z9 = 0.001;
function q9(e50) {
const t6 = [...e50].sort((e53, t7) => e53 - t7), n6 = [];
for (const e53 of t6) {
const t7 = n6[n6.length - 1];
(t7 === undefined || Math.abs(e53 - t7) > Z9) && n6.push(e53);
}
return n6;
}
function J9(e50) {
const t6 = Math.min(...e50), n6 = Math.max(...e50);
return !(t6 <= 0) && n6 / t6 <= 1.01;
}
function Q9(e50) {
if (!function(e53) {
return J9(e53.map((e54) => e54.width)) && J9(e53.map((e54) => e54.height));
}(e50))
return false;
if (!function(e53) {
return e53.every((e54) => {
const t7 = Math.min(e54.width, e54.height), n7 = Math.max(e54.width, e54.height);
return !(t7 <= 0) && n7 / t7 <= 1.5;
});
}(e50))
return false;
const t6 = q9(e50.map((e53) => e53.center.y)), n6 = q9(e50.map((e53) => e53.center.x)), o6 = t6.length, i6 = n6.length;
if (o6 < 3 || i6 < 3)
return false;
const r6 = o6 * i6;
return !((r6 > 0 ? e50.length / r6 : 0) < 0.5) && !!function(e53, t7, n7) {
if (t7.length < 3)
return false;
if (n7.length < 3)
return false;
const o7 = new Set(t7.slice(1, -1)), i7 = new Set(n7.slice(1, -1));
let r7 = 0;
for (const t8 of e53)
o7.has(t8.center.y) && i7.has(t8.center.x) && (r7 += 1);
return r7 >= 1;
}(e50, t6, n6);
}
function K9(e50) {
return [Math.round(e50.width / Z9), Math.round(e50.height / Z9), e50.layers.join(",")].join(":");
}
function e62(e50) {
if (e50.length < 3)
return false;
const t6 = [...e50].sort((e53, t7) => e53 - t7), n6 = t6[1] - t6[0];
return !(n6 <= Z9) && t6.every((e53, o6) => o6 === 0 || Math.abs(e53 - t6[o6 - 1] - n6) <= Z9);
}
function t6(e50) {
const t7 = function(e53) {
const t8 = new Map;
for (const n7 of e53) {
const e54 = Math.round(n7.center.y / Z9), o6 = Math.round(n7.center.x / Z9), i6 = t8.get(e54) ?? { y: n7.center.y, obstaclesByX: new Map };
i6.obstaclesByX.set(o6, n7), t8.set(e54, i6);
}
return [...t8.values()];
}(e50);
let n6 = [];
for (const e53 of t7) {
const o6 = [...e53.obstaclesByX.keys()];
if (!e62([...e53.obstaclesByX.values()].map((e54) => e54.center.x)))
continue;
const i6 = t7.filter((e54) => o6.every((t8) => e54.obstaclesByX.has(t8)));
if (!e62(i6.map((e54) => e54.y)))
continue;
const r6 = i6.flatMap((e54) => o6.map((t8) => e54.obstaclesByX.get(t8)));
r6.length > n6.length && (n6 = r6);
}
return n6;
}
function n6(e50) {
if (Q9(e50))
return e50;
const t7 = Map.groupBy(e50, K9);
let n7 = [];
for (const e53 of t7.values()) {
const t8 = t6(e53);
t8.length > n7.length && (n7 = t8);
}
return n7.length > 0 ? n7 : null;
}
function o6(e50) {
const t7 = Math.min(e50.width, e50.height), n7 = Math.max(e50.width, e50.height);
return t7 > 0 && n7 / t7 >= 1.5;
}
function i6({ perimeterPadObstacles: e50, thermalPadObstacles: t7 }) {
if (t7.length === 0)
return true;
if (t7.length > 4)
return false;
const n7 = W9(e50), o7 = n7.maxX - n7.minX, i7 = n7.maxY - n7.minY, r6 = n7.minX + 0.2 * o7, s6 = n7.maxX - 0.2 * o7, a6 = n7.minY + 0.2 * i7, c6 = n7.maxY - 0.2 * i7, l6 = Math.min(...e50.map((e53) => Math.min(e53.width, e53.height)));
return t7.every((e53) => {
const t8 = Math.min(e53.width, e53.height);
return e53.center.x >= r6 && e53.center.x <= s6 && e53.center.y >= a6 && e53.center.y <= c6 && t8 > l6;
});
}
function r6(e50) {
if (e50.length < 12)
return false;
if (e50.length > 32)
return false;
const { counts: t7, maxNearestSideRatio: n7 } = function(e53) {
const t8 = W9(e53), n8 = t8.maxX - t8.minX, o7 = t8.maxY - t8.minY, i7 = { top: 0, right: 0, bottom: 0, left: 0 };
if (n8 <= 0 || o7 <= 0)
return { counts: i7, maxNearestSideRatio: 1 };
let r7 = 0;
for (const s6 of e53) {
const e54 = s6.width > s6.height, a6 = [{ side: "top", distance: Math.abs(s6.center.y - t8.minY), axisSpan: o7, orientationMatches: !e54 }, { side: "right", distance: Math.abs(t8.maxX - s6.center.x), axisSpan: n8, orientationMatches: e54 }, { side: "bottom", distance: Math.abs(t8.maxY - s6.center.y), axisSpan: o7, orientationMatches: !e54 }, { side: "left", distance: Math.abs(s6.center.x - t8.minX), axisSpan: n8, orientationMatches: e54 }].filter((e55) => e55.orientationMatches).sort((e55, t10) => e55.distance - t10.distance)[0];
i7[a6.side] += 1, r7 = Math.max(r7, a6.distance / a6.axisSpan);
}
return { counts: i7, maxNearestSideRatio: r7 };
}(e50);
return t7.top >= 3 && t7.right >= 3 && t7.bottom >= 3 && t7.left >= 3 && n7 <= 0.25;
}
function s6(e50) {
const t7 = function(e53) {
return e53.filter(o6);
}(e50);
return { perimeterPadObstacles: t7, thermalPadObstacles: e50.filter((e53) => !o6(e53)) };
}
function a6(e50) {
const t7 = Math.min(...e50), n7 = Math.max(...e50);
return !(t7 <= 0) && n7 / t7 <= 1.01;
}
function c6(e50, t7) {
let n7 = 0, o7 = Number.POSITIVE_INFINITY;
for (let i7 = 0;i7 < t7.length; i7++) {
const r7 = Math.abs(e50 - t7[i7]);
r7 < o7 && (n7 = i7, o7 = r7);
}
return n7;
}
function l6({ memberObstacles: e50, inputSrj: t7 }) {
if (!function(e53) {
return a6(e53.map((e54) => e54.width)) && a6(e53.map((e54) => e54.height));
}(e50))
return false;
const n7 = q9(e50.map((e53) => e53.center.y)), o7 = q9(e50.map((e53) => e53.center.x));
if (!(n7.length === 2 && o7.length >= 4 || o7.length === 2 && n7.length >= 4))
return false;
const i7 = function({ memberObstacles: e53, rowAxisValues: t8, columnAxisValues: n8 }) {
if (t8.length === 2 && n8.length >= 4) {
const n10 = [[], []];
for (const o8 of e53)
n10[c6(o8.center.y, t8)].push(o8);
return Math.min(...n10[1].map((e54) => e54.center.y - e54.height / 2)) - Math.max(...n10[0].map((e54) => e54.center.y + e54.height / 2));
}
if (n8.length === 2 && t8.length >= 4) {
const t10 = [[], []];
for (const o8 of e53)
t10[c6(o8.center.x, n8)].push(o8);
return Math.min(...t10[1].map((e54) => e54.center.x - e54.width / 2)) - Math.max(...t10[0].map((e54) => e54.center.x + e54.width / 2));
}
return null;
}({ memberObstacles: e50, rowAxisValues: n7, columnAxisValues: o7 });
if (i7 === null)
return false;
return i7 > 2 * (Xo(t7).padDiameter + (t7.defaultObstacleMargin ?? 0.15));
}
var h6 = [class e53 {
constructor(e50) {
this.params = e50;
}
params;
static componentKind = "qfp_thermalpad";
componentKind = e53.componentKind;
static isMatch({ memberObstacles: e50 }) {
return function(e54) {
const { perimeterPadObstacles: t7, thermalPadObstacles: n7 } = s6(e54);
return n7.length !== 0 && !!r6(t7) && i6({ perimeterPadObstacles: t7, thermalPadObstacles: n7 });
}(e50);
}
}, class e55 {
constructor(e50) {
this.params = e50;
}
params;
static componentKind = "qfp";
componentKind = e55.componentKind;
static isMatch({ memberObstacles: e50 }) {
return function(e54) {
const { perimeterPadObstacles: t7, thermalPadObstacles: n7 } = s6(e54);
return !(n7.length > 0) && !!i6({ perimeterPadObstacles: t7, thermalPadObstacles: n7 }) && r6(t7);
}(e50);
}
}, class e56 {
constructor(e50) {
this.params = e50;
}
params;
static componentKind = "soic";
componentKind = e56.componentKind;
static isMatch(e50) {
return l6(e50);
}
}, class e57 {
constructor(e50) {
this.params = e50;
}
params;
static componentKind = "bga";
componentKind = e57.componentKind;
static isMatch({ memberObstacles: e50 }) {
return function(e54) {
return n6(e54) !== null;
}(e50);
}
}];
function d6(e50) {
return function(e54) {
for (const t7 of h6)
if (t7.isMatch(e54))
return new t7(e54);
return null;
}(e50)?.componentKind ?? null;
}
var u6 = class extends De {
inputSrj;
initialized = false;
groupedComponentObstacles = {};
groupedComponentKinds = {};
unprocessedComponentIds = [];
detectedComponents = [];
currentComponentId = null;
currentMemberObstacles = [];
output = null;
constructor({ inputSrj: e50 }) {
super(), this.inputSrj = e50;
}
getConstructorParams() {
return [{ inputSrj: this.inputSrj }];
}
_step() {
this.initialized ? this.output ? this.solved = true : this.currentComponentId !== null || this.unprocessedComponentIds.length > 0 ? this.processNextComponent() : (this.finalizeOutput(), this.solved = true) : this.initializeDetectionState();
}
getOutput() {
if (!this.output)
throw new Error("ComponentDetectionSolver has not solved yet");
return this.output;
}
visualize() {
const e50 = [];
e50.push(...this.inputSrj.obstacles.filter((e54) => !e54.componentId).map((e54) => ({ center: e54.center, width: e54.width, height: e54.height, fill: "rgba(120, 120, 120, 0.10)", stroke: "rgba(120, 120, 120, 0.40)", label: e54.obstacleId, layer: e54.layers.join(","), step: 0 })));
const t7 = new Set(this.detectedComponents.map((e54) => e54.componentId));
for (const n7 of this.inputSrj.obstacles) {
if (!n7.componentId)
continue;
if (t7.has(n7.componentId))
continue;
const o7 = n7.componentId === this.currentComponentId, i7 = ko(n7.componentId), r7 = this.groupedComponentKinds[n7.componentId];
e50.push({ center: n7.center, width: n7.width, height: n7.height, fill: Oo(i7, o7 ? 0.55 : 0.82), stroke: Oo(i7, o7 ? 0.1 : 0.45), label: r7 ? `${n7.componentId} ${r7.toUpperCase()}` : n7.componentId, layer: n7.layers.join(","), step: o7 ? 1 : 0 });
}
for (const t8 of this.detectedComponents) {
const n7 = ko(t8.componentId);
e50.push({ center: { x: (t8.bounds.minX + t8.bounds.maxX) / 2, y: (t8.bounds.minY + t8.bounds.maxY) / 2 }, width: t8.bounds.maxX - t8.bounds.minX, height: t8.bounds.maxY - t8.bounds.minY, fill: Oo(n7, 0.88), stroke: Oo(n7, 0.1), label: `${t8.componentId} ${t8.componentKind.toUpperCase()} region`, step: 2 });
}
return { title: this.getVisualizationTitle(), rects: e50, lines: [], points: [], circles: [] };
}
preview() {
return this.visualize();
}
initializeDetectionState() {
this.initialized = true, 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 e50 = this.unprocessedComponentIds.shift();
return e50 ? (this.currentComponentId = e50, void (this.currentMemberObstacles = this.groupedComponentObstacles[e50] ?? [])) : (this.currentComponentId = null, void (this.currentMemberObstacles = []));
}
if (this.currentMemberObstacles.length === 0)
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((e50) => ({ ...e50, bounds: { ...e50.bounds } })), this.stats = { initialized: this.initialized, totalComponentCount: Object.keys(this.groupedComponentObstacles).length, detectedComponentCount: this.detectedComponents.length, detectedBgaComponentCount: this.detectedComponents.filter((e50) => e50.componentKind === "bga").length, detectedQfpComponentCount: this.detectedComponents.filter((e50) => e50.componentKind === "qfp").length, detectedQfpComponentIds: this.detectedComponents.filter((e50) => e50.componentKind === "qfp").map((e50) => e50.componentId), detectedQfpThermalPadComponentCount: this.detectedComponents.filter((e50) => e50.componentKind === "qfp_thermalpad").length, detectedQfpThermalPadComponentIds: this.detectedComponents.filter((e50) => e50.componentKind === "qfp_thermalpad").map((e50) => e50.componentId), detectedSoicComponentCount: this.detectedComponents.filter((e50) => e50.componentKind === "soic").length, detectedSoicComponentIds: this.detectedComponents.filter((e50) => e50.componentKind === "soic").map((e50) => e50.componentId), remainingComponentCount: this.unprocessedComponentIds.length, hasActiveComponent: this.currentComponentId !== null };
}
groupObstaclesByComponentId({ obstacles: e50 }) {
const t7 = {}, n7 = {};
for (const n8 of e50)
n8.componentId && (t7[n8.componentId] ??= [], t7[n8.componentId].push(n8));
const o7 = Object.entries(t7).flatMap(([e54, t8]) => {
const o8 = this.inputSrj.bounds;
if (t8.some((e58) => !G9({ bounds: At(e58), outerBounds: o8, epsilon: 0 })))
return [];
const i7 = d6({ memberObstacles: t8, inputSrj: this.inputSrj });
if (!i7)
return [];
n7[e54] = i7;
return [[e54, i7 === "bga" ? n6(t8) : t8]];
});
return this.groupedComponentKinds = n7, Object.fromEntries(o7);
}
createDetectedComponent({ componentId: e50, componentKind: t7, memberObstacles: n7 }) {
return { componentId: e50, componentKind: t7, bounds: { __type: "rect", ...W9(n7) } };
}
getVisualizationTitle() {
const e50 = Object.keys(this.groupedComponentObstacles).length || new Set(this.inputSrj.obstacles.map((e54) => e54.componentId).filter((e54) => Boolean(e54))).size, t7 = this.detectedComponents.length;
return this.initialized ? this.output || this.solved ? `Component Detection: done ${t7}/${e50}` : this.currentComponentId !== null || this.unprocessedComponentIds.length > 0 ? `Component Detection: ${t7}/${e50} processed` : `Component Detection: finalizing ${t7}/${e50}` : "Component Detection: setup";
}
};
var p6 = (e50) => e50.componentId && e50.obstacleId ? `${e50.componentId}
${e50.obstacleId}` : e50.componentId ?? e50.obstacleId ?? "obstacle";
var m6 = class extends ze {
rectBoundsComponentDetection;
pipelineDef = [Le("rectBoundsComponentDetection", u6, (e50) => [{ inputSrj: e50.inputProblem.inputSrj }])];
getConstructorParams() {
return [this.inputProblem];
}
getOutput() {
const e50 = this.getStageOutput("rectBoundsComponentDetection");
if (!e50)
throw new Error("ComponentDetectionSolver has not solved yet");
return e50;
}
initialVisualize() {
const { bounds: e50 } = this.inputProblem.inputSrj;
return { title: "Component Detection: board and grouped component pads", rects: [{ center: { x: (e50.minX + e50.maxX) / 2, y: (e50.minY + e50.maxY) / 2 }, width: e50.maxX - e50.minX, height: e50.maxY - e50.minY, fill: "rgba(0, 0, 0, 0)", stroke: "rgba(40, 40, 40, 0.7)", label: "Board bounds", step: 0 }, ...this.inputProblem.inputSrj.obstacles.map((e54) => {
const t7 = e54.componentId ? ko(e54.componentId) : null;
return { center: e54.center, width: e54.width, height: e54.height, fill: t7 ? Oo(t7, 0.72) : "rgba(120, 120, 120, 0.10)", stroke: t7 ? Oo(t7, 0.28) : "rgba(120, 120, 120, 0.40)", label: p6(e54), layer: e54.layers.join(","), step: e54.componentId ? 1 : 0 };
})], lines: [], points: [], circles: [] };
}
};
var g6 = 0.000000001;
function f6(e50) {
return Vt({ center: e50.center, width: e50.width, height: e50.height });
}
function _6(e50, t7) {
const n7 = { minX: Math.max(e50.minX, t7.minX), maxX: Math.min(e50.maxX, t7.maxX), minY: Math.max(e50.minY, t7.minY), maxY: Math.min(e50.maxY, t7.maxY) };
return y6(n7) ? n7 : null;
}
function y6(e50) {
const t7 = e50.maxX - e50.minX, n7 = e50.maxY - e50.minY, o7 = Number.isFinite(t7) && t7 > g6, i7 = Number.isFinite(n7) && n7 > g6;
return o7 && i7;
}
function b6(e50) {
(function(e54) {
if (!Number.isInteger(e54.layerCount))
throw new Error("TopologyMergingSolver: layerCount must be an integer");
if (e54.layerCount <= 0)
throw new Error("TopologyMergingSolver: layerCount must be positive");
if (e54.nodeGroups.length === 0)
throw new Error("TopologyMergingSolver: at least one node group is required");
const t8 = new Set;
let n8 = 0;
for (const o7 of e54.nodeGroups) {
if (t8.has(o7.groupId))
throw new Error(`TopologyMergingSolver: duplicate topology group id "${o7.groupId}"`);
if (t8.add(o7.groupId), n8 += o7.nodes.length, o7.nodes.length === 0)
throw new Error(`TopologyMergingSolver: topology group "${o7.groupId}" is empty`);
const i7 = new Set;
for (const t10 of o7.nodes) {
if (i7.has(t10.capacityMeshNodeId))
throw new Error(`TopologyMergingSolver: duplicate node id "${t10.capacityMeshNodeId}" in group "${o7.groupId}"`);
i7.add(t10.capacityMeshNodeId), x6({ node: t10, groupId: o7.groupId, layerCount: e54.layerCount });
}
}
if (n8 === 0)
throw new Error("TopologyMergingSolver: topology node groups are empty");
})(e50);
const t7 = [], n7 = new Map;
for (let o7 = 0;o7 < e50.nodeGroups.length; o7++) {
const i7 = e50.nodeGroups[o7];
for (const e54 of i7.nodes) {
const r7 = { sourceKey: `${i7.groupId}:${e54.capacityMeshNodeId}`, groupIndex: o7, node: e54, bounds: f6(e54) };
t7.push(r7), n7.set(r7.sourceKey, r7);
}
}
return { preparedNodes: t7, preparedNodeBySourceKey: n7 };
}
function x6({ node: e50, groupId: t7, layerCount: n7 }) {
if (!y6(f6(e50)))
throw new Error(`TopologyMergingSolver: node "${e50.capacityMeshNodeId}" in group "${t7}" has invalid bounds`);
if (e50.availableZ.length === 0)
throw new Error(`TopologyMergingSolver: node "${e50.capacityMeshNodeId}" in group "${t7}" has no available layers`);
const o7 = [...new Set(e50.availableZ)].sort((e54, t8) => e54 - t8), i7 = o7.some((e54) => !Number.isInteger(e54) || e54 < 0 || e54 >= n7), r7 = o7.length === e50.availableZ.length && o7.every((t8, n8) => t8 === e50.availableZ[n8]);
if (i7 || !r7)
throw new Error(`TopologyMergingSolver: node "${e50.capacityMeshNodeId}" in group "${t7}" has invalid or unsorted availableZ`);
}
var v6 = 0.00001;
var I6 = 0.00004;
function S6({ regions: e50, preparedNodeBySourceKey: t7, nodeGroups: n7, provenance: o7, preserveSourceIds: i7 = true }) {
i7 && (o7.groupIndexesByNodeId.clear(), o7.sourceKeysByNodeId.clear());
const r7 = [...e50].sort((e54, t8) => e54.bounds.minX - t8.bounds.minX || e54.bounds.minY - t8.bounds.minY || e54.bounds.maxX - t8.bounds.maxX || e54.bounds.maxY - t8.bounds.maxY || e54.availableZ[0] - t8.availableZ[0]), s7 = new Set;
return r7.map((e54, r8) => {
const a7 = e54.sourceKeys.map((e58) => {
const n8 = t7.get(e58);
if (!n8)
throw new Error(`TopologyMergingSolver: missing source node for "${e58}"`);
return n8;
}), c7 = a7.map(({ node: e58 }) => e58), l7 = function({ sourceNodes: e58, isComponentTopologyNode: t8 }) {
if (e58.length === 1)
return { _isComponentTopologyNode: !!t8 || e58[0]._isComponentTopologyNode };
const n8 = e58.map((e59) => e59.capacityMeshNodeId), o8 = C6(e58.map((e59) => e59._targetConnectionName), "target connection", n8), i8 = C6(e58.map((e59) => e59._offBoardConnectionId), "off-board connection", n8), r10 = C6(e58.map((e59) => e59._offboardNetName), "off-board net", n8), s8 = Array.from(new Set(e58.flatMap((e59) => e59._offBoardConnectedCapacityMeshNodeIds ?? []))), a8 = Array.from(new Set(e58.flatMap((e59) => e59._connectedTo ?? [])));
return { _containsObstacle: e58.some((e59) => e59._containsObstacle) || undefined, _completelyInsideObstacle: e58.some((e59) => e59._completelyInsideObstacle) || undefined, _containsTarget: e58.some((e59) => e59._containsTarget) || undefined, _targetConnectionName: o8, _isVirtualOffboard: e58.some((e59) => e59._isVirtualOffboard) || undefined, _offboardNetName: r10, _offBoardConnectionId: i8, _offBoardConnectedCapacityMeshNodeIds: s8.length > 0 ? s8 : undefined, _qfpRegionType: P6(e58.map((e59) => e59._qfpRegionType)), _isNarrowQfpPadGap: e58.some((e59) => e59._isNarrowQfpPadGap) || undefined, _soicRegionType: P6(e58.map((e59) => e59._soicRegionType)), _isComponentTopologyNode: t8 || undefined, _connectedTo: a8.length > 0 ? a8 : undefined };
}({ sourceNodes: c7, isComponentTopologyNode: a7.some(({ groupIndex: e58 }) => n7[e58].isComponent) }), h7 = i7 && a7.length === 1 ? a7[0].node : null, d7 = Boolean(h7 && function({ region: e58, sourceNode: t8, usedNodeIds: n8 }) {
const o8 = f6(t8), i8 = Math.abs(e58.bounds.minX - o8.minX) <= v6 && Math.abs(e58.bounds.maxX - o8.maxX) <= v6 && Math.abs(e58.bounds.minY - o8.minY) <= v6 && Math.abs(e58.bounds.maxY - o8.maxY) <= v6, r10 = e58.availableZ.length === t8.availableZ.length && e58.availableZ.every((e59, n10) => e59 === t8.availableZ[n10]);
return i8 && r10 && !n8.has(t8.capacityMeshNodeId);
}({ region: e54, sourceNode: h7, usedNodeIds: s7 }));
let u7 = d7 ? h7.capacityMeshNodeId : `topology_merge_${r8}`;
for (;s7.has(u7); )
u7 = `${u7}_next`;
return s7.add(u7), i7 && (o7.groupIndexesByNodeId.set(u7, [...new Set(a7.map(({ groupIndex: e58 }) => e58))]), o7.sourceKeysByNodeId.set(u7, [...e54.sourceKeys])), { ...h7 ?? c7[0], ...l7, capacityMeshNodeId: u7, center: { x: (e54.bounds.minX + e54.bounds.maxX) / 2, y: (e54.bounds.minY + e54.bounds.maxY) / 2 }, width: e54.bounds.maxX - e54.bounds.minX, height: e54.bounds.maxY - e54.bounds.minY, layer: `z${e54.availableZ.join(",")}`, availableZ: [...e54.availableZ], _adjacentNodeIds: undefined, _parent: undefined, _strawNode: undefined, _strawParentCapacityMeshNodeId: undefined };
});
}
function C6(e50, t7, n7) {
const o7 = Array.from(new Set(e50.filter((e54) => e54 !== undefined)));
if (o7.length > 1)
throw new Error(`TopologyMergingSolver: conflicting ${t7} values for overlapping source nodes ${n7.join(", ")}`);
return o7[0];
}
function P6(e50) {
const t7 = Array.from(new Set(e50.filter((e54) => e54 !== undefined)));
return t7.length === 1 ? t7[0] : undefined;
}
function M6({ node: e50, sourceKey: t7, preparedNodeBySourceKey: n7 }) {
const o7 = n7.get(t7);
if (!o7)
throw new Error(`TopologyMergingSolver: missing source node for output "${e50.capacityMeshNodeId}"`);
const i7 = f6(e50), r7 = i7.minX >= o7.bounds.minX - I6 && i7.maxX <= o7.bounds.maxX + I6 && i7.minY >= o7.bounds.minY - I6 && i7.maxY <= o7.bounds.maxY + I6, s7 = e50.availableZ.every((e54) => o7.node.availableZ.includes(e54));
if (!r7 || !s7)
throw new Error(`TopologyMergingSolver: output node "${e50.capacityMeshNodeId}" escapes its source geometry or layers`);
}
function w6({ groupIndexesA: e50, groupIndexesB: t7, sourceKeysA: n7, sourceKeysB: o7, sharedLayers: i7, preparedNodeBySourceKey: r7 }) {
if (e50.length !== 1 || t7.length !== 1 || e50[0] !== t7[0] || n7.length !== 1 || o7.length !== 1 || n7[0] === o7[0])
return false;
const s7 = r7.get(n7[0]), a7 = r7.get(o7[0]);
if (!s7 || !a7 || i7.length === 0)
return false;
return i7.some((e54) => s7.node.availableZ.includes(e54) && a7.node.availableZ.includes(e54)) && _6(s7.bounds, a7.bounds) !== null;
}
function N6(e50) {
const t7 = [...e50].sort((e54, t8) => e54 - t8), n7 = [];
for (const e54 of t7) {
const t8 = n7[n7.length - 1];
(t8 === undefined || Math.abs(e54 - t8) > v6) && n7.push(e54);
}
return n7;
}
function T6(e50, t7) {
return t7.x >= e50.minX - v6 && t7.x <= e50.maxX + v6 && t7.y >= e50.minY - v6 && t7.y <= e50.maxY + v6;
}
function R6({ coveringNodes: e50, nodeGroups: t7, layerCount: n7 }) {
const o7 = new Map;
for (let i7 = 0;i7 < n7; i7++) {
const n8 = e50.filter(({ node: e54 }) => e54.availableZ.includes(i7)).sort((e54, t8) => e54.sourceKey.localeCompare(t8.sourceKey));
if (n8.length === 0)
continue;
const r7 = new Set(n8.map(({ groupIndex: e54 }) => e54)), s7 = n8.filter(({ node: e54 }) => e54._containsObstacle && e54._containsTarget), a7 = s7.filter(({ groupIndex: e54 }) => !t7[e54].isComponent), c7 = new Set(s7.map(({ groupIndex: e54 }) => e54)), l7 = s7.length > 0 ? a7.length > 0 || c7.size === 1 ? "target-passthrough" : "target-merged" : r7.size === 1 ? "passthrough" : "merged", h7 = D6({ topologyMode: l7, nodesOnLayer: n8, targetObstacleNodes: s7, globalTargetObstacleNodes: a7 });
for (const e54 of h7) {
const t8 = JSON.stringify({ mode: l7, sourceKeys: e54 }), n10 = o7.get(t8);
n10 ? n10.availableZ.push(i7) : o7.set(t8, { availableZ: [i7], sourceKeys: e54, topologyMode: l7, topologySignature: t8 });
}
}
return [...o7.values()];
}
function E6(e50) {
return JSON.stringify({ availableZ: e50.availableZ, topologySignature: e50.topologySignature });
}
function A6(e50) {
return JSON.stringify({ mergeKey: E6(e50), minY: e50.bounds.minY.toPrecision(15), maxY: e50.bounds.maxY.toPrecision(15) });
}
function O6(e50) {
return JSON.stringify({ mergeKey: E6(e50), minX: e50.bounds.minX.toPrecision(15), maxX: e50.bounds.maxX.toPrecision(15) });
}
function k6(e50, t7) {
const n7 = new Map;
for (const o7 of e50) {
const e54 = t7 === "horizontal" ? A6(o7) : O6(o7), i7 = n7.get(e54) ?? [];
i7.push(o7), n7.set(e54, i7);
}
return [...n7.values()].flatMap((e54) => function(e58, t8) {
const n8 = [...e58].sort((e59, n10) => t8 === "horizontal" ? e59.bounds.minX - n10.bounds.minX : e59.bounds.minY - n10.bounds.minY), o7 = [];
for (const e59 of n8) {
const n10 = o7[o7.length - 1], i7 = n10 !== undefined && (t8 === "horizontal" ? Math.abs(n10.bounds.maxX - e59.bounds.minX) <= v6 : Math.abs(n10.bounds.maxY - e59.bounds.minY) <= v6);
n10 && i7 ? t8 === "horizontal" ? n10.bounds.maxX = e59.bounds.maxX : n10.bounds.maxY = e59.bounds.maxY : o7.push({ ...e59, bounds: { ...e59.bounds }, availableZ: [...e59.availableZ], sourceKeys: [...e59.sourceKeys] });
}
return o7;
}(e54, t7));
}
function D6({ topologyMode: e50, nodesOnLayer: t7, targetObstacleNodes: n7, globalTargetObstacleNodes: o7 }) {
if (e50 === "target-passthrough") {
return (o7.length > 0 ? o7 : n7).map(({ sourceKey: e54 }) => [e54]);
}
return e50 === "target-merged" ? [n7.map(({ sourceKey: e54 }) => e54).sort()] : e50 === "passthrough" ? t7.map(({ sourceKey: e54 }) => [e54]) : [t7.map(({ sourceKey: e54 }) => e54).sort()];
}
var L6 = class extends De {
constructor(e50) {
super(), this.inputProblem = e50, this.MAX_ITERATIONS = 1e5;
const { preparedNodes: t7, preparedNodeBySourceKey: n7 } = b6(e50);
this.preparedNodes = t7, this.preparedNodeBySourceKey = n7, this.xCoordinates = N6(this.preparedNodes.flatMap(({ bounds: e54 }) => [e54.minX, e54.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 (this.inputProblem.nodeGroups.length === 1)
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 e50 = function(e54) {
let t7 = e54;
for (;; ) {
const e58 = k6(t7, "horizontal"), n7 = k6(e58, "vertical");
if (n7.length === t7.length)
return n7;
t7 = n7;
}
}(function({ regions: e54, preparedNodeBySourceKey: t7 }) {
const n7 = new Map;
for (const t8 of e54)
for (const e58 of t8.sourceKeys) {
const o8 = n7.get(e58) ?? new Set;
o8.add(t8.topologyMode), n7.set(e58, o8);
}
const o7 = new Set([...n7.entries()].filter(([, e58]) => e58.size === 1 && e58.has("target-passthrough")).map(([e58]) => e58));
return o7.size === 0 ? e54 : [...e54.filter((e58) => e58.topologyMode !== "target-passthrough" || !o7.has(e58.sourceKeys[0])), ...[...o7].map((e58) => {
const n8 = t7.get(e58);
if (!n8)
throw new Error(`TopologyMergingSolver: missing authoritative target source "${e58}"`);
return { bounds: { ...n8.bounds }, availableZ: [...n8.node.availableZ], sourceKeys: [e58], topologyMode: "target-passthrough", topologySignature: JSON.stringify({ mode: "target-passthrough", sourceKeys: [e58] }) };
})];
}({ regions: this.atomicRegions, preparedNodeBySourceKey: this.preparedNodeBySourceKey }));
this.outputNodes = S6({ regions: e50, preparedNodeBySourceKey: this.preparedNodeBySourceKey, nodeGroups: this.inputProblem.nodeGroups, provenance: this.outputProvenance }), function({ nodes: e54, preparedNodeBySourceKey: t7, provenance: n7 }) {
const o7 = new Set;
for (const i7 of e54) {
if (o7.has(i7.capacityMeshNodeId))
throw new Error(`TopologyMergingSolver: duplicate output node id "${i7.capacityMeshNodeId}"`);
if (o7.add(i7.capacityMeshNodeId), !y6(f6(i7)))
throw new Error(`TopologyMergingSolver: output node "${i7.capacityMeshNodeId}" has invalid bounds`);
if (i7.availableZ.length === 0)
throw new Error(`TopologyMergingSolver: output node "${i7.capacityMeshNodeId}" has no available layers`);
const e58 = n7.sourceKeysByNodeId.get(i7.capacityMeshNodeId);
if (!e58)
throw new Error(`TopologyMergingSolver: missing output provenance for node "${i7.capacityMeshNodeId}"`);
e58.length === 1 && M6({ node: i7, sourceKey: e58[0], preparedNodeBySourceKey: t7 });
}
for (let o8 = 0;o8 < e54.length; o8++) {
const i7 = e54[o8];
for (let r7 = o8 + 1;r7 < e54.length; r7++) {
const o10 = e54[r7], s7 = i7.availableZ.filter((e58) => o10.availableZ.includes(e58));
if (s7.length === 0)
continue;
const a7 = _6(f6(i7), f6(o10));
if (!a7)
continue;
const c7 = a7.maxX - a7.minX, l7 = a7.maxY - a7.minY;
if (c7 <= I6 || l7 <= I6)
continue;
const h7 = n7.groupIndexesByNodeId.get(i7.capacityMeshNodeId), d7 = n7.groupIndexesByNodeId.get(o10.capacityMeshNodeId);
if (!h7 || !d7)
throw new Error(`TopologyMergingSolver: missing output provenance for overlapping nodes "${i7.capacityMeshNodeId}" and "${o10.capacityMeshNodeId}"`);
const u7 = n7.sourceKeysByNodeId.get(i7.capacityMeshNodeId), p7 = n7.sourceKeysByNodeId.get(o10.capacityMeshNodeId);
if (!u7 || !p7)
throw new Error(`TopologyMergingSolver: missing source provenance for overlapping nodes "${i7.capacityMeshNodeId}" and "${o10.capacityMeshNodeId}"`);
if (!w6({ groupIndexesA: h7, groupIndexesB: d7, sourceKeysA: u7, sourceKeysB: p7, sharedLayers: s7, preparedNodeBySourceKey: t7 }))
throw new Error(`TopologyMergingSolver: output nodes "${i7.capacityMeshNodeId}" and "${o10.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 = e50.length, this.solved = true;
}
getOutput() {
if (!this.solved)
throw new Error("TopologyMergingSolver: getOutput() called before the solver completed");
return this.outputNodes;
}
computeProgress() {
const e50 = Math.max(1, this.xCoordinates.length - 1);
return this.solved ? 1 : Math.min(0.99, this.currentXIndex / e50);
}
visualize() {
const e50 = this.solved ? this.outputNodes : S6({ regions: this.atomicRegions, preparedNodeBySourceKey: this.preparedNodeBySourceKey, nodeGroups: this.inputProblem.nodeGroups, provenance: this.outputProvenance, preserveSourceIds: false });
return { title: `Topology Merging: ${e50.length} refined regions`, coordinateSystem: "cartesian", rects: e50.map((e54) => ({ ...mF(e54, { rectMargin: 0.01, zOffset: 0.02 }), label: `${e54.capacityMeshNodeId}
availableZ: ${e54.availableZ.join(",")}
component: ${e54._isComponentTopologyNode ? "yes" : "no"}` })), lines: [], points: [], circles: [], texts: [] };
}
completePassthroughTopology() {
const e50 = this.inputProblem.nodeGroups[0];
this.outputNodes = e50.nodes;
for (const t7 of this.outputNodes)
this.outputProvenance.groupIndexesByNodeId.set(t7.capacityMeshNodeId, [0]), this.outputProvenance.sourceKeysByNodeId.set(t7.capacityMeshNodeId, [`${e50.groupId}:${t7.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 = true;
}
processCurrentXSlab() {
const e50 = this.xCoordinates[this.currentXIndex], t7 = this.xCoordinates[this.currentXIndex + 1];
if (t7 - e50 <= v6)
return;
const n7 = (e50 + t7) / 2, o7 = this.preparedNodes.filter(({ bounds: e54 }) => n7 >= e54.minX - v6 && n7 <= e54.maxX + v6), i7 = N6(o7.flatMap(({ bounds: e54 }) => [e54.minY, e54.maxY]));
for (let r7 = 0;r7 < i7.length - 1; r7++) {
const s7 = i7[r7], a7 = i7[r7 + 1];
if (a7 - s7 <= v6)
continue;
const c7 = { x: n7, y: (s7 + a7) / 2 }, l7 = o7.filter(({ bounds: e54 }) => T6(e54, c7));
if (l7.length === 0)
continue;
const h7 = R6({ coveringNodes: l7, nodeGroups: this.inputProblem.nodeGroups, layerCount: this.inputProblem.layerCount });
for (const n8 of h7)
this.atomicRegions.push({ bounds: { minX: e50, maxX: t7, minY: s7, maxY: a7 }, availableZ: n8.availableZ, sourceKeys: n8.sourceKeys, topologyMode: n8.topologyMode, topologySignature: n8.topologySignature });
}
}
};
function z6({ meshNodes: e50, components: t7 }) {
return t7.length === 0 ? e50 : e50.map((e54) => {
const n7 = t7.some((t8) => function({ node: e58, component: t10 }) {
const { replacementObstacle: n8 } = t10, o7 = Math.abs(e58.center.x - n8.center.x) <= g6 && Math.abs(e58.center.y - n8.center.y) <= g6 && Math.abs(e58.width - n8.width) <= g6 && Math.abs(e58.height - n8.height) <= g6;
if (t10.componentKind !== "qfp" && t10.componentKind !== "qfp_thermalpad" && t10.componentKind !== "soic")
return o7;
const i7 = n8.center.x - n8.width / 2, r7 = n8.center.x + n8.width / 2, s7 = n8.center.y - n8.height / 2, a7 = n8.center.y + n8.height / 2, c7 = e58.center.x >= i7 - g6 && e58.center.x <= r7 + g6 && e58.center.y >= s7 - g6 && e58.center.y <= a7 + g6, l7 = e58.width * e58.height, h7 = n8.width * n8.height, d7 = c7 && l7 >= 0.2 * h7;
return o7 || d7;
}({ node: e54, component: t8 }));
return n7 ? { ...e54, _containsObstacle: undefined, _completelyInsideObstacle: undefined, _containsTarget: undefined, _targetConnectionName: undefined, _connectedTo: undefined } : e54;
});
}
var B6 = class extends ze {
globalTopologySolver;
componentTopologyBatchSolver;
normalizedInput;
pipelineDef = [Le("globalTopologySolver", Kn, (e50) => [e50.getGlobalTopologySolverInput()]), Le("componentTopologyBatchSolver", U9, (e50) => [{ componentSrjs: e50.getComponentNoConnectionSrjs(), componentIds: e50.normalizedInput.components.map((e54) => e54.componentId), componentKinds: e50.normalizedInput.components.map((e54) => e54.componentKind), viaDiameter: e50.inputProblem.viaDiameter, obstacleMargin: e50.inputProblem.obstacleMargin }])];
constructor(e50) {
super(e50), this.normalizedInput = V9(e50);
}
getConstructorParams() {
return [this.inputProblem];
}
getOutput() {
const e50 = z6({ meshNodes: this.getStageOutput("globalTopologySolver")?.meshNodes ?? [], components: this.normalizedInput.components }), t7 = this.getStageOutput("componentTopologyBatchSolver")?.componentMeshNodes ?? [], n7 = this.getComponentNoConnectionSrjs();
return { globalNoConnectionSrj: this.normalizedInput.globalNoConnectionSrj, componentNoConnectionSrjs: n7, globalMeshNodes: e50, componentMeshNodes: t7 };
}
finalVisualize() {
const e50 = this.getOutput();
return { title: "Topology Planning: generated topology groups", rects: [...e50.componentNoConnectionSrjs.flatMap((e54, t7) => {
const n7 = this.normalizedInput.components[t7] ?? null;
return e54.obstacles.map((e58) => ({ center: e58.center, width: e58.width, height: e58.height, fill: "rgba(120, 120, 120, 0.06)", stroke: "rgba(120, 120, 120, 0.35)", label: e58.obstacleId ?? n7?.componentId ?? "component-pad", layer: e58.layers.join(",") }));
}), ...[...e50.globalMeshNodes, ...e50.componentMeshNodes.flat()].map((e54) => {
const t7 = this.normalizedInput.components.find((t8) => e54.capacityMeshNodeId.includes(t8.componentId));
return { ...mF(e54, { rectMargin: 0.01 }), fill: e54._containsObstacle ? Oo("red", 0.82) : "rgba(0, 120, 255, 0.12)", stroke: e54._containsObstacle ? Oo("red", 0.3) : "rgba(0, 120, 255, 0.55)", label: t7 ? `${t7.componentKind.toUpperCase()} ${e54.capacityMeshNodeId}` : e54.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((e50) => function({ inputSrj: e54, component: t7 }) {
const n7 = W9(t7.memberObstacles), o7 = Math.max(e54.minViaPadDiameter ?? e54.min_via_pad_diameter ?? e54.minViaDiameter ?? 0.3, e54.defaultObstacleMargin ?? 0.15, 2 * e54.minTraceWidth), i7 = new Set(t7.memberObstacles.flatMap((e58) => e58.connectedTo)), r7 = e54.connections.flatMap((e58) => e58.pointsToConnect.filter((e59) => {
const t8 = [e59.pointId, e59.pcb_port_id].filter((e60) => typeof e60 == "string").some((e60) => i7.has(e60)), r8 = e59.x >= n7.minX - o7 && e59.x <= n7.maxX + o7 && e59.y >= n7.minY - o7 && e59.y <= n7.maxY + o7;
return t8 && r8;
})).reduce((e58, t8) => ({ minX: Math.min(e58.minX, t8.x), maxX: Math.max(e58.maxX, t8.x), minY: Math.min(e58.minY, t8.y), maxY: Math.max(e58.maxY, t8.y) }), n7), s7 = e54.obstacles.filter((e58) => Wt(At(e58), r7)).map((e58) => ({ ...e58 }));
return { ...structuredClone(e54), bounds: r7, obstacles: s7 };
}({ inputSrj: this.inputProblem.inputSrj, component: e50 }));
}
getGlobalTopologySolverInput() {
return { simpleRouteJson: this.normalizedInput.globalNoConnectionSrj, maxGapFillPasses: 4 };
}
filterGlobalRectDiffNodesFromVisualization({ visualization: e50 }) {
return { ...e50, rects: H9({ rects: e50.rects, components: this.normalizedInput.components }) };
}
};
var F6 = (e50, t7) => {
if (e50)
return Object.entries(t7).sort(([e54], [t8]) => t8.length - e54.length).find(([t8]) => e50.includes(t8))?.[1];
};
var j6 = (e50, t7) => ({ ...e50, points: e50.points?.map((e54) => ({ ...e54, color: F6(e54.label, t7) ?? e54.color })), lines: e50.lines?.map((e54) => ({ ...e54, strokeColor: F6(e54.label, t7) ?? e54.strokeColor })), circles: e50.circles?.map((e54) => {
const n7 = F6(e54.label, t7);
return n7 ? { ...e54, fill: n7, stroke: n7 } : e54;
}) });
var $6 = class extends ai {
constructor(e50) {
super(), this.topologyPlanningSolver = e50, this.solved = e50.solved, this.failed = e50.failed, this.error = e50.error, this.stats = e50.stats;
}
topologyPlanningSolver;
getOutput() {
return this.topologyPlanningSolver.getOutput().componentMeshNodes.flat();
}
visualize() {
return this.topologyPlanningSolver.finalVisualize() ?? this.topologyPlanningSolver.visualize();
}
preview() {
return this.visualize();
}
};
var Y6 = class {
MAX_ITERATIONS = 1e5;
solved = false;
failed = false;
iterations = 0;
progress = 0;
error = null;
activeSubSolver;
failedSubSolvers;
timeToSolve;
stats = {};
_setupDone = false;
getSolverName() {
return this.constructor.name;
}
setup() {
this._setupDone || (this._setup(), this._setupDone = true);
}
_setup() {}
step() {
if (this._setupDone || this.setup(), !this.solved && !this.failed) {
this.iterations++;
try {
this._step();
} catch (e50) {
throw this.error = `${this.getSolverName()} error: ${e50}`, this.failed = true, e50;
}
!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 = true), "computeProgress" in this && (this.progress = this.computeProgress());
}
}
_step() {}
getConstructorParams() {
throw new Error("getConstructorParams not implemented");
}
getOutput() {
return null;
}
solve() {
const e50 = Date.now();
for (;!this.solved && !this.failed; )
this.step();
const t7 = Date.now();
this.timeToSolve = t7 - e50;
}
visualize() {
return { lines: [], points: [], rects: [], circles: [] };
}
tryFinalAcceptance() {}
preview() {
return { lines: [], points: [], rects: [], circles: [] };
}
};
var X6 = (e50) => e50.filter((e54) => Boolean(e54));
var W6 = (e50, t7, n7) => {
const o7 = `${Math.round(100 * e50.x)},${Math.round(100 * e50.y)}`, i7 = t7.map((e54) => ((e58, t8) => e58 === "top" ? 0 : e58 === "bottom" ? t8 - 1 : Number.parseInt(e58.slice(5), 10))(e54, n7)).sort().join("-");
return `${o7}:${i7}`;
};
var V6 = class {
parent = new Map;
cachedObstacles;
canonicalSetsByAliases = new Map;
constructor(e50, t7 = e50.traces ?? [], n7 = {}) {
for (const t8 of e50.connections)
this.unionAll(X6([t8.name, t8.source_trace_id, t8.rootConnectionName, t8.netConnectionName, ...t8.mergedConnectionNames ?? [], ...t8.pointsToConnect.flatMap((t10) => [t10.pointId, t10.pcb_port_id, ...n7.includePhysicalPositionAliases ? [W6(t10, t10.layers ?? [t10.layer], e50.layerCount)] : []])]));
for (const n8 of [...t7, ...e50.fixedTraces ?? []])
this.unionAll(X6([n8.pcb_trace_id, n8.connection_name, n8.source_trace_id, n8.rootConnectionName, ...n8.mergedConnectionNames ?? [], ...n8.connectsTo ?? []]));
for (const t8 of e50.obstacles)
this.unionAll(n7.includePhysicalPositionAliases ? X6([t8.obstacleId, ...t8.connectedTo, ...t8.offBoardConnectsTo ?? [], W6(t8.center, t8.layers, e50.layerCount)]) : t8.connectedTo);
this.setCacheableObstacles(e50.obstacles);
}
setCacheableObstacles(e50) {
if (this.cachedObstacles !== e50) {
this.cachedObstacles = e50, this.canonicalSetsByAliases.clear();
for (const t7 of e50)
this.canonicalSetsByAliases.set(t7.connectedTo, null);
}
}
canonicalize(e50) {
return [...new Set(e50.map((e54) => this.find(e54)))];
}
canonicalizeToSet(e50) {
const t7 = this.canonicalSetsByAliases.get(e50);
if (t7 && e50.length === t7.aliases.length && e50.every((e54, n8) => e54 === t7.aliases[n8]))
return t7.canonicalNames;
const n7 = new Set(this.canonicalize(e50));
return this.canonicalSetsByAliases.has(e50) && this.canonicalSetsByAliases.set(e50, { aliases: [...e50], canonicalNames: n7 }), n7;
}
unionAll(e50) {
const t7 = e50[0];
if (t7) {
this.add(t7);
for (let n7 = 1;n7 < e50.length; n7++)
this.union(t7, e50[n7]);
}
}
add(e50) {
this.parent.has(e50) || this.parent.set(e50, e50);
}
find(e50) {
this.add(e50);
const t7 = this.parent.get(e50);
if (t7 === e50)
return e50;
const n7 = this.find(t7);
return this.parent.set(e50, n7), n7;
}
union(e50, t7) {
const n7 = this.find(e50), o7 = this.find(t7);
n7 !== o7 && this.parent.set(o7, n7);
}
};
var H6 = 0.000001;
var G6 = (e50, t7) => Math.hypot(t7.x - e50.x, t7.y - e50.y);
var U6 = (e50, t7, n7) => {
const o7 = n7.x - t7.x, i7 = n7.y - t7.y, r7 = o7 * o7 + i7 * i7;
if (r7 <= 0.000000000001)
return G6(e50, t7);
const s7 = q6(((e50.x - t7.x) * o7 + (e50.y - t7.y) * i7) / r7, 0, 1);
return Math.hypot(e50.x - (t7.x + o7 * s7), e50.y - (t7.y + i7 * s7));
};
var Z6 = (e50, t7, n7 = 0.000001) => Math.abs(e50.x - t7.x) <= n7 && Math.abs(e50.y - t7.y) <= n7;
var q6 = (e50, t7, n7) => Math.max(t7, Math.min(n7, e50));
var J6 = (e50, t7, n7) => (t7.x - e50.x) * (n7.y - e50.y) - (t7.y - e50.y) * (n7.x - e50.x);
var Q6 = (e50, t7, n7) => Math.abs(J6(t7, n7, e50)) <= 0.000000001 && e50.x >= Math.min(t7.x, n7.x) - 0.000000001 && e50.x <= Math.max(t7.x, n7.x) + 0.000000001 && e50.y >= Math.min(t7.y, n7.y) - 0.000000001 && e50.y <= Math.max(t7.y, n7.y) + 0.000000001;
var K6 = (e50, t7, n7, o7) => ((e54, t8, n8, o8) => {
const i7 = J6(e54, t8, n8), r7 = J6(e54, t8, o8), s7 = J6(n8, o8, e54), a7 = J6(n8, o8, t8);
return i7 * r7 < 0 && s7 * a7 < 0 || Math.abs(i7) <= 0.000000001 && Q6(n8, e54, t8) || Math.abs(r7) <= 0.000000001 && Q6(o8, e54, t8) || Math.abs(s7) <= 0.000000001 && Q6(e54, n8, o8) || Math.abs(a7) <= 0.000000001 && Q6(t8, n8, o8);
})(e50, t7, n7, o7) ? 0 : Math.min(U6(e50, n7, o7), U6(t7, n7, o7), U6(n7, e50, t7), U6(o7, e50, t7));
var e82 = (e50, t7) => {
let n7 = false;
for (let o7 = 0, i7 = t7.length - 1;o7 < t7.length; i7 = o7++) {
const r7 = t7[o7], s7 = t7[i7];
if (Q6(e50, s7, r7))
return true;
r7.y > e50.y != s7.y > e50.y && e50.x < (s7.x - r7.x) * (e50.y - r7.y) / (s7.y - r7.y) + r7.x && (n7 = !n7);
}
return n7;
};
var t8 = (e50, t7, n7) => {
if (e82(e50, n7) || e82(t7, n7))
return 0;
let o7 = Number.POSITIVE_INFINITY;
for (let i7 = 0;i7 < n7.length; i7++) {
const r7 = n7[i7], s7 = n7[(i7 + 1) % n7.length];
o7 = Math.min(o7, K6(e50, t7, r7, s7));
}
return o7;
};
function n8(e50, t7, n7) {
let o7 = 0, i7 = 1;
const r7 = t7.x - e50.x, s7 = t7.y - e50.y, a7 = [[-r7, e50.x - n7.minX], [r7, n7.maxX - e50.x], [-s7, e50.y - n7.minY], [s7, n7.maxY - e50.y]];
for (const [e54, t10] of a7) {
if (Math.abs(e54) < 0.000000000001) {
if (t10 < 0)
return false;
continue;
}
const n10 = t10 / e54;
if (e54 < 0 ? o7 = Math.max(o7, n10) : i7 = Math.min(i7, n10), o7 > i7)
return false;
}
return true;
}
function o8({ start: e50, end: t7, width: n7, base: o7 }) {
const i7 = G6(e50, t7), r7 = ((e54) => q6(1.25 * e54, 0.25, 0.75))(n7), s7 = Math.max(1, Math.ceil(i7 / r7)), a7 = n7 / 2, c7 = [];
for (let i8 = 0;i8 < s7; i8++) {
const r8 = i8 / s7, l7 = (i8 + 1) / s7, h7 = e50.x + (t7.x - e50.x) * r8, d7 = e50.y + (t7.y - e50.y) * r8, u7 = e50.x + (t7.x - e50.x) * l7, p7 = e50.y + (t7.y - e50.y) * l7;
c7.push({ ...o7, minX: Math.min(h7, u7) - a7, minY: Math.min(d7, p7) - a7, maxX: Math.max(h7, u7) + a7, maxY: Math.max(d7, p7) + a7, exactShape: { type: "segment", start: { x: h7, y: d7 }, end: { x: u7, y: p7 }, width: n7 } });
}
return c7;
}
var i8 = (e50, t7, n7) => {
const o7 = Math.cos(n7), i7 = Math.sin(n7), r7 = e50.x - t7.x, s7 = e50.y - t7.y;
return { x: t7.x + r7 * o7 - s7 * i7, y: t7.y + r7 * i7 + s7 * o7 };
};
var r8 = class {
nodeIndices = [];
priorities = [];
get size() {
return this.nodeIndices.length;
}
push(e50, t7) {
let n7 = this.nodeIndices.length;
for (this.nodeIndices.push(e50), this.priorities.push(t7);n7 > 0; ) {
const e54 = n7 - 1 >> 1;
if (this.priorities[e54] <= t7)
break;
this.swap(n7, e54), n7 = e54;
}
}
pop() {
const e50 = this.nodeIndices[0], t7 = this.nodeIndices.pop(), n7 = this.priorities.pop();
if (this.nodeIndices.length === 0)
return e50;
this.nodeIndices[0] = t7, this.priorities[0] = n7;
let o7 = 0;
for (;; ) {
const e54 = 2 * o7 + 1, t10 = e54 + 1;
if (e54 >= this.nodeIndices.length)
break;
let n10 = e54;
if (t10 < this.nodeIndices.length && this.priorities[t10] < this.priorities[e54] && (n10 = t10), this.priorities[o7] <= this.priorities[n10])
break;
this.swap(o7, n10), o7 = n10;
}
return e50;
}
swap(e50, t7) {
[this.nodeIndices[e50], this.nodeIndices[t7]] = [this.nodeIndices[t7], this.nodeIndices[e50]], [this.priorities[e50], this.priorities[t7]] = [this.priorities[t7], this.priorities[e50]];
}
};
var s8 = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]];
var a8 = ["#d53535", "#3478c8", "#8e44ad", "#15956f"];
var c8 = class extends Y6 {
problem;
searchBounds;
rows;
columns;
origin;
nodes = [];
open = new r8;
bestCost = new Map;
closed = new Set;
baseStateCount;
stateSpaceUpperBound;
endLayerIndices;
targetCell;
segmentWidthCache = new Map;
closedStateCount = 0;
output = null;
constructor(e50) {
super(), this.problem = e50;
const t7 = Math.max(e50.traceWidth, e50.viaDiameter) / 2 + e50.obstacleIndex.clearance, n7 = q6(Math.min(e50.start.x, e50.end.x) - e50.searchPadding, e50.bounds.minX + t7, e50.bounds.maxX - t7), o7 = q6(Math.max(e50.start.x, e50.end.x) + e50.searchPadding, e50.bounds.minX + t7, e50.bounds.maxX - t7), i7 = q6(Math.min(e50.start.y, e50.end.y) - e50.searchPadding, e50.bounds.minY + t7, e50.bounds.maxY - t7), r7 = q6(Math.max(e50.start.y, e50.end.y) + e50.searchPadding, e50.bounds.minY + t7, e50.bounds.maxY - t7), s7 = Math.floor((n7 - e50.gridOffset.x) / e50.gridSize) * e50.gridSize + e50.gridOffset.x, a7 = Math.floor((i7 - e50.gridOffset.y) / e50.gridSize) * e50.gridSize + e50.gridOffset.y;
this.origin = { x: s7, y: a7 }, this.columns = Math.max(2, Math.floor((o7 - s7) / e50.gridSize) + 1), this.rows = Math.max(2, Math.floor((r7 - a7) / e50.gridSize) + 1), this.searchBounds = { minX: s7, minY: a7, maxX: s7 + (this.columns - 1) * e50.gridSize, maxY: a7 + (this.rows - 1) * e50.gridSize };
const c7 = this.rows * this.columns * e50.layers.length * (e50.maxViaCount + 1);
this.baseStateCount = c7, this.stateSpaceUpperBound = c7 * (this.rows * this.columns + 1), this.targetCell = this.pointToCell(e50.end), this.endLayerIndices = new Set(e50.endLayers.map((t10) => e50.layers.indexOf(t10)).filter((e54) => e54 >= 0));
const l7 = this.pointToCell(e50.start);
for (const t10 of e50.startLayers) {
const n10 = e50.layers.indexOf(t10);
if (n10 < 0 || this.endpointCollides(e50.start, n10))
continue;
const o10 = { ...l7, ...e50.start, layerIndex: n10, viaCount: 0, viaPoints: [], g: 0, f: this.heuristic(e50.start), parentIndex: -1 }, i10 = this.nodes.length;
this.nodes.push(o10), this.open.push(i10, o10.f), this.bestCost.set(this.toStateIndex(o10), 0);
}
this.open.size !== 0 && this.endLayerIndices.size !== 0 || (this.failed = true, this.error = "No collision-free multilayer route endpoint"), this.MAX_ITERATIONS = Math.min(15000, Math.max(2000, 2 * c7)), this.stats = this.createStats();
}
getSolverName() {
return `LayerAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`;
}
_step() {
if (this.open.size === 0)
return this.failed = true, void (this.error = "No collision-free multilayer grid route found");
const e50 = this.open.pop(), t7 = this.nodes[e50], n7 = this.toStateIndex(t7);
if (!this.closed.has(n7)) {
if (this.closed.add(n7), this.closedStateCount++, t7.row === this.targetCell.row && t7.column === this.targetCell.column && this.endLayerIndices.has(t7.layerIndex) && t7.viaCount >= this.problem.minViaCount && !this.segmentCollides(t7, this.problem.end))
return this.output = this.reconstructRoute(e50), this.solved = true, void (this.stats = this.createStats());
this.expandPlanarMoves(e50, t7), this.expandViaMoves(e50, t7), this.stats = this.createStats();
}
}
expandPlanarMoves(e50, t7) {
for (const [n7, o7] of s8) {
const i7 = t7.row + n7, r7 = t7.column + o7;
if (i7 < 0 || i7 >= this.rows || r7 < 0 || r7 >= this.columns)
continue;
const s7 = this.cellToPoint(i7, r7), a7 = this.getSafeSegmentWidth(t7, s7);
if (a7 <= 0)
continue;
const c7 = this.problem.gridSize * (n7 !== 0 && o7 !== 0 ? Math.SQRT2 : 1) * Math.max(1, (this.problem.traceWidth / a7) ** this.problem.neckPenaltyExponent);
this.enqueueNode({ row: i7, column: r7, ...s7, layerIndex: t7.layerIndex, viaCount: t7.viaCount, viaPoints: t7.viaPoints, g: t7.g + c7, parentIndex: e50 });
}
}
expandViaMoves(e50, t7) {
if (t7.viaCount >= this.problem.maxViaCount)
return;
const n7 = 0.5 * this.problem.gridSize;
if (G6(t7, this.problem.start) < n7 - 0.000000001 || G6(t7, this.problem.end) < n7 - 0.000000001)
return;
const o7 = t7.parentIndex >= 0 ? this.nodes[t7.parentIndex] : undefined;
if (!o7 || o7.layerIndex === t7.layerIndex || !Z6(o7, t7))
for (let n10 = 0;n10 < this.problem.layers.length; n10++)
n10 !== t7.layerIndex && (this.problem.obstacleIndex.collidesVia({ point: t7, 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: true, sameNetObstacleClearance: 0, otherNewViaPoints: t7.viaPoints, fixedVias: this.problem.fixedVias }) || this.enqueueNode({ row: t7.row, column: t7.column, x: t7.x, y: t7.y, layerIndex: n10, viaCount: t7.viaCount + 1, viaPoints: [...t7.viaPoints, { x: t7.x, y: t7.y }], g: t7.g + this.problem.viaCost, parentIndex: e50 }));
}
enqueueNode(e50) {
const t7 = this.toStateIndex(e50);
if (this.closed.has(t7) || e50.g >= (this.bestCost.get(t7) ?? Number.POSITIVE_INFINITY))
return;
this.bestCost.set(t7, e50.g);
const n7 = e50.g + this.heuristic(e50), o7 = this.nodes.length;
this.nodes.push({ ...e50, f: n7 }), this.open.push(o7, n7);
}
endpointCollides(e50, t7) {
return this.getSafeSegmentWidth({ ...e50, layerIndex: t7, viaCount: 0 }, e50) <= 0;
}
segmentCollides(e50, t7) {
return this.getSafeSegmentWidth(e50, t7) <= 0;
}
getSafeSegmentWidth(e50, t7) {
const n7 = this.problem.layers[e50.layerIndex], o7 = this.problem.startLayers.length === 1 && e50.viaCount === 0 && n7 === this.problem.originalStartLayer && G6(this.problem.start, e50) <= this.problem.maxStartNeckLength + 0.000000001 && G6(this.problem.start, t7) <= this.problem.maxStartNeckLength + 0.000000001, i7 = this.problem.endLayers.length === 1 && n7 === this.problem.originalEndLayer && G6(this.problem.end, e50) <= this.problem.maxEndNeckLength + 0.000000001 && G6(this.problem.end, t7) <= this.problem.maxEndNeckLength + 0.000000001, r7 = Math.max(o7 ? this.problem.startNeckWidth : 0, i7 ? this.problem.endNeckWidth : 0), s7 = [e50.x, e50.y, t7.x, t7.y, e50.layerIndex, e50.viaCount, r7].join(":"), a7 = this.segmentWidthCache.get(s7);
if (a7 !== undefined)
return a7;
const c7 = (o10) => !this.problem.obstacleIndex.collides({ start: e50, end: t7, layer: n7, width: o10, connectionNames: this.problem.connectionNames, ignoreTraceIndex: this.problem.ignoreTraceIndex, ignoreTraceIndices: this.problem.softTraceIndices, ignoreRouteRange: this.problem.ignoreRouteRange, obstacleClearance: this.problem.obstacleClearance });
let l7 = 0;
if (o7 || i7) {
const e54 = 0.025;
let t10 = Math.ceil((r7 - 0.000000001) / e54), n10 = Math.floor((this.problem.traceWidth + 0.000000001) / e54);
for (;t10 <= n10; ) {
const o10 = Math.floor((t10 + n10) / 2), i10 = Number((o10 * e54).toFixed(6));
c7(i10) ? (l7 = i10, t10 = o10 + 1) : n10 = o10 - 1;
}
l7 < r7 - 0.000000001 && c7(r7) && (l7 = r7);
} else
l7 = c7(this.problem.traceWidth) ? this.problem.traceWidth : 0;
return this.segmentWidthCache.set(s7, l7), l7;
}
reconstructRoute(e50) {
const t7 = [];
let n7 = e50;
for (;n7 >= 0; ) {
const e54 = this.nodes[n7];
t7.push(e54), n7 = e54.parentIndex;
}
t7.reverse();
const o7 = t7[t7.length - 1];
Z6(o7, this.problem.end) || t7.push({ ...o7, ...this.problem.end, row: this.targetCell.row, column: this.targetCell.column, parentIndex: -1 });
const i7 = [];
let r7 = [t7[0]];
for (let e54 = 1;e54 < t7.length; e54++) {
const n10 = t7[e54 - 1], o10 = t7[e54];
o10.layerIndex !== n10.layerIndex ? (i7.push(r7), r7 = [o10]) : r7.push(o10);
}
i7.push(r7);
const s7 = [];
for (let e54 = 0;e54 < i7.length; e54++) {
const t10 = this.simplifySection(i7[e54]), n10 = t10.slice(0, -1).map((e58, n11) => this.getSafeSegmentWidth(e58, t10[n11 + 1])), o10 = t10.map((e58, o11) => ({ route_type: "wire", x: e58.x, y: e58.y, layer: this.problem.layers[e58.layerIndex], width: n10.length === 0 ? Math.min(this.problem.startNeckWidth, this.problem.endNeckWidth) : o11 === 0 ? n10[0] : o11 === t10.length - 1 ? n10[n10.length - 1] : Math.min(n10[o11 - 1], n10[o11]) }));
s7.push(...o10);
const r10 = i7[e54 + 1];
if (r10) {
const e58 = this.problem.layers[t10.at(-1).layerIndex], n11 = this.problem.layers[r10[0].layerIndex], o11 = t10.at(-1);
s7.push({ route_type: "via", x: o11.x, y: o11.y, from_layer: e58, to_layer: n11, via_diameter: this.problem.viaDiameter, via_hole_diameter: this.problem.viaHoleDiameter });
}
}
return { route: s7, traceWidth: this.problem.traceWidth, startNeckWidth: this.problem.startNeckWidth, endNeckWidth: this.problem.endNeckWidth, gridSize: this.problem.gridSize, gridOffset: this.problem.gridOffset, viaCount: i7.length - 1 };
}
simplifySection(e50) {
return e50.length <= 2 ? e50 : this.problem.neckPenaltyExponent > 1 ? this.simplifyStrictSection(e50) : this.simplifyWidthPreservingSection(e50);
}
simplifyStrictSection(e50) {
const t7 = e50.slice(0, -1).map((t10, n10) => this.getSafeSegmentWidth(t10, e50[n10 + 1])), n7 = [0];
for (let o10 = 0;o10 < t7.length; o10++)
n7.push(n7[o10] + this.getWidthPenalizedCost(e50[o10], e50[o10 + 1], t7[o10]));
const o7 = [e50[0]];
let i7 = 0;
for (;i7 < e50.length - 1; ) {
let r7 = e50.length - 1;
for (;r7 > i7 + 1 && !this.shortcutPreservesRouteQuality(e50, t7, n7, i7, r7); )
r7--;
o7.push(e50[r7]), i7 = r7;
}
return this.removeRedundantCollinearPoints(o7);
}
shortcutPreservesRouteQuality(e50, t7, n7, o7, i7) {
const r7 = this.getSafeSegmentWidth(e50[o7], e50[i7]);
if (r7 <= 0)
return false;
let s7 = Number.POSITIVE_INFINITY;
for (let e54 = o7;e54 < i7; e54++)
s7 = Math.min(s7, t7[e54]);
const a7 = n7[i7] - n7[o7];
return r7 >= s7 - 0.000000001 && this.getWidthPenalizedCost(e50[o7], e50[i7], r7) <= a7 + 0.000000001;
}
getWidthPenalizedCost(e50, t7, n7) {
return G6(e50, t7) * Math.max(1, (this.problem.traceWidth / n7) ** this.problem.neckPenaltyExponent);
}
simplifyWidthPreservingSection(e50) {
const t7 = e50.slice(0, -1).map((t10, n10) => this.getSafeSegmentWidth(t10, e50[n10 + 1])), n7 = [0];
for (let o10 = 0;o10 < t7.length; o10++)
n7.push(n7[o10] + G6(e50[o10], e50[o10 + 1]) * Math.max(1, (this.problem.traceWidth / t7[o10]) ** this.problem.neckPenaltyExponent));
const o7 = new Float64Array(e50.length).fill(Number.POSITIVE_INFINITY), i7 = new Float64Array(e50.length).fill(Number.POSITIVE_INFINITY), r7 = new Int32Array(e50.length).fill(-1);
o7[0] = 0, i7[0] = 0;
for (let s10 = 1;s10 < e50.length; s10++) {
let a10 = Number.POSITIVE_INFINITY;
for (let c7 = s10 - 1;c7 >= 0; c7--) {
if (a10 = Math.min(a10, t7[c7]), !Number.isFinite(o7[c7]))
continue;
const l7 = this.getSafeSegmentWidth(e50[c7], e50[s10]);
if (l7 < a10 - 0.000000001)
continue;
const h7 = G6(e50[c7], e50[s10]);
if (h7 * Math.max(1, (this.problem.traceWidth / l7) ** this.problem.neckPenaltyExponent) > n7[s10] - n7[c7] + 0.000000001)
continue;
const d7 = o7[c7] + h7 * Math.max(0, this.problem.traceWidth - l7), u7 = i7[c7] + h7;
(d7 < o7[s10] - 0.000000001 || Math.abs(d7 - o7[s10]) <= 0.000000001 && u7 < i7[s10] - 0.000000001) && (o7[s10] = d7, i7[s10] = u7, r7[s10] = c7);
}
}
const s7 = [];
let a7 = e50.length - 1;
for (;a7 >= 0 && (s7.push(e50[a7]), a7 !== 0); )
if (a7 = r7[a7], a7 < 0)
return e50;
return s7.reverse(), this.removeRedundantCollinearPoints(s7);
}
removeRedundantCollinearPoints(e50) {
return e50.filter((e54, t7, n7) => {
if (t7 === 0 || t7 === n7.length - 1)
return true;
const o7 = n7[t7 - 1], i7 = n7[t7 + 1], r7 = (e54.x - o7.x) * (i7.y - e54.y) - (e54.y - o7.y) * (i7.x - e54.x), s7 = Math.abs(this.getSafeSegmentWidth(o7, e54) - this.getSafeSegmentWidth(e54, i7)) < 0.000000001;
return Math.abs(r7) > 0.00000001 || !s7;
});
}
pointToCell(e50) {
return { column: q6(Math.round((e50.x - this.origin.x) / this.problem.gridSize), 0, this.columns - 1), row: q6(Math.round((e50.y - this.origin.y) / this.problem.gridSize), 0, this.rows - 1) };
}
cellToPoint(e50, t7) {
return { x: this.origin.x + t7 * this.problem.gridSize, y: this.origin.y + e50 * this.problem.gridSize };
}
toStateIndex(e50) {
const t7 = ((e50.viaCount * this.problem.layers.length + e50.layerIndex) * this.rows + e50.row) * this.columns + e50.column;
if (e50.viaCount !== 1 || e50.viaPoints.length === 0 || G6(e50, e50.viaPoints[0]) >= this.problem.viaHoleDiameter + this.problem.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance - 0.000000001)
return t7;
const n7 = this.pointToCell(e50.viaPoints[0]);
return t7 + (1 + n7.row * this.columns + n7.column) * this.baseStateCount;
}
heuristic(e50) {
return G6(e50, 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(0.99, this.iterations / this.MAX_ITERATIONS);
}
getOutput() {
return this.output;
}
getConstructorParams() {
const { obstacleIndex: e50, ...t7 } = this.problem;
return [t7];
}
visualize() {
const e50 = this.nodes.filter((e54) => this.closed.has(this.toStateIndex(e54))).slice(-2e3).map((e54) => ({ x: e54.x, y: e54.y, color: `${a8[e54.layerIndex % a8.length]}55` })), t7 = [], n7 = [], o7 = this.output?.route ?? [];
for (let e54 = 0;e54 < o7.length - 1; e54++) {
const i7 = o7[e54], r7 = o7[e54 + 1];
if (i7?.route_type === "wire" && r7?.route_type === "wire" && i7.layer === r7.layer) {
const e58 = this.problem.layers.indexOf(i7.layer);
t7.push({ points: [i7, r7], strokeColor: a8[e58 % a8.length] ?? "#333", strokeWidth: i7.width });
}
i7?.route_type === "via" && n7.push({ center: i7, radius: (i7.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: [...e50, { ...this.problem.start, color: "green", label: "reroute start" }, { ...this.problem.end, color: "purple", label: "reroute target" }], lines: t7, circles: n7, texts: [] };
}
};
var l8 = [{ direction: 1, strength: 0.7 }, { direction: -1, strength: 0.7 }, { direction: 1, strength: 1 }, { direction: -1, strength: 1 }];
var h8 = (e50, t7, n7) => {
const o7 = n7.x - t7.x, i7 = n7.y - t7.y, r7 = o7 * o7 + i7 * i7;
if (r7 <= 0.000000000001)
return { ...t7 };
const s7 = q6(((e50.x - t7.x) * o7 + (e50.y - t7.y) * i7) / r7, 0, 1);
return { x: t7.x + o7 * s7, y: t7.y + i7 * s7 };
};
var d8 = class extends Y6 {
problem;
phase = "prepare-candidate";
variantCursor = 0;
relaxationIteration = 0;
candidatePoints = [];
sampledPoints;
output = null;
constructor(e50) {
super(), this.problem = e50, 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 >= l8.length)
return this.failed = true, void (this.error = "No collision-free elastic displacement found");
this.candidatePoints = this.sampledPoints.map((e50) => ({ ...e50 })), 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 e50 = this.simplifyCandidate(this.candidatePoints);
this.pathCollides(e50) ? (this.variantCursor++, this.phase = "prepare-candidate") : (this.output = { points: e50, traceWidth: this.problem.traceWidth }, this.phase = "complete");
break;
}
case "complete":
this.solved = true;
}
this.stats = this.createStats();
}
sampleRoute() {
const e50 = [], t7 = q6(2 * this.problem.traceWidth, 0.2, 0.45), n7 = this.problem.trace.route;
for (let o7 = this.problem.range.startIndex;o7 < this.problem.range.endIndex; o7++) {
const i7 = n7[o7], r7 = n7[o7 + 1];
if (i7?.route_type !== "wire" || r7?.route_type !== "wire" || i7.layer !== r7.layer)
continue;
e50.length === 0 && e50.push({ x: i7.x, y: i7.y });
const s7 = G6(i7, r7), a7 = Math.max(1, Math.ceil(s7 / t7));
for (let t10 = 1;t10 <= a7; t10++) {
const n10 = t10 / a7;
e50.push({ x: i7.x + (r7.x - i7.x) * n10, y: i7.y + (r7.y - i7.y) * n10 });
}
}
return e50;
}
relaxCandidate() {
const e50 = l8[this.variantCursor], t7 = this.candidatePoints.map((e54) => ({ ...e54 })), n7 = new Uint8Array(this.candidatePoints.length);
for (let o7 = 1;o7 < this.candidatePoints.length - 1; o7++) {
const i7 = this.candidatePoints[o7], r7 = this.findNearestCorridorSegment(i7);
if (!r7)
continue;
const s7 = G6(r7.segment.start, r7.segment.end);
if (s7 <= 0.000000001)
continue;
const a7 = r7.segment.width / 2 + this.problem.traceWidth / 2 + this.problem.obstacleIndex.clearance + 0.025;
if (r7.distance > a7 + 0.35)
continue;
const c7 = { x: (r7.segment.start.y - r7.segment.end.y) / s7 * e50.direction, y: (r7.segment.end.x - r7.segment.start.x) / s7 * e50.direction }, l7 = a7 - ((i7.x - r7.closest.x) * c7.x + (i7.y - r7.closest.y) * c7.y);
if (l7 <= 0)
continue;
const h7 = Math.min(0.35, l7 * e50.strength);
t7[o7] = { x: i7.x + c7.x * h7, y: i7.y + c7.y * h7 }, n7[o7] = 1;
}
for (let e54 = 1;e54 < t7.length - 1; e54++) {
if (!n7[e54])
continue;
const o7 = t7[e54 - 1], i7 = t7[e54], r7 = t7[e54 + 1];
t7[e54] = { x: 0.85 * i7.x + (o7.x + r7.x) / 2 * 0.15, y: 0.85 * i7.y + (o7.y + r7.y) / 2 * 0.15 };
}
this.candidatePoints = t7;
}
findNearestCorridorSegment(e50) {
let t7;
for (const n7 of this.problem.corridor) {
if (n7.layer !== this.problem.layer)
continue;
const o7 = h8(e50, n7.start, n7.end), i7 = G6(e50, o7);
(!t7 || i7 < t7.distance) && (t7 = { segment: n7, closest: o7, distance: i7 });
}
return t7;
}
simplifyCandidate(e50) {
if (e50.length <= 2)
return e50;
const t7 = [e50[0]];
let n7 = 0;
for (;n7 < e50.length - 1; ) {
let o7 = e50.length - 1;
for (;o7 > n7 + 1 && this.segmentCollides(e50[n7], e50[o7]); )
o7--;
t7.push(e50[o7]), n7 = o7;
}
return t7.filter((e54, t10, n10) => t10 === 0 || !Z6(e54, n10[t10 - 1]));
}
pathCollides(e50) {
if (e50.length < 2)
return true;
for (let t7 = 0;t7 < e50.length - 1; t7++)
if (this.segmentCollides(e50[t7], e50[t7 + 1]))
return true;
return false;
}
segmentCollides(e50, t7) {
return this.problem.obstacleIndex.collides({ start: e50, end: t7, layer: this.problem.layer, width: this.problem.traceWidth, connectionNames: this.problem.connectionNames, ignoreTraceIndex: -1 });
}
createStats() {
const e50 = l8[this.variantCursor];
return { phase: this.phase, direction: e50?.direction, strength: e50?.strength, variantCursor: this.variantCursor, relaxationIteration: this.relaxationIteration, sampledPointCount: this.sampledPoints.length };
}
computeProgress() {
return Math.min(0.99, (this.variantCursor + this.relaxationIteration / 12) / l8.length);
}
getOutput() {
return this.output;
}
getConstructorParams() {
return [this.problem];
}
visualize() {
return { coordinateSystem: "cartesian", title: `Elastic trace push: ${this.phase}`, lines: [...this.problem.corridor.map((e50) => ({ points: [e50.start, e50.end], strokeColor: "rgba(255, 128, 0, 0.6)", strokeWidth: e50.width })), ...this.candidatePoints.length > 1 ? [{ points: this.candidatePoints, strokeColor: "#1769d2", strokeWidth: this.problem.traceWidth }] : []], points: [], rects: [], circles: [], texts: [] };
}
};
var u8 = (e50, t7) => {
const n7 = Math.abs(t7.x - e50.x), o7 = Math.abs(t7.y - e50.y);
return n7 <= H6 || o7 <= H6 || Math.abs(n7 - o7) <= H6;
};
var p8 = (e50) => {
let t7 = 0;
for (let n7 = 0;n7 < e50.length - 1; n7++)
u8(e50[n7], e50[n7 + 1]) || t7++;
return t7;
};
var m8 = (e50) => {
let t7 = 0;
for (let n7 = 0;n7 < e50.length - 1; n7++)
t7 += G6(e50[n7], e50[n7 + 1]);
return t7;
};
var g8 = (e50) => e50.filter((t7, n7) => n7 === 0 || !Z6(t7, e50[n7 - 1]));
var f8 = (e50, t7) => {
const n7 = t7.x - e50.x, o7 = t7.y - e50.y, i7 = Math.abs(n7), r7 = Math.abs(o7), s7 = Math.sign(n7), a7 = Math.sign(o7), c7 = [];
u8(e50, t7) && c7.push([e50, t7]), c7.push([e50, { x: t7.x, y: e50.y }, t7], [e50, { x: e50.x, y: t7.y }, t7]), i7 >= r7 ? c7.push([e50, { x: t7.x - s7 * r7, y: e50.y }, t7], [e50, { x: e50.x + s7 * r7, y: t7.y }, t7]) : c7.push([e50, { x: e50.x, y: t7.y - a7 * i7 }, t7], [e50, { x: t7.x, y: e50.y + a7 * i7 }, t7]);
const l7 = new Map;
for (const e54 of c7) {
const t10 = g8(e54);
if (t10.length < 2 || t10.some((e58, n11) => n11 < t10.length - 1 && !u8(e58, t10[n11 + 1])))
continue;
const n10 = t10.map((e58) => `${e58.x.toFixed(6)},${e58.y.toFixed(6)}`).join(";");
l7.set(n10, t10);
}
return [...l7.values()].sort((e54, t10) => m8(e54) - m8(t10) || e54.length - t10.length);
};
var _8 = class {
nodeIndices = [];
priorities = [];
get size() {
return this.nodeIndices.length;
}
push(e50, t7) {
let n7 = this.nodeIndices.length;
for (this.nodeIndices.push(e50), this.priorities.push(t7);n7 > 0; ) {
const e54 = n7 - 1 >> 1;
if (this.priorities[e54] <= t7)
break;
this.swap(n7, e54), n7 = e54;
}
}
pop() {
const e50 = this.nodeIndices[0], t7 = this.nodeIndices.pop(), n7 = this.priorities.pop();
if (this.nodeIndices.length === 0)
return e50;
this.nodeIndices[0] = t7, this.priorities[0] = n7;
let o7 = 0;
for (;; ) {
const e54 = 2 * o7 + 1, t10 = e54 + 1;
if (e54 >= this.nodeIndices.length)
break;
let n10 = e54;
if (t10 < this.nodeIndices.length && this.priorities[t10] < this.priorities[e54] && (n10 = t10), this.priorities[o7] <= this.priorities[n10])
break;
this.swap(o7, n10), o7 = n10;
}
return e50;
}
swap(e50, t7) {
[this.nodeIndices[e50], this.nodeIndices[t7]] = [this.nodeIndices[t7], this.nodeIndices[e50]], [this.priorities[e50], this.priorities[t7]] = [this.priorities[t7], this.priorities[e50]];
}
};
var y8 = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]];
var b8 = class extends Y6 {
problem;
searchBounds;
rows;
columns;
origin;
nodes = [];
open = new _8;
bestCost;
closed;
closedCellCount = 0;
targetCell;
output = null;
constructor(e50) {
super(), this.problem = e50;
const t7 = e50.traceWidth / 2 + e50.obstacleIndex.clearance, n7 = q6(Math.min(e50.start.x, e50.end.x) - e50.searchPadding, e50.bounds.minX + t7, e50.bounds.maxX - t7), o7 = q6(Math.max(e50.start.x, e50.end.x) + e50.searchPadding, e50.bounds.minX + t7, e50.bounds.maxX - t7), i7 = q6(Math.min(e50.start.y, e50.end.y) - e50.searchPadding, e50.bounds.minY + t7, e50.bounds.maxY - t7), r7 = q6(Math.max(e50.start.y, e50.end.y) + e50.searchPadding, e50.bounds.minY + t7, e50.bounds.maxY - t7), s7 = Math.floor((n7 - e50.gridOffset.x) / e50.gridSize) * e50.gridSize + e50.gridOffset.x, a7 = Math.floor((i7 - e50.gridOffset.y) / e50.gridSize) * e50.gridSize + e50.gridOffset.y;
if (this.origin = { x: s7, y: a7 }, this.columns = Math.max(2, Math.floor((o7 - s7) / e50.gridSize) + 1), this.rows = Math.max(2, Math.floor((r7 - a7) / e50.gridSize) + 1), this.searchBounds = { minX: s7, minY: a7, maxX: s7 + (this.columns - 1) * e50.gridSize, maxY: a7 + (this.rows - 1) * e50.gridSize }, this.bestCost = new Float64Array(this.rows * this.columns).fill(Number.POSITIVE_INFINITY), this.closed = new Uint8Array(this.rows * this.columns), this.endpointCollides(e50.start) || this.endpointCollides(e50.end))
return this.failed = true, this.error = "Grid-route endpoint violates obstacle clearance", this.targetCell = { row: 0, column: 0 }, this.MAX_ITERATIONS = 1, void (this.stats = this.createStats());
const c7 = this.pointToCell(e50.start);
this.targetCell = this.pointToCell(e50.end);
const l7 = { ...c7, x: e50.start.x, y: e50.start.y, g: 0, f: this.heuristic(e50.start), parentIndex: -1 };
this.nodes.push(l7), this.open.push(0, l7.f), this.bestCost[this.toFlatIndex(c7.row, c7.column)] = 0, this.MAX_ITERATIONS = Math.min(5000, Math.max(1000, this.rows * this.columns * 2)), this.stats = this.createStats();
}
endpointCollides(e50) {
return this.problem.obstacleIndex.collides({ start: e50, end: e50, 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 (this.open.size === 0)
return this.failed = true, void (this.error = "No collision-free grid route found");
const e50 = this.open.pop(), t7 = this.nodes[e50], n7 = this.toFlatIndex(t7.row, t7.column);
if (!this.closed[n7]) {
if (this.closed[n7] = 1, this.closedCellCount++, t7.row === this.targetCell.row && t7.column === this.targetCell.column && this.getAllowedConnector(t7, this.problem.end) !== null)
return this.output = { points: this.reconstructPath(e50), traceWidth: this.problem.traceWidth, gridSize: this.problem.gridSize, gridOffset: this.problem.gridOffset }, this.solved = true, void (this.stats = this.createStats());
for (const [n10, o7] of y8) {
const i7 = t7.row + n10, r7 = t7.column + o7;
if (i7 < 0 || i7 >= this.rows || r7 < 0 || r7 >= this.columns)
continue;
const s7 = this.toFlatIndex(i7, r7);
if (this.closed[s7])
continue;
const a7 = t7.parentIndex === -1 && this.problem.requireOctilinear;
let c7 = this.problem.gridSize * (n10 !== 0 && o7 !== 0 ? Math.SQRT2 : 1);
if (!a7 && t7.g + c7 >= this.bestCost[s7])
continue;
const l7 = this.cellToPoint(i7, r7), h7 = this.getAllowedConnector(t7, l7);
if (h7 === null)
continue;
a7 && (c7 = m8(h7));
const d7 = t7.g + c7;
if (d7 >= this.bestCost[s7])
continue;
this.bestCost[s7] = d7;
const u7 = d7 + this.heuristic(l7), p7 = this.nodes.length;
this.nodes.push({ row: i7, column: r7, ...l7, g: d7, f: u7, parentIndex: e50 }), this.open.push(p7, u7);
}
this.stats = this.createStats();
}
}
segmentCollides(e50, t7) {
return this.problem.obstacleIndex.collides({ start: e50, end: t7, 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(e50, t7) {
return this.problem.requireOctilinear && (("parentIndex" in e50) && e50.parentIndex === -1 || Z6(t7, this.problem.end)) ? f8(e50, t7).find((e54) => e54.slice(0, -1).every((t10, n7) => !this.segmentCollides(t10, e54[n7 + 1]))) ?? null : this.segmentCollides(e50, t7) ? null : [e50, t7];
}
pointToCell(e50) {
return { column: q6(Math.round((e50.x - this.origin.x) / this.problem.gridSize), 0, this.columns - 1), row: q6(Math.round((e50.y - this.origin.y) / this.problem.gridSize), 0, this.rows - 1) };
}
cellToPoint(e50, t7) {
return { x: this.origin.x + t7 * this.problem.gridSize, y: this.origin.y + e50 * this.problem.gridSize };
}
toFlatIndex(e50, t7) {
return e50 * this.columns + t7;
}
heuristic(e50) {
return Math.hypot(this.problem.end.x - e50.x, this.problem.end.y - e50.y);
}
reconstructPath(e50) {
const t7 = [];
let n7 = e50;
for (;n7 >= 0; ) {
const e54 = this.nodes[n7];
t7.push({ x: e54.x, y: e54.y }), n7 = e54.parentIndex;
}
if (t7.reverse(), Z6(t7[0], this.problem.start) || t7.unshift({ ...this.problem.start }), Z6(t7[t7.length - 1], this.problem.end) || t7.push({ ...this.problem.end }), this.problem.requireOctilinear) {
const e54 = [t7[0]];
for (let n10 = 0;n10 < t7.length - 1; n10++) {
const o10 = t7[n10], i10 = t7[n10 + 1], r7 = n10 === 0 || n10 === t7.length - 2 ? this.getAllowedConnector(n10 === 0 ? { ...o10, parentIndex: -1 } : o10, i10) : [o10, i10];
if (!r7)
return t7;
e54.push(...r7.slice(1));
}
return e54.filter((e58, t10, n10) => {
if (t10 === 0 || t10 === n10.length - 1)
return true;
const o10 = n10[t10 - 1], i10 = n10[t10 + 1], r7 = (e58.x - o10.x) * (i10.y - e58.y) - (e58.y - o10.y) * (i10.x - e58.x);
return Math.abs(r7) > 0.00000001 || !u8(o10, i10);
});
}
const o7 = [t7[0]];
let i7 = 0;
for (;i7 < t7.length - 1; ) {
let e54 = t7.length - 1;
for (;e54 > i7 + 1 && this.segmentCollides(t7[i7], t7[e54]); )
e54--;
o7.push(t7[e54]), i7 = e54;
}
return o7.filter((e54, t10, n10) => {
if (t10 === 0 || t10 === n10.length - 1)
return true;
const o10 = n10[t10 - 1], i10 = n10[t10 + 1], r7 = (e54.x - o10.x) * (i10.y - e54.y) - (e54.y - o10.y) * (i10.x - e54.x);
return Math.abs(r7) > 0.00000001;
});
}
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(0.99, this.iterations / this.MAX_ITERATIONS);
}
getOutput() {
return this.output;
}
getConstructorParams() {
const { obstacleIndex: e50, ...t7 } = this.problem;
return [t7];
}
visualize() {
const e50 = this.nodes.filter((e54) => this.closed[this.toFlatIndex(e54.row, e54.column)]).slice(-2e3).map((e54) => ({ x: e54.x, y: e54.y, color: "rgba(0,90,255,0.22)" })), t7 = 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: [...e50, { ...this.problem.start, color: "green", label: "reroute start" }, { ...this.problem.end, color: "purple", label: "reroute target" }], lines: t7.length > 1 ? [{ points: t7, strokeColor: "#00a050", strokeWidth: this.problem.traceWidth }] : [], circles: [], texts: [] };
}
};
var x8 = class {
items;
clearance;
minPadEdgeToPadEdgeClearance;
holeClearance;
boardEdgeClearance;
boardLayers;
minViaHoleEdgeToViaHoleEdgeClearance;
defaultViaHoleDiameter;
bounds;
maxIndexedViaHoleDiameter;
index;
connectionNameSets;
copperObjectIds;
connectionNameResolver;
connectedPads;
dynamicTraceIndex;
constructor(e50, t7, n7, o7 = [], i7 = new V6(e50, t7)) {
var r7;
this.bounds = e50.bounds, this.boardLayers = (r7 = e50.layerCount, ["top", ...Array.from({ length: Math.max(0, r7 - 2) }, (e54, t10) => `inner${t10 + 1}`), ...r7 > 1 ? ["bottom"] : []]), this.dynamicTraceIndex = n7, this.clearance = Math.max(e50.defaultObstacleMargin ?? 0, e50.minTraceToPadEdgeClearance ?? 0, 0.1), this.holeClearance = e50.minTraceToHoleEdgeClearance ?? this.clearance, this.minPadEdgeToPadEdgeClearance = e50.minPadEdgeToPadEdgeClearance ?? this.clearance, this.boardEdgeClearance = e50.minBoardEdgeClearance ?? this.clearance, this.minViaHoleEdgeToViaHoleEdgeClearance = Math.max(e50.minViaHoleEdgeToViaHoleEdgeClearance ?? 0, 0.1), this.defaultViaHoleDiameter = e50.min_via_hole_diameter ?? e50.minViaHoleDiameter ?? 0.3, this.items = [...e50.obstacles.flatMap((e54, t10) => function(e58, t11 = 0.6) {
if (e58.isNonPlatedHole && e58.shape === "circle") {
const t12 = e58.width / 2;
return [{ minX: e58.center.x - t12, minY: e58.center.y - t12, maxX: e58.center.x + t12, maxY: e58.center.y + t12, layers: e58.layers, kind: "obstacle", obstacleKind: "hole", connectionNames: e58.connectedTo, exactShape: { type: "circle", center: e58.center, radius: t12 } }];
}
const n10 = (e58.ccwRotationDegrees ?? 0) * Math.PI / 180, o10 = Math.max(1, Math.ceil(e58.width / t11)), i10 = Math.max(1, Math.ceil(e58.height / t11)), r10 = e58.width / o10, s10 = e58.height / i10, a7 = [];
for (let t12 = 0;t12 < i10; t12++)
for (let i11 = 0;i11 < o10; i11++) {
const o11 = { x: e58.center.x - e58.width / 2 + (i11 + 0.5) * r10, y: e58.center.y - e58.height / 2 + (t12 + 0.5) * s10 }, c7 = r10 / 2, l7 = s10 / 2, h7 = [{ x: o11.x - c7, y: o11.y - l7 }, { x: o11.x + c7, y: o11.y - l7 }, { x: o11.x + c7, y: o11.y + l7 }, { x: o11.x - c7, y: o11.y + l7 }].map((t13) => i8(t13, e58.center, n10));
a7.push({ minX: Math.min(...h7.map((e59) => e59.x)), minY: Math.min(...h7.map((e59) => e59.y)), maxX: Math.max(...h7.map((e59) => e59.x)), maxY: Math.max(...h7.map((e59) => e59.y)), layers: e58.layers, kind: "obstacle", obstacleKind: e58.isNonPlatedHole ? "hole" : e58.connectedTo[0]?.startsWith("pcb_via_") ? "via" : e58.connectedTo[0]?.startsWith("pcb_smtpad_") || e58.connectedTo[0]?.startsWith("pcb_plated_hole_") ? "pad" : "other", connectionNames: e58.connectedTo, exactShape: { type: "polygon", points: h7 } });
}
return a7;
}(e54).map((e58) => ({ ...e58, copperObjectId: `obstacle:${t10}` }))), ...this.createTraceItems(e50.fixedTraces ?? [], true), ...this.createTraceItems(t7), ...o7], this.maxIndexedViaHoleDiameter = this.items.reduce((e54, t10) => t10.kind === "via" ? Math.max(e54, t10.viaHoleDiameter ?? this.defaultViaHoleDiameter) : e54, this.defaultViaHoleDiameter), this.connectionNameResolver = i7, i7.setCacheableObstacles(e50.obstacles);
const s7 = new Map;
this.connectionNameSets = this.items.map((e54) => {
let t10 = s7.get(e54.connectionNames);
return t10 || (t10 = i7.canonicalizeToSet(e54.connectionNames), s7.set(e54.connectionNames, t10)), t10;
}), this.copperObjectIds = this.items.map((e54, t10) => e54.copperObjectId ?? `indexed-item:${t10}`), this.connectedPads = e50.obstacles.flatMap((e54) => e54.connectedTo.some((e58) => e58.startsWith("pcb_smtpad_") || e58.startsWith("pcb_plated_hole_")) ? [{ obstacle: e54, canonicalConnectionNames: i7.canonicalizeToSet(e54.connectedTo) }] : []), this.index = this.items.length > 0 ? new je(this.items.length) : null;
for (const e54 of this.items)
this.index.add(e54.minX, e54.minY, e54.maxX, e54.maxY);
this.index?.finish();
}
createTraceItems(e50, t7 = false) {
const n7 = [];
for (let o7 = 0;o7 < e50.length; o7++) {
const i7 = e50[o7], r7 = t7 ? undefined : o7, s7 = `${t7 ? "fixed-trace" : "trace"}:${o7}`, a7 = !t7 && o7 === this.dynamicTraceIndex, c7 = [i7.connection_name, i7.source_trace_id, i7.rootConnectionName, ...i7.mergedConnectionNames ?? [], ...i7.connectsTo ?? []].filter((e54) => Boolean(e54));
for (let e54 = 0;e54 < i7.route.length; e54++) {
const t10 = i7.route[e54];
if (t10.route_type === "via") {
const o11 = t10.via_diameter ?? 0.6;
n7.push({ minX: t10.x - o11 / 2, minY: t10.y - o11 / 2, maxX: t10.x + o11 / 2, maxY: t10.y + o11 / 2, layers: this.boardLayers, kind: "via", connectionNames: c7, copperObjectId: s7, traceIndex: r7, routeStartIndex: e54, routeEndIndex: e54, viaHoleDiameter: t10.via_hole_diameter ?? this.defaultViaHoleDiameter, exactShape: { type: "circle", center: { x: t10.x, y: t10.y }, radius: o11 / 2 } });
continue;
}
if (a7)
continue;
const o10 = i7.route[e54 + 1];
t10.route_type === "wire" && o10?.route_type === "wire" && t10.layer === o10.layer && n7.push(...o8({ start: t10, end: o10, width: t10.width, base: { layers: [t10.layer], kind: "trace", connectionNames: c7, copperObjectId: s7, traceIndex: r7, routeStartIndex: e54, routeEndIndex: e54 + 1 } }));
}
}
return n7;
}
collides(e50) {
if (this.isOutsideBounds(e50))
return true;
const { radius: t7, candidates: n7, canonicalConnectionNames: o7 } = this.getCollisionCandidates(e50);
for (const i7 of n7)
if (this.itemCollides(i7, e50, t7, o7))
return true;
return false;
}
findCollisions(e50) {
const { radius: t7, candidates: n7, canonicalConnectionNames: o7 } = this.getCollisionCandidates(e50), i7 = [];
for (const r7 of n7)
this.itemCollides(r7, e50, t7, o7) && i7.push(this.items[r7]);
return i7;
}
getSameNetCopperContactIds(e50) {
const t7 = e50.width / 2, n7 = this.index?.search(Math.min(e50.start.x, e50.end.x) - t7, Math.min(e50.start.y, e50.end.y) - t7, Math.max(e50.start.x, e50.end.x) + t7, Math.max(e50.start.y, e50.end.y) + t7) ?? [], o7 = new Set(this.connectionNameResolver.canonicalize(e50.connectionNames)), i7 = new Set;
for (const r7 of n7) {
const n10 = this.items[r7];
n10.layers.includes(e50.layer) && (n10.traceIndex === e50.ignoreTraceIndex || e50.ignoreTraceIndices?.includes(n10.traceIndex ?? -1) || [...this.connectionNameSets[r7]].some((e54) => o7.has(e54)) && this.itemCopperTouches(n10, e50, t7) && i7.add(this.copperObjectIds[r7]));
}
return i7;
}
getConnectedPadWidthLimit(e50) {
if (Math.hypot(e50.end.x - e50.start.x, e50.end.y - e50.start.y) <= 0.00001)
return null;
const t7 = this.getConnectedPadWidthLimitAtPoint(e50, e50.start), n7 = this.getConnectedPadWidthLimitAtPoint(e50, e50.end);
return t7 === null ? n7 : n7 === null ? t7 : Math.min(t7, n7);
}
getConnectedPadWidthLimitAtPoint(e50, t7) {
const n7 = this.getConnectedPadsAtPoint(e50, t7);
return n7.length === 0 ? null : Math.max(...n7.map(({ obstacle: t10 }) => this.getPadWidthNormalToQuery(t10, e50)));
}
getConnectedPadEndpointWidthLimitAtPoint(e50, t7) {
const n7 = this.getConnectedPadsAtPoint(e50, t7);
return n7.length === 0 ? null : Math.max(...n7.map(({ obstacle: e54 }) => {
const n10 = this.getObstacleLocalPoint(t7, e54);
return Math.max(0, 2 * Math.min(e54.width / 2 - Math.abs(n10.x), e54.height / 2 - Math.abs(n10.y)));
}));
}
getConnectedPadBoundaryPoint(e50, t7) {
const n7 = t7 === "start" ? e50.start : e50.end, o7 = t7 === "start" ? e50.end : e50.start, i7 = this.getConnectedPadsAtPoint(e50, n7).sort((t10, n10) => this.getPadWidthNormalToQuery(n10.obstacle, e50) - this.getPadWidthNormalToQuery(t10.obstacle, e50))[0];
return !i7 || this.pointIsInsideObstacle(o7, i7.obstacle) ? null : this.getObstacleBoundaryPoint(n7, o7, i7.obstacle);
}
getConnectedPadsAtPoint(e50, t7) {
const n7 = new Set(this.connectionNameResolver.canonicalize(e50.connectionNames));
return this.connectedPads.filter(({ obstacle: o7, canonicalConnectionNames: i7 }) => o7.layers.includes(e50.layer) && [...i7].some((e54) => n7.has(e54)) && this.pointIsInsideObstacle(t7, o7));
}
pointIsInsideObstacle(e50, t7) {
const { x: n7, y: o7 } = this.getObstacleLocalPoint(e50, t7);
return Math.abs(n7) <= t7.width / 2 + 0.000000001 && Math.abs(o7) <= t7.height / 2 + 0.000000001;
}
getObstacleLocalPoint(e50, t7) {
const n7 = -(t7.ccwRotationDegrees ?? 0) * Math.PI / 180, o7 = Math.cos(n7), i7 = Math.sin(n7), r7 = e50.x - t7.center.x, s7 = e50.y - t7.center.y;
return { x: r7 * o7 - s7 * i7, y: r7 * i7 + s7 * o7 };
}
getPadWidthNormalToQuery(e50, t7) {
const n7 = t7.end.x - t7.start.x, o7 = t7.end.y - t7.start.y, i7 = Math.hypot(n7, o7);
if (i7 <= 0.000000001)
return Math.min(e50.width, e50.height);
const r7 = -o7 / i7, s7 = n7 / i7, a7 = -(e50.ccwRotationDegrees ?? 0) * Math.PI / 180, c7 = Math.cos(a7), l7 = Math.sin(a7), h7 = r7 * c7 - s7 * l7, d7 = r7 * l7 + s7 * c7;
return Math.abs(h7) * e50.width + Math.abs(d7) * e50.height;
}
getObstacleBoundaryPoint(e50, t7, n7) {
const o7 = -(n7.ccwRotationDegrees ?? 0) * Math.PI / 180, i7 = Math.cos(o7), r7 = Math.sin(o7), s7 = (e54) => {
const t10 = e54.x - n7.center.x, o10 = e54.y - n7.center.y;
return { x: t10 * i7 - o10 * r7, y: t10 * r7 + o10 * i7 };
}, a7 = s7(e50), c7 = s7(t7), l7 = { x: c7.x - a7.x, y: c7.y - a7.y }, h7 = [];
if (Math.abs(l7.x) > 0.000000000001) {
const e54 = l7.x > 0 ? n7.width / 2 : -n7.width / 2;
h7.push((e54 - a7.x) / l7.x);
}
if (Math.abs(l7.y) > 0.000000000001) {
const e54 = l7.y > 0 ? n7.height / 2 : -n7.height / 2;
h7.push((e54 - a7.y) / l7.y);
}
const d7 = Math.min(...h7.filter((e54) => e54 >= 0 && e54 <= 1));
return Number.isFinite(d7) ? { x: e50.x + (t7.x - e50.x) * d7, y: e50.y + (t7.y - e50.y) * d7 } : null;
}
getConnectedLayersAtPoint(e50, t7) {
const n7 = new Set(this.connectionNameResolver.canonicalize(t7)), o7 = new Set, i7 = this.index?.search(e50.x, e50.y, e50.x, e50.y) ?? [];
for (const t10 of i7) {
const i10 = this.items[t10];
if (i10.kind !== "obstacle")
continue;
if (![...this.connectionNameSets[t10]].some((e54) => n7.has(e54)))
continue;
if (i10.exactShape?.type === "polygon" ? t8(e50, e50, i10.exactShape.points) <= 0.000000001 : i10.exactShape?.type === "circle" ? Math.hypot(i10.exactShape.center.x - e50.x, i10.exactShape.center.y - e50.y) <= i10.exactShape.radius + 0.000000001 : e50.x >= i10.minX - 0.000000001 && e50.x <= i10.maxX + 0.000000001 && e50.y >= i10.minY - 0.000000001 && e50.y <= i10.maxY + 0.000000001)
for (const e54 of i10.layers)
o7.add(e54);
}
return [...o7];
}
collidesVia(e50) {
return this.getViaViolationSignatures(e50).size > 0;
}
getViaViolationSignatures(e50) {
const t7 = new Set;
for (const n10 of e50.layers) {
const o10 = { isVia: true, start: e50.point, end: e50.point, layer: n10, width: e50.padDiameter, connectionNames: e50.connectionNames, ignoreTraceIndex: e50.ignoreTraceIndex, ignoreTraceIndices: e50.ignoreTraceIndices, ignoreRouteRange: e50.ignoreRouteRange, obstacleClearance: e50.obstacleClearance, blockSameNetObstacles: e50.blockSameNetObstacles, sameNetObstacleClearance: e50.sameNetObstacleClearance };
this.isOutsideBounds(o10) && t7.add(`board-edge:${n10}`);
const { radius: i10, candidates: r10, canonicalConnectionNames: s10 } = this.getCollisionCandidates(o10);
for (const e54 of r10)
this.itemCollides(e54, o10, i10, s10) && t7.add(`copper:${n10}:${this.getViolationObjectId(e54)}`);
}
const n7 = e50.holeDiameter + this.minViaHoleEdgeToViaHoleEdgeClearance;
for (const o10 of e50.otherNewViaPoints ?? [])
Math.hypot(o10.x - e50.point.x, o10.y - e50.point.y) < n7 - 0.000000001 && t7.add(`new-via-drill:${o10.x},${o10.y}:${e50.holeDiameter}`);
const o7 = e50.fixedVias ?? [];
for (let n10 = 0;n10 < o7.length; n10++) {
const i10 = o7[n10], r10 = e50.holeDiameter / 2 + i10.holeDiameter / 2 + this.minViaHoleEdgeToViaHoleEdgeClearance;
Math.hypot(i10.point.x - e50.point.x, i10.point.y - e50.point.y) < r10 - 0.000000001 && t7.add(`fixed-via-drill:${n10}:${i10.point.x},${i10.point.y}:${i10.holeDiameter}`);
}
const i7 = e50.holeDiameter / 2 + this.maxIndexedViaHoleDiameter / 2 + this.minViaHoleEdgeToViaHoleEdgeClearance, r7 = this.index?.search(e50.point.x - i7, e50.point.y - i7, e50.point.x + i7, e50.point.y + i7) ?? [], s7 = new Set;
for (const n10 of r7) {
const o10 = this.items[n10];
if (o10.kind !== "via" || o10.exactShape?.type !== "circle")
continue;
if (o10.traceIndex === e50.ignoreTraceIndex && e50.ignoreRouteRange && (o10.routeEndIndex ?? -1) >= e50.ignoreRouteRange.start && (o10.routeStartIndex ?? Number.POSITIVE_INFINITY) <= e50.ignoreRouteRange.end)
continue;
if (e50.ignoreTraceIndices?.includes(o10.traceIndex ?? -1))
continue;
const i10 = `${this.copperObjectIds[n10] ?? "unknown"}:${o10.routeStartIndex ?? -1}`;
if (s7.has(i10))
continue;
s7.add(i10);
const r10 = o10.viaHoleDiameter ?? this.defaultViaHoleDiameter, a7 = e50.holeDiameter / 2 + r10 / 2 + this.minViaHoleEdgeToViaHoleEdgeClearance;
Math.hypot(o10.exactShape.center.x - e50.point.x, o10.exactShape.center.y - e50.point.y) < a7 - 0.000000001 && t7.add(`indexed-via-drill:${this.getViolationObjectId(n10)}`);
}
return t7;
}
getViolationObjectId(e50) {
const t7 = this.items[e50], n7 = this.copperObjectIds[e50], o7 = `${t7.routeStartIndex ?? ""}-${t7.routeEndIndex ?? ""}`;
if (t7.kind === "obstacle")
return n7;
if (t7.exactShape?.type === "segment") {
const { start: e54, end: i7, width: r7 } = t7.exactShape;
return `${n7}:${t7.kind}:${o7}:${e54.x},${e54.y}:${i7.x},${i7.y}:${r7}`;
}
if (t7.exactShape?.type === "circle") {
const { center: e54, radius: i7 } = t7.exactShape;
return `${n7}:${t7.kind}:${o7}:${e54.x},${e54.y}:${i7}`;
}
return t7.exactShape?.type === "polygon" ? `${n7}:${t7.kind}:${o7}:${t7.exactShape.points.map((e54) => `${e54.x},${e54.y}`).join(";")}` : `${n7}:${t7.kind}:${o7}:${t7.minX},${t7.minY},${t7.maxX},${t7.maxY}`;
}
getCollisionCandidates(e50) {
const t7 = Math.max(this.clearance, this.holeClearance, e50.isVia ? this.minPadEdgeToPadEdgeClearance : 0, e50.obstacleClearance ?? this.clearance, e50.sameNetObstacleClearance ?? 0), n7 = e50.width / 2 + t7, o7 = { minX: Math.min(e50.start.x, e50.end.x) - n7, minY: Math.min(e50.start.y, e50.end.y) - n7, maxX: Math.max(e50.start.x, e50.end.x) + n7, maxY: Math.max(e50.start.y, e50.end.y) + n7 };
return { radius: n7, candidates: this.index?.search(o7.minX, o7.minY, o7.maxX, o7.maxY) ?? [], canonicalConnectionNames: this.connectionNameResolver.canonicalize(e50.connectionNames) };
}
itemCollides(e50, t7, n7, o7) {
const i7 = this.items[e50];
if (!i7.layers.includes(t7.layer))
return false;
const r7 = this.connectionNameSets[e50], s7 = o7.some((e54) => r7.has(e54));
if (s7 && (!t7.blockSameNetObstacles || i7.kind !== "obstacle" || i7.obstacleKind === "via"))
return false;
if (i7.kind === "trace" && t7.ignoreTraceIndices?.includes(i7.traceIndex ?? -1))
return false;
if (i7.kind === "trace" && i7.traceIndex === t7.ignoreTraceIndex && t7.ignoreRouteRange && (i7.routeEndIndex ?? -1) >= t7.ignoreRouteRange.start && (i7.routeStartIndex ?? Number.POSITIVE_INFINITY) <= t7.ignoreRouteRange.end)
return false;
const a7 = t7.isVia && (i7.kind === "via" || i7.kind === "obstacle" && i7.obstacleKind === "via") ? this.minPadEdgeToPadEdgeClearance : i7.kind !== "obstacle" || i7.obstacleKind !== "hole" || t7.isVia ? i7.kind === "obstacle" && i7.obstacleKind === "pad" ? s7 && t7.blockSameNetObstacles ? t7.sameNetObstacleClearance ?? t7.obstacleClearance ?? this.clearance : t7.obstacleClearance ?? this.clearance : this.clearance : this.holeClearance, c7 = t7.width / 2 + a7;
return i7.exactShape?.type === "segment" ? K6(t7.start, t7.end, i7.exactShape.start, i7.exactShape.end) <= c7 + i7.exactShape.width / 2 + 0.000000001 : i7.exactShape?.type === "polygon" ? t8(t7.start, t7.end, i7.exactShape.points) <= c7 + 0.000000001 : i7.exactShape?.type === "circle" ? U6(i7.exactShape.center, t7.start, t7.end) <= c7 + i7.exactShape.radius + 0.000000001 : n8(t7.start, t7.end, { minX: i7.minX - c7, minY: i7.minY - c7, maxX: i7.maxX + c7, maxY: i7.maxY + c7 });
}
itemCopperTouches(e50, t7, n7) {
return e50.exactShape?.type === "segment" ? K6(t7.start, t7.end, e50.exactShape.start, e50.exactShape.end) <= n7 + e50.exactShape.width / 2 + 0.000000001 : e50.exactShape?.type === "polygon" ? t8(t7.start, t7.end, e50.exactShape.points) <= n7 + 0.000000001 : e50.exactShape?.type === "circle" ? U6(e50.exactShape.center, t7.start, t7.end) <= n7 + e50.exactShape.radius + 0.000000001 : n8(t7.start, t7.end, { minX: e50.minX - n7, minY: e50.minY - n7, maxX: e50.maxX + n7, maxY: e50.maxY + n7 });
}
isOutsideBounds(e50) {
const t7 = e50.width / 2 + this.boardEdgeClearance;
return Math.min(e50.start.x, e50.end.x) - t7 < this.bounds.minX || Math.max(e50.start.x, e50.end.x) + t7 > this.bounds.maxX || Math.min(e50.start.y, e50.end.y) - t7 < this.bounds.minY || Math.max(e50.start.y, e50.end.y) + t7 > this.bounds.maxY;
}
};
var v8 = [{ x: 0, y: 0 }, { x: 0.5, y: 0 }, { x: 0, y: 0.5 }, { x: 0.5, y: 0.5 }];
var I8 = (e50) => e50?.route_type === "wire";
var S8 = class extends Y6 {
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(e50, t7 = new V6(e50.simpleRouteJson, e50.traces)) {
super(), this.inputProblem = structuredClone(e50), this.traces = structuredClone(e50.traces), this.corridor = structuredClone(e50.corridor), this.mutableTraceIndices = e50.mutableTraceIndices ? new Set(e50.mutableTraceIndices) : null, this.connectionNameResolver = t7, this.blockerIndex = new x8(this.inputProblem.simpleRouteJson, this.traces, e50.powerTraceIndex, [], this.connectionNameResolver), this.activeSubSolver = null, this.MAX_ITERATIONS = 25000, 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 = true : (this.failed = true, this.error = "No locally reroutable trace blocks the power corridor");
}
this.stats = this.createStats();
}
scanNextCorridorSegment() {
const e50 = this.corridor[this.corridorCursor];
if (!e50)
return this.blockers = [...this.blockersByTrace.values()].sort((e54, t10) => e54.traceIndex - t10.traceIndex), void (this.phase = "select-blocker");
const t7 = this.traces[this.inputProblem.powerTraceIndex], n7 = this.blockerIndex.findCollisions({ start: e50.start, end: e50.end, layer: e50.layer, width: e50.width, connectionNames: t7 ? this.getTraceConnectionNames(t7) : [] });
for (const e54 of n7)
this.recordBlockingTrace(e54);
this.corridorCursor++;
}
recordBlockingTrace(e50) {
if (e50.kind !== "trace" || e50.traceIndex === undefined || e50.routeStartIndex === undefined || e50.routeEndIndex === undefined || e50.traceIndex === this.inputProblem.powerTraceIndex || this.mutableTraceIndices !== null && !this.mutableTraceIndices.has(e50.traceIndex))
return;
const t7 = this.traces[e50.traceIndex];
if (!t7)
return;
const n7 = this.findConnectionForTrace(t7);
if ((n7 ? this.resolveNominalTraceWidth(n7) : this.getTraceNominalWidth(t7)) >= (this.inputProblem.pushOnlyNominalWidthsBelow ?? this.inputProblem.nominalPowerWidth) - H6)
return;
const o7 = this.blockersByTrace.get(e50.traceIndex);
if (o7)
return o7.firstRouteIndex = Math.min(o7.firstRouteIndex, e50.routeStartIndex), void (o7.lastRouteIndex = Math.max(o7.lastRouteIndex, e50.routeEndIndex));
this.blockersByTrace.set(e50.traceIndex, { traceIndex: e50.traceIndex, firstRouteIndex: e50.routeStartIndex, lastRouteIndex: e50.routeEndIndex });
}
selectNextBlocker() {
if (this.currentBlocker = this.blockers[this.blockerCursor] ?? null, !this.currentBlocker)
return void (this.phase = "complete");
const e50 = this.findStableAnchorRange(this.currentBlocker);
if (!e50)
return void this.blockerCursor++;
const t7 = this.traces[this.currentBlocker.traceIndex];
this.currentRange = e50, this.currentTraceWidth = this.getRangeWidth(t7, e50), this.gridResolutions = this.getGridResolutions(this.currentTraceWidth), this.resolutionCursor = 0, this.offsetCursor = 0, this.currentObstacleIndex = new x8(this.inputProblem.simpleRouteJson, this.traces, this.currentBlocker.traceIndex, this.createInflatedCorridorItems(), this.connectionNameResolver), this.activeSubSolver = new d8({ trace: t7, range: e50, layer: t7.route[e50.startIndex].layer, traceWidth: this.currentTraceWidth, corridor: this.corridor, obstacleIndex: this.currentObstacleIndex, connectionNames: this.getTraceConnectionNames(t7) }), this.phase = "try-elastic-push";
}
findStableAnchorRange(e50) {
const t7 = this.traces[e50.traceIndex];
if (!t7)
return null;
let { firstRouteIndex: n7, lastRouteIndex: o7 } = e50;
for (;n7 > 0; ) {
const e54 = t7.route[n7];
if (I8(e54) && this.pointClearsCorridor(e54))
break;
n7--;
}
for (;o7 < t7.route.length - 1; ) {
const e54 = t7.route[o7];
if (I8(e54) && this.pointClearsCorridor(e54))
break;
o7++;
}
const i7 = t7.route[n7], r7 = t7.route[o7];
if (!I8(i7) || !I8(r7) || i7.layer !== r7.layer || !this.pointClearsCorridor(i7) || !this.pointClearsCorridor(r7) || n7 >= o7)
return null;
const s7 = { startIndex: n7, endIndex: o7 }, a7 = this.getRangeLength(t7, s7);
return !Number.isFinite(a7) || a7 > (this.inputProblem.maxRerouteLength ?? 10) + H6 ? null : s7;
}
pointClearsCorridor(e50) {
return this.corridor.every((t7) => {
if (t7.layer !== e50.layer)
return true;
const n7 = t7.width / 2 + e50.width / 2 + this.blockerIndex.clearance;
return U6(e50, t7.start, t7.end) >= n7 - H6;
});
}
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 >= v8.length)
return this.resolutionCursor++, void (this.offsetCursor = 0);
const e50 = this.traces[this.currentBlocker.traceIndex], t7 = e50.route[this.currentRange.startIndex], n7 = e50.route[this.currentRange.endIndex];
if (!I8(t7) || !I8(n7))
return this.blockerCursor++, void (this.phase = "select-blocker");
const o7 = this.gridResolutions[this.resolutionCursor], i7 = v8[this.offsetCursor], r7 = this.currentObstacleIndex;
if (!r7)
return this.blockerCursor++, void (this.phase = "select-blocker");
this.attemptedGridCount++, this.activeSubSolver = new b8({ start: t7, end: n7, layer: t7.layer, traceWidth: this.currentTraceWidth, gridSize: o7, gridOffset: { x: i7.x * o7, y: i7.y * o7 }, connectionNames: this.getTraceConnectionNames(e50), obstacleIndex: r7, ignoreTraceIndex: this.currentBlocker.traceIndex, ignoreRouteRange: { start: this.currentRange.startIndex, end: this.currentRange.endIndex }, bounds: this.inputProblem.simpleRouteJson.bounds, searchPadding: q6(2.5 * this.inputProblem.nominalPowerWidth, 1.5, 4) });
}
stepActiveSubSolver() {
const e50 = this.activeSubSolver;
if (e50.step(), e50.solved || e50.failed) {
if (e50.solved) {
const t7 = e50.getOutput();
if (t7)
return this.applyRoute(t7, e50 instanceof d8 ? "elastic" : "grid"), this.activeSubSolver = null, void (this.phase = "complete");
}
this.failedSubSolvers ??= [], this.failedSubSolvers.push(e50), this.activeSubSolver = null, e50 instanceof d8 ? this.phase = "try-grid-candidate" : this.offsetCursor++;
}
}
applyRoute(e50, t7) {
const n7 = this.currentBlocker, o7 = this.currentRange, i7 = this.traces[n7.traceIndex], r7 = i7.route[o7.startIndex], s7 = i7.route[o7.endIndex], a7 = e50.points.map((e54) => ({ route_type: "wire", x: e54.x, y: e54.y, width: this.currentTraceWidth, layer: r7.layer }));
a7[0].width = Math.max(a7[0].width, r7.width), a7[a7.length - 1].width = Math.max(a7[a7.length - 1].width, s7.width), i7.route.splice(o7.startIndex, o7.endIndex - o7.startIndex + 1, ...a7), this.output = { traces: this.traces, pushedTraceIndex: n7.traceIndex, replacedRange: o7, strategy: t7 };
}
createInflatedCorridorItems() {
return this.corridor.flatMap((e50) => o8({ start: e50.start, end: e50.end, width: e50.width, base: { layers: [e50.layer], kind: "obstacle", connectionNames: [] } }));
}
getGridResolutions(e50) {
return [q6(1.5 * e50, 0.1, 0.3), q6(0.75 * e50, 0.08, 0.18)].filter((e54, t7, n7) => n7.findIndex((t10) => Math.abs(t10 - e54) < H6) === t7);
}
getRangeWidth(e50, t7) {
let n7 = this.inputProblem.simpleRouteJson.minTraceWidth;
for (let o7 = t7.startIndex;o7 <= t7.endIndex; o7++) {
const t10 = e50.route[o7];
I8(t10) && (n7 = Math.max(n7, t10.width));
}
return n7;
}
getRangeLength(e50, t7) {
let n7 = 0;
for (let o7 = t7.startIndex;o7 < t7.endIndex; o7++) {
const t10 = e50.route[o7], i7 = e50.route[o7 + 1];
if (!I8(t10) || !I8(i7) || t10.layer !== i7.layer)
return Number.POSITIVE_INFINITY;
n7 += G6(t10, i7);
}
return n7;
}
resolveNominalTraceWidth(e50) {
return Math.max(e50.nominalTraceWidth ?? e50.width ?? this.inputProblem.simpleRouteJson.nominalTraceWidth ?? this.inputProblem.simpleRouteJson.minTraceWidth, this.inputProblem.simpleRouteJson.minTraceWidth);
}
getTraceNominalWidth(e50) {
return e50.route.reduce((e54, t7) => t7.route_type === "wire" ? Math.max(e54, t7.width) : e54, this.inputProblem.simpleRouteJson.minTraceWidth);
}
findConnectionForTrace(e50) {
const t7 = this.connectionByTraceId.get(e50.pcb_trace_id);
if (t7 !== undefined)
return t7 ?? undefined;
const n7 = this.getTraceConnectionNames(e50), o7 = this.inputProblem.simpleRouteJson.connections.find((e54) => [e54.name, e54.source_trace_id, e54.rootConnectionName, e54.netConnectionName, ...e54.mergedConnectionNames ?? []].filter((e58) => Boolean(e58)).some((e58) => n7.includes(e58))) ?? null;
return this.connectionByTraceId.set(e50.pcb_trace_id, o7), o7 ?? undefined;
}
getTraceConnectionNames(e50) {
return [e50.connection_name, e50.source_trace_id, e50.rootConnectionName, ...e50.mergedConnectionNames ?? []].filter((e54) => Boolean(e54));
}
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 this.phase === "scan-corridor" ? this.corridor.length === 0 ? 0.25 : this.corridorCursor / this.corridor.length * 0.25 : this.blockers.length === 0 ? 0.5 : Math.min(0.99, 0.25 + this.blockerCursor / this.blockers.length);
}
getOutput() {
return this.output;
}
getConstructorParams() {
return [this.inputProblem];
}
visualize() {
const e50 = [];
for (let t7 = 0;t7 < this.traces.length; t7++) {
const n7 = this.traces[t7];
for (let o7 = 0;o7 < n7.route.length - 1; o7++) {
const i7 = n7.route[o7], r7 = n7.route[o7 + 1];
I8(i7) && I8(r7) && i7.layer === r7.layer && e50.push({ points: [i7, r7], strokeColor: t7 === this.currentBlocker?.traceIndex ? "#1769d2" : "#777", strokeWidth: Math.max(i7.width, r7.width) });
}
}
for (const t7 of this.corridor)
e50.push({ points: [t7.start, t7.end], strokeColor: "rgba(255, 128, 0, 0.55)", strokeWidth: t7.width });
return { coordinateSystem: "cartesian", title: this.getSolverName(), lines: e50, points: [], rects: [], circles: [], texts: [] };
}
};
var C8 = 0.000001;
var P8 = (e50, t7) => Math.hypot(e50.x - t7.x, e50.y - t7.y);
var M8 = (e50, t7, n7) => {
const o7 = n7.x - t7.x, i7 = n7.y - t7.y, r7 = o7 * o7 + i7 * i7, s7 = r7 <= 0.000000000001 ? 0 : Math.max(0, Math.min(1, ((e50.x - t7.x) * o7 + (e50.y - t7.y) * i7) / r7));
return Math.hypot(e50.x - (t7.x + s7 * o7), e50.y - (t7.y + s7 * i7));
};
var w8 = (e50, t7, n7) => (t7.x - e50.x) * (n7.y - e50.y) - (t7.y - e50.y) * (n7.x - e50.x);
var N8 = (e50, t7, n7, o7) => ((e54, t10, n10, o10) => {
const i7 = w8(n10, o10, e54), r7 = w8(n10, o10, t10), s7 = w8(e54, t10, n10), a7 = w8(e54, t10, o10);
return (i7 > 0 && r7 < 0 || i7 < 0 && r7 > 0) && (s7 > 0 && a7 < 0 || s7 < 0 && a7 > 0);
})(e50, t7, n7, o7) ? 0 : Math.min(M8(e50, n7, o7), M8(t7, n7, o7), M8(n7, e50, t7), M8(o7, e50, t7));
var T8 = (e50) => {
const t7 = (e50.ccwRotationDegrees ?? 0) * Math.PI / 180, n7 = Math.cos(t7), o7 = Math.sin(t7);
return [{ x: -e50.width / 2, y: -e50.height / 2 }, { x: e50.width / 2, y: -e50.height / 2 }, { x: e50.width / 2, y: e50.height / 2 }, { x: -e50.width / 2, y: e50.height / 2 }].map((t10) => ({ x: e50.center.x + t10.x * n7 - t10.y * o7, y: e50.center.y + t10.x * o7 + t10.y * n7 }));
};
var R8 = (e50) => {
if (!(e50.type === "oval" || e50.shape === "circle"))
return false;
if (Math.abs(e50.width - e50.height) > C8)
throw new Error(`Physical connectivity does not yet support non-circular oval obstacle ${e50.obstacleId ?? "<unknown>"}`);
return true;
};
var E8 = (e50, t7) => {
for (let n10 = 0;n10 < t7.length; n10++)
if (M8(e50, t7[n10], t7[(n10 + 1) % t7.length]) <= C8)
return true;
let n7 = false;
for (let o7 = 0, i7 = t7.length - 1;o7 < t7.length; i7 = o7++) {
const r7 = t7[o7], s7 = t7[i7];
r7.y > e50.y != s7.y > e50.y && e50.x < (s7.x - r7.x) * (e50.y - r7.y) / (s7.y - r7.y) + r7.x && (n7 = !n7);
}
return n7;
};
var A8 = (e50, t7) => {
if (R8(t7))
return Math.max(0, P8(e50, t7.center) - t7.width / 2);
const n7 = T8(t7);
return E8(e50, n7) ? 0 : Math.min(...n7.map((t10, o7) => M8(e50, t10, n7[(o7 + 1) % n7.length])));
};
var O8 = (e50, t7) => {
if (R8(e50))
return R8(t7) ? Math.max(0, P8(e50.center, t7.center) - e50.width / 2 - t7.width / 2) : Math.max(0, A8(e50.center, t7) - e50.width / 2);
if (R8(t7))
return O8(t7, e50);
const n7 = T8(e50), o7 = T8(t7);
if (E8(n7[0], o7) || E8(o7[0], n7))
return 0;
let i7 = Number.POSITIVE_INFINITY;
for (let e54 = 0;e54 < n7.length; e54++)
for (let t10 = 0;t10 < o7.length; t10++)
i7 = Math.min(i7, N8(n7[e54], n7[(e54 + 1) % n7.length], o7[t10], o7[(t10 + 1) % o7.length]));
return i7;
};
var k8 = (e50, t7) => ({ minX: e50.minX - t7, minY: e50.minY - t7, maxX: e50.maxX + t7, maxY: e50.maxY + t7 });
var D8 = (e50) => ({ minX: e50.x, minY: e50.y, maxX: e50.x, maxY: e50.y });
var L8 = (e50) => {
if (R8(e50))
return k8(D8(e50.center), e50.width / 2);
const t7 = T8(e50);
return { minX: Math.min(...t7.map((e54) => e54.x)), minY: Math.min(...t7.map((e54) => e54.y)), maxX: Math.max(...t7.map((e54) => e54.x)), maxY: Math.max(...t7.map((e54) => e54.y)) };
};
var z8 = (e50, t7) => {
if (!((e54, t10) => e54.layers.some((e58) => t10.layers.includes(e58)))(e50, t7) || !((e54, t10) => e54.maxX + C8 >= t10.minX && t10.maxX + C8 >= e54.minX && e54.maxY + C8 >= t10.minY && t10.maxY + C8 >= e54.minY)(e50.bounds, t7.bounds))
return false;
if (e50.kind === "bridge-pad") {
const n7 = { kind: "obstacle", obstacle: e50.obstacle, layers: e50.layers, bounds: e50.bounds };
return t7.kind === "bridge-pad" ? z8(n7, { kind: "obstacle", obstacle: t7.obstacle, layers: t7.layers, bounds: t7.bounds }) : z8(n7, t7);
}
return t7.kind === "bridge-pad" ? z8(t7, e50) : e50.kind === "endpoint" ? t7.kind === "endpoint" ? P8(e50.point, t7.point) <= C8 : t7.kind === "obstacle" ? A8(e50.point, t7.obstacle) <= C8 : t7.kind === "segment" ? M8(e50.point, t7.start, t7.end) <= t7.width / 2 + C8 : P8(e50.point, t7.center) <= t7.diameter / 2 + C8 : t7.kind === "endpoint" ? z8(t7, e50) : e50.kind === "obstacle" ? t7.kind === "obstacle" ? O8(e50.obstacle, t7.obstacle) <= C8 : t7.kind === "segment" ? ((e54, t10, n7) => {
if (R8(n7))
return Math.max(0, M8(n7.center, e54, t10) - n7.width / 2);
const o7 = T8(n7);
return E8(e54, o7) || E8(t10, o7) ? 0 : Math.min(...o7.map((n10, i7) => N8(e54, t10, n10, o7[(i7 + 1) % o7.length])));
})(t7.start, t7.end, e50.obstacle) <= t7.width / 2 + C8 : A8(t7.center, e50.obstacle) <= t7.diameter / 2 + C8 : t7.kind === "obstacle" ? z8(t7, e50) : e50.kind === "segment" ? t7.kind === "segment" ? N8(e50.start, e50.end, t7.start, t7.end) <= (e50.width + t7.width) / 2 + C8 : M8(t7.center, e50.start, e50.end) <= e50.width / 2 + t7.diameter / 2 + C8 : t7.kind === "segment" ? z8(t7, e50) : P8(e50.center, t7.center) <= (e50.diameter + t7.diameter) / 2 + C8;
};
var B8 = class {
parent;
constructor(e50) {
this.parent = Array.from({ length: e50 }, (e54, t7) => t7);
}
find(e50) {
const t7 = this.parent[e50];
if (t7 === e50)
return e50;
const n7 = this.find(t7);
return this.parent[e50] = n7, n7;
}
union(e50, t7) {
const n7 = this.find(e50), o7 = this.find(t7);
n7 !== o7 && (this.parent[o7] = n7);
}
};
var F8 = (e50, t7) => {
const n7 = t7.indexOf(e50.from_layer), o7 = t7.indexOf(e50.to_layer);
return n7 < 0 || o7 < 0 ? [...new Set([e50.from_layer, e50.to_layer])] : t7.slice(Math.min(n7, o7), Math.max(n7, o7) + 1);
};
var j8 = (e50) => [e50.pcb_trace_id, e50.connection_name, e50.source_trace_id, e50.rootConnectionName, ...e50.mergedConnectionNames ?? [], ...e50.connectsTo ?? []].filter((e54) => Boolean(e54));
var $8 = (e50) => [e50.name, e50.source_trace_id, e50.rootConnectionName, ...e50.mergedConnectionNames ?? [], e50.netConnectionName, ...e50.pointsToConnect.flatMap((e54) => [e54.pointId, e54.pcb_port_id])].filter((e54) => Boolean(e54));
var Y8 = (e50) => [e50.obstacleId, ...e50.connectedTo, ...e50.offBoardConnectsTo ?? []].filter((e54) => Boolean(e54));
var X8 = (e50, t7, n7, o7) => ({ kind: "bridge-contact", center: { x: e50.x, y: e50.y }, diameter: t7, layers: n7, bridgeId: o7, bounds: k8(D8(e50), t7 / 2) });
var W8 = 0.01;
var V8 = { "0603": { horizontalWidth: 0.8, horizontalHeight: 0.95, centerSpacings: [1.65, 1.8] }, 1206: { horizontalWidth: 0.6, horizontalHeight: 1.6, centerSpacings: [3.2] }, "1206x4_pair": { horizontalWidth: 0.8, horizontalHeight: 0.5, centerSpacings: [2.7] } };
var H8 = (e50, t7, n7) => {
if (!e50.layer)
throw new Error(`Jumper ${n7} is missing its layer`);
const o7 = V8[e50.footprint];
if (!o7)
throw new Error(`Unsupported jumper footprint ${String(e50.footprint)} on ${n7}`);
const i7 = Math.abs(e50.end.x - e50.start.x), r7 = Math.abs(e50.end.y - e50.start.y), s7 = (e54) => o7.centerSpacings.some((t10) => Math.abs(e54 - t10) < W8), a7 = r7 < W8 && s7(i7), c7 = i7 < W8 && s7(r7);
if (!a7 && !c7)
throw new Error(`Jumper ${n7} does not match ${e50.footprint} pad spacing`);
const l7 = { type: "rect", center: { ...t7 }, width: a7 ? o7.horizontalWidth : o7.horizontalHeight, height: a7 ? o7.horizontalHeight : o7.horizontalWidth, layers: [e50.layer], connectedTo: [] };
return { kind: "bridge-pad", obstacle: l7, layers: l7.layers, bridgeId: n7, bounds: L8(l7) };
};
var G8 = (e50, t7, n7) => {
if (e50.layer !== n7.layer || t7.layer !== n7.layer)
return false;
const o7 = (e54, t10) => Math.abs(e54.x - t10.x) < W8 && Math.abs(e54.y - t10.y) < W8, i7 = o7(e50, n7.start) && o7(t7, n7.end), r7 = o7(e50, n7.end) && o7(t7, n7.start);
return i7 || r7;
};
var U8 = (e50, t7, n7, o7) => {
const i7 = [], r7 = e50.route.flatMap((e54, t10) => e54.route_type === "jumper" ? [{ routePoint: e54, routePointIndex: t10 }] : []), s7 = new Map;
for (const t10 of r7) {
const n10 = [];
for (let o11 = 1;o11 < e50.route.length; o11++) {
const i10 = e50.route[o11 - 1], r10 = e50.route[o11];
i10?.route_type === "wire" && r10?.route_type === "wire" && G8(i10, r10, t10.routePoint) && n10.push(o11);
}
if (n10.length !== 1)
throw new Error(`Jumper ${e50.pcb_trace_id}:${t10.routePointIndex} matched ${n10.length} placeholder wire segments`);
const o10 = n10[0];
if (s7.has(o10))
throw new Error(`Multiple jumpers matched placeholder segment ${o10} on ${e50.pcb_trace_id}`);
s7.set(o10, t10);
}
let a7;
for (let r10 = 0;r10 < e50.route.length; r10++) {
const c7 = e50.route[r10];
if (c7.route_type === "wire") {
if (a7 && a7.layer === c7.layer && P8(a7, c7) > C8) {
const e54 = a7;
if (s7.get(r10))
;
else {
const t10 = e54.width / 2;
i7.push({ kind: "segment", start: { x: e54.x, y: e54.y }, end: { x: c7.x, y: c7.y }, width: e54.width, layers: [e54.layer], bounds: k8({ minX: Math.min(e54.x, c7.x), minY: Math.min(e54.y, c7.y), maxX: Math.max(e54.x, c7.x), maxY: Math.max(e54.y, c7.y) }, t10) });
}
}
a7 = c7;
continue;
}
if (a7 = undefined, c7.route_type === "via") {
const o10 = e50.route[r10 - 1], s10 = e50.route[r10 + 1];
for (const t10 of [o10, s10])
if (t10?.route_type === "wire" && P8(t10, c7) > C8)
throw new Error(`Via ${e50.pcb_trace_id}:${r10} is adjacent to a non-colocated wire endpoint`);
const a10 = c7.via_diameter ?? n7;
i7.push({ kind: "via", center: { x: c7.x, y: c7.y }, diameter: a10, layers: F8(c7, t7), bounds: k8(D8(c7), a10 / 2) });
continue;
}
const l7 = `${e50.pcb_trace_id}:${r10}:${c7.route_type}`;
if (c7.route_type === "jumper") {
i7.push(H8(c7, c7.start, l7), H8(c7, c7.end, l7));
continue;
}
if (c7.route_type === "through_obstacle") {
if (!o7.find((e54) => e54.layers.includes(c7.from_layer) && e54.layers.includes(c7.to_layer) && A8(c7.start, e54) <= C8 && A8(c7.end, e54) <= C8))
throw new Error(`Through-obstacle marker ${l7} has no same-net multilayer obstacle witness`);
i7.push(X8(c7.start, 0, [c7.from_layer], l7), X8(c7.end, 0, [c7.to_layer], l7));
continue;
}
throw new Error(`Unsupported route primitive: ${String(c7.route_type)}`);
}
return i7;
};
var Z8 = (e50, t7, n7) => {
const o7 = e50.pointsToConnect[n7];
return o7.pointId ?? o7.pcb_port_id ?? `${e50.name}[${t7}:${n7}]`;
};
var q8 = (e50) => {
const t7 = {}, n7 = {}, o7 = [];
for (let i7 = 0;i7 < e50.connections.length; i7++) {
const r7 = e50.connections[i7];
for (let e54 = 0;e54 < r7.pointsToConnect.length; e54++) {
const s7 = `${i7}:${e54}`;
t7[s7] = Z8(r7, i7, e54), n7[s7] = s7, o7.push([s7]);
}
}
return { endpointCount: Object.keys(t7).length, endpointLabels: t7, componentByEndpointKey: n7, endpointComponents: o7 };
};
var J8 = (e50) => {
if (e50 === null || typeof e50 != "object")
return JSON.stringify(e50) ?? String(e50);
if (Array.isArray(e50))
return `[${e50.map((e54) => J8(e54)).join(",")}]`;
const t7 = e50;
return `{${Object.keys(t7).sort().map((e54) => `${JSON.stringify(e54)}:${J8(t7[e54])}`).join(",")}}`;
};
var Q8 = (e50, t7) => {
const n7 = new V6(e50, t7, { includePhysicalPositionAliases: true }), o7 = (i7 = e50.layerCount) <= 1 ? ["top"] : i7 === 2 ? ["top", "bottom"] : ["top", ...Array.from({ length: i7 - 2 }, (e54, t10) => `inner${t10 + 1}`), "bottom"];
var i7;
const r7 = ((e54) => {
const t10 = e54.min_via_hole_diameter ?? e54.minViaHoleDiameter ?? 0;
return Math.max(t10, e54.min_via_pad_diameter ?? e54.minViaPadDiameter ?? e54.minViaDiameter ?? 0.6);
})(e50), s7 = new Map, a7 = new Map, c7 = {}, l7 = (e54, t10) => {
const n10 = s7.get(e54) ?? [];
n10.push(t10), s7.set(e54, n10);
};
for (let t10 = 0;t10 < e50.connections.length; t10++) {
const o10 = e50.connections[t10], i10 = n7.canonicalize($8(o10));
if (i10.length !== 1)
throw new Error(`Connection ${o10.name} resolved to ${i10.length} canonical nets`);
for (let e54 = 0;e54 < o10.pointsToConnect.length; e54++) {
const n10 = o10.pointsToConnect[e54], r10 = `${t10}:${e54}`, s10 = Z8(o10, t10, e54);
c7[r10] = s10;
const a10 = { kind: "endpoint", endpointKey: r10, endpointLabel: s10, point: { x: n10.x, y: n10.y }, layers: n10.layers ?? [n10.layer], bounds: D8(n10) };
for (const e58 of i10)
l7(e58, a10);
}
}
for (const t10 of e50.obstacles) {
const e54 = { kind: "obstacle", obstacle: t10, layers: t10.layers, bounds: L8(t10) };
for (const o10 of n7.canonicalize(Y8(t10))) {
const n10 = a7.get(o10) ?? [];
n10.push(t10), a7.set(o10, n10), s7.has(o10) && l7(o10, e54);
}
}
for (const i10 of [...t7, ...e50.fixedTraces ?? []]) {
const e54 = n7.canonicalize(j8(i10));
if (e54.length !== 1)
throw new Error(`Trace ${i10.pcb_trace_id} resolved to ${e54.length} canonical nets`);
const t10 = a7.get(e54[0]) ?? [], c10 = U8(i10, o7, r7, t10);
for (const t11 of e54)
if (s7.has(t11))
for (const e58 of c10)
l7(t11, e58);
}
const h7 = {}, d7 = [];
for (const e54 of s7.values()) {
const t10 = new B8(e54.length), n10 = new Map;
for (let o11 = 0;o11 < e54.length; o11++) {
const i11 = e54[o11];
if (i11.kind !== "bridge-contact" && i11.kind !== "bridge-pad")
continue;
const r10 = n10.get(i11.bridgeId);
r10 === undefined ? n10.set(i11.bridgeId, o11) : t10.union(r10, o11);
}
const o10 = e54.length > 0 ? new je(e54.length) : null;
if (o10) {
for (const t11 of e54)
o10.add(t11.bounds.minX, t11.bounds.minY, t11.bounds.maxX, t11.bounds.maxY);
o10.finish();
}
for (let n11 = 0;n11 < e54.length; n11++) {
const i11 = e54[n11], r10 = o10?.search(i11.bounds.minX - C8, i11.bounds.minY - C8, i11.bounds.maxX + C8, i11.bounds.maxY + C8) ?? [];
for (const o11 of r10)
o11 <= n11 || z8(i11, e54[o11]) && t10.union(n11, o11);
}
const i10 = new Map;
for (let n11 = 0;n11 < e54.length; n11++) {
const o11 = e54[n11];
if (o11.kind !== "endpoint")
continue;
const r10 = t10.find(n11), s10 = i10.get(r10) ?? [];
s10.push(o11.endpointKey), i10.set(r10, s10);
}
for (const e58 of i10.values()) {
e58.sort();
const t11 = e58[0];
d7.push(e58);
for (const n11 of e58) {
if (h7[n11] !== undefined)
throw new Error(`Endpoint ${n11} was assigned to multiple canonical nets`);
h7[n11] = t11;
}
}
}
return d7.sort(([e54 = ""], [t10 = ""]) => e54.localeCompare(t10)), { endpointCount: Object.keys(c7).length, endpointLabels: c7, componentByEndpointKey: h7, endpointComponents: d7 };
};
var K8 = class {
baseline;
inputProblem;
baselineCaptureError;
baselineTraceSignature;
constructor(e50, t7) {
this.inputProblem = e50, this.baselineTraceSignature = J8(t7);
try {
this.baseline = Q8(e50, t7), this.baselineCaptureError = null;
} catch (t10) {
this.baseline = q8(e50), this.baselineCaptureError = t10 instanceof Error ? t10.message : String(t10);
}
}
validate(e50) {
if (this.baselineCaptureError) {
const t10 = J8(e50) === this.baselineTraceSignature;
return { safe: t10, candidate: this.baseline, regressions: [], validationError: t10 ? `Connectivity validation is limited to exact trace preservation: ${this.baselineCaptureError}` : `Connectivity validation failed closed: ${this.baselineCaptureError}` };
}
let t7;
try {
t7 = Q8(this.inputProblem, e50);
} catch (e54) {
return { safe: false, candidate: q8(this.inputProblem), regressions: [], validationError: `Connectivity validation failed closed: ${e54 instanceof Error ? e54.message : String(e54)}` };
}
const n7 = [];
for (const e54 of this.baseline.endpointComponents) {
if (e54.length < 2)
continue;
const o7 = new Map;
for (const n10 of e54) {
const e58 = t7.componentByEndpointKey[n10] ?? `missing:${n10}`, i7 = o7.get(e58) ?? [];
i7.push(n10), o7.set(e58, i7);
}
o7.size <= 1 || n7.push({ baselineEndpointKeys: [...e54], baselineEndpointLabels: e54.map((e58) => this.baseline.endpointLabels[e58]), candidateComponents: [...o7.values()] });
}
return { safe: n7.length === 0, candidate: t7, regressions: n7 };
}
};
var e72 = [{ x: 0, y: 0 }, { x: 0.5, y: 0.5 }];
var t7 = [0.15, 0.2, 0.25, 0.3, 0.4, 0.5];
var n7 = (e50) => e50?.route_type === "wire";
var o7 = (e50) => e50?.route_type === "via";
var i7 = Array.from({ length: 24 }, (e50, t10) => {
const n10 = t10 * Math.PI / 12;
return { x: Math.cos(n10), y: Math.sin(n10) };
});
var r7 = (e50) => [...new Set(e50.map((e54) => Number(e54.toFixed(6))))].sort((e54, t10) => t10 - e54);
var s7 = class extends Y6 {
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 = false;
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 = false;
activeShovePadding = 0;
viaGridAttempt = null;
candidateSetMayUseGridFallback = false;
pendingPushedViaRepair = null;
alternatePushedViaRepairs = [];
pushedViaRepairRollbackTraces = null;
connectivityFinalized = false;
finalizedMutatedTraceIndices = [];
resumePhase = "scan-via-pairs";
constructor(e50) {
super(), this.inputProblem = structuredClone(e50), this.traces = structuredClone(e50.traces), this.initialConnectivitySafeTraces = structuredClone(e50.traces), this.connectivityInvariant = new K8(this.inputProblem.simpleRouteJson, this.initialConnectivitySafeTraces), this.connectionNameResolver = new V6(e50.simpleRouteJson, this.traces), this.maxRerouteLength = e50.maxRerouteLength ?? 10, this.desiredPadClearance = e50.desiredPadClearance, this.clearancePaddingTiers = r7([...e50.clearancePaddingTiers ?? [0.1, 0.05, 0], 0]).filter((e54) => e54 >= 0);
const t10 = this.traces.map((e54, t11) => t11), n10 = (e54, t11, n11) => {
const o11 = [...new Set(e54 ?? n11)];
for (const e58 of o11)
if (!Number.isInteger(e58) || e58 < 0 || e58 >= this.traces.length)
throw new RangeError(`Invalid cleanup ${t11} index: ${e58}`);
return o11;
}, o10 = n10(e50.traceIndices, "trace", t10);
this.viaRepairTraceIndices = n10(e50.viaRepairTraceIndices, "via repair trace", o10), this.mutableTraceIndices = n10(e50.mutableTraceIndices, "mutable trace", o10), this.mutableTraceIndexSet = new Set(this.mutableTraceIndices), this.traceIndices = o10.filter((e54) => this.resolveNominalTraceWidth(this.traces[e54]) >= 0.499999);
for (const e54 of this.traceIndices)
this.initialTraceLengths.set(e54, this.measureTraceLength(this.traces[e54]));
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 = true;
}
this.stats = this.createStats();
}
repairNextVia() {
const e50 = this.viaRepairTraceIndices[this.traceCursor], t10 = e50 === undefined ? undefined : this.traces[e50];
if (!t10)
return this.traceCursor = 0, this.routeCursor = 0, this.phase = "scan-via-pairs", void this.rebuildObstacleIndex();
const n10 = t10.route.findIndex((e54, t11) => t11 >= this.routeCursor && o7(e54));
if (n10 === -1)
return this.traceCursor++, void (this.routeCursor = 0);
this.routeCursor = n10 + 1;
const o10 = t10.route[n10], i10 = t10.route[n10 - 1], r10 = t10.route[n10 + 1];
if (!o7(o10) || !n7(i10) || !n7(r10))
return;
const s10 = this.getTraceConnectionNames(t10), a7 = this.getBaseObstacleClearance();
if (!this.obstacleIndex.collidesVia({ point: o10, layers: this.obstacleIndex.boardLayers, padDiameter: o10.via_diameter ?? 0.6, holeDiameter: o10.via_hole_diameter ?? this.obstacleIndex.defaultViaHoleDiameter, connectionNames: s10, ignoreTraceIndex: e50, ignoreRouteRange: { start: n10, end: n10 }, obstacleClearance: a7, blockSameNetObstacles: true, sameNetObstacleClearance: 0 }))
return;
const c7 = this.findViaRepair(t10, n10, a7);
if (!c7) {
const e54 = this.findPushableViaRepairs(t10, n10, a7), o11 = e54.shift();
return o11 ? (this.alternatePushedViaRepairs = e54, void this.startPushedViaRepair(o11)) : void this.unresolvedViaCount++;
}
t10.route.splice(c7.startIndex, c7.endIndex - c7.startIndex + 1, ...c7.route), this.relocatedViaCount++, this.routeCursor = c7.startIndex + c7.route.length, this.rebuildObstacleIndex();
}
findViaRepair(e50, t10, n10) {
const o10 = this.createViaRepairContext(e50, t10);
if (!o10)
return null;
const i10 = o10.candidates.map((e54) => ({ point: e54, movedLength: G6(o10.leftAnchor, e54) + G6(e54, o10.rightAnchor) })).filter(({ movedLength: e54 }) => e54 <= o10.originalLength + Math.min(6, this.maxRerouteLength) + H6);
i10.sort((e54, t11) => e54.movedLength - t11.movedLength || G6(e54.point, o10.via) - G6(t11.point, o10.via));
for (const e54 of i10)
if (this.isViaRepairPointSafe(o10, e54.point, n10))
return this.createViaRepairReplacement(o10, e54.point);
return null;
}
findPushableViaRepairs(e50, t10, n10) {
const o10 = this.viaRepairTraceIndices[this.traceCursor];
if (o10 === undefined)
return [];
const i10 = this.createViaRepairContext(e50, t10);
if (!i10)
return [];
const r10 = i10.candidates.flatMap((e54) => {
const t11 = G6(i10.leftAnchor, e54) + G6(e54, i10.rightAnchor);
if (t11 > i10.originalLength + Math.min(6, this.maxRerouteLength) + H6)
return [];
const r11 = new Set, s10 = this.getViaRepairCollisionQueries(i10, e54, n10);
for (const e58 of s10)
for (const t12 of this.obstacleIndex.findCollisions(e58)) {
if (t12.kind !== "trace" || t12.traceIndex === undefined || t12.traceIndex === o10 || !this.mutableTraceIndexSet.has(t12.traceIndex))
return [];
r11.add(t12.traceIndex);
}
if (r11.size === 0 || r11.size > 2)
return [];
const a7 = [...r11];
return this.isViaRepairPointSafe(i10, e54, n10, a7) ? [{ point: e54, movedLength: t11, blockerCount: r11.size, blockerKey: [...r11].sort((e58, t12) => e58 - t12).join(",") }] : [];
});
r10.sort((e54, t11) => e54.blockerCount - t11.blockerCount || e54.movedLength - t11.movedLength || G6(e54.point, i10.via) - G6(t11.point, i10.via));
return [...new Map([...r10].reverse().map((e54) => [e54.blockerKey, e54])).values(), ...r10].filter((e54, t11, n11) => n11.findIndex((t12) => t12.point.x === e54.point.x && t12.point.y === e54.point.y) === t11).slice(0, 12).map((e54) => ({ traceIndex: o10, viaIndex: t10, point: e54.point, padClearance: n10, corridor: [{ start: i10.leftAnchor, end: e54.point, layer: i10.leftWire.layer, width: i10.leftWire.width }, { start: e54.point, end: i10.rightAnchor, layer: i10.rightWire.layer, width: i10.rightWire.width }, ...this.obstacleIndex.boardLayers.map((t11) => ({ start: e54.point, end: e54.point, layer: t11, width: i10.viaDiameter }))] }));
}
createViaRepairContext(e50, t10) {
const n10 = e50.route[t10], o10 = e50.route[t10 - 1], i10 = e50.route[t10 + 1];
if (!o7(n10) || !n7(o10) || !n7(i10))
return null;
const r10 = t10 - 1 == 0 || !n7(e50.route[t10 - 2]), s10 = t10 + 1 === e50.route.length - 1 || !n7(e50.route[t10 + 2]), a7 = r10 ? o10 : e50.route[t10 - 2], c7 = s10 ? i10 : e50.route[t10 + 2], l7 = G6(a7, n10) + G6(n10, c7), h7 = this.getTraceConnectionNames(e50), d7 = n10.via_diameter ?? 0.6, u7 = n10.via_hole_diameter ?? this.obstacleIndex.defaultViaHoleDiameter, p7 = Math.max(0.3, u7 + this.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance + 0.05), m7 = [p7, p7 + 0.15, p7 + 0.3, p7 + 0.5, p7 + 0.75, p7 + 1, p7 + 1.5, p7 + 2].flatMap((e54) => i7.map((t11) => ({ x: 0.025 * Math.round((n10.x + t11.x * e54) / 0.025), y: 0.025 * Math.round((n10.y + t11.y * e54) / 0.025) }))), g7 = [...m7, ...m7.flatMap((e54) => [{ x: e54.x, y: Math.floor(10 * n10.y) / 10 }, { x: e54.x, y: Math.ceil(10 * n10.y) / 10 }, { x: Math.floor(10 * n10.x) / 10, y: e54.y }, { x: Math.ceil(10 * n10.x) / 10, y: e54.y }])].filter((e54, t11, n11) => n11.findIndex((t12) => t12.x === e54.x && t12.y === e54.y) === t11);
return { trace: e50, viaIndex: t10, via: n10, leftWire: o10, rightWire: i10, leftIsEndpoint: r10, rightIsEndpoint: s10, leftAnchor: a7, rightAnchor: c7, originalLength: l7, connectionNames: h7, viaDiameter: d7, holeDiameter: u7, ignoreRouteRange: { start: Math.max(0, t10 - 2), end: Math.min(e50.route.length - 1, t10 + 2) }, candidates: g7 };
}
getViaRepairCollisionQueries(e50, t10, n10, o10) {
const i10 = this.viaRepairTraceIndices[this.traceCursor], r10 = { connectionNames: e50.connectionNames, ignoreTraceIndex: i10, ignoreTraceIndices: o10, ignoreRouteRange: e50.ignoreRouteRange, obstacleClearance: n10 };
return [...this.obstacleIndex.boardLayers.map((n11) => ({ ...r10, start: t10, end: t10, layer: n11, width: e50.viaDiameter, blockSameNetObstacles: true, sameNetObstacleClearance: 0 })), { ...r10, start: e50.leftAnchor, end: t10, layer: e50.leftWire.layer, width: e50.leftWire.width }, { ...r10, start: t10, end: e50.rightAnchor, layer: e50.rightWire.layer, width: e50.rightWire.width }];
}
isViaRepairPointSafe(e50, t10, n10, o10) {
const i10 = this.viaRepairTraceIndices[this.traceCursor];
return !this.obstacleIndex.collidesVia({ point: t10, layers: this.obstacleIndex.boardLayers, padDiameter: e50.viaDiameter, holeDiameter: e50.holeDiameter, connectionNames: e50.connectionNames, ignoreTraceIndex: i10, ignoreTraceIndices: o10, ignoreRouteRange: { start: e50.viaIndex, end: e50.viaIndex }, obstacleClearance: n10, blockSameNetObstacles: true, sameNetObstacleClearance: 0 }) && !this.getViaRepairCollisionQueries(e50, t10, n10, o10).slice(this.obstacleIndex.boardLayers.length).some((e54) => this.obstacleIndex.collides(e54));
}
createViaRepairReplacement(e50, t10) {
const n10 = { ...e50.leftWire, ...t10 }, o10 = { ...e50.via, ...t10 }, i10 = { ...e50.rightWire, ...t10 };
return { startIndex: e50.viaIndex - 1, endIndex: e50.viaIndex + 1, route: [...e50.leftIsEndpoint ? [e50.leftWire] : [], n10, o10, i10, ...e50.rightIsEndpoint ? [e50.rightWire] : []] };
}
startPushedViaRepair(e50) {
this.pendingPushedViaRepair = e50, this.pushedViaRepairRollbackTraces = structuredClone(this.traces), this.attemptedPushedViaRepairCount++, this.activeSubSolver = new S8({ simpleRouteJson: this.inputProblem.simpleRouteJson, traces: this.traces, powerTraceIndex: e50.traceIndex, nominalPowerWidth: Math.max(...e50.corridor.map((e54) => e54.width)), pushOnlyNominalWidthsBelow: Number.POSITIVE_INFINITY, mutableTraceIndices: this.mutableTraceIndices, corridor: e50.corridor, maxRerouteLength: this.maxRerouteLength }, this.connectionNameResolver);
}
finishPushedViaRepairSolver(e50) {
const t10 = this.pendingPushedViaRepair;
if (this.activeSubSolver = null, !t10)
return;
if (e50.solved) {
const n11 = e50.getOutput();
if (n11) {
this.traces = n11.traces, this.rebuildObstacleIndex();
const e54 = this.traces[t10.traceIndex], o10 = e54 ? this.createViaRepairContext(e54, t10.viaIndex) : null;
if (o10 && this.isViaRepairPointSafe(o10, t10.point, t10.padClearance)) {
const n12 = this.createViaRepairReplacement(o10, t10.point);
return e54.route.splice(n12.startIndex, n12.endIndex - n12.startIndex + 1, ...n12.route), this.relocatedViaCount++, this.committedPushedViaRepairCount++, this.routeCursor = n12.startIndex + n12.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 n10 = this.alternatePushedViaRepairs.shift();
if (n10)
return this.rebuildObstacleIndex(), void this.startPushedViaRepair(n10);
this.alternatePushedViaRepairs = [], this.unresolvedViaCount++, this.rebuildObstacleIndex();
}
scanNextViaPair() {
const e50 = this.traceIndices[this.traceCursor];
if (e50 === undefined)
return this.traceCursor = 0, this.routeCursor = 0, void (this.phase = "scan-pad-clearance");
const t10 = this.traces[e50], n10 = t10.route.findIndex((e54, t11) => t11 >= this.routeCursor && e54.route_type === "via");
if (n10 === -1)
return void this.advanceTrace();
const o10 = t10.route.slice(n10 + 1).findIndex((e54) => e54.route_type === "via");
if (o10 === -1)
return void this.advanceTrace();
const i10 = n10 - 1, r10 = n10 + 1 + o10 + 1, s10 = t10.route[i10], a7 = t10.route[r10];
if (this.routeCursor = n10 + 1, !n7(s10) || !n7(a7) || s10.layer !== a7.layer || G6(s10, a7) > this.maxRerouteLength + H6)
return;
const c7 = this.createCandidates({ kind: "via-pair", traceIndex: e50, startIndex: i10, endIndex: r10 }), l7 = c7[0]?.width ?? Math.max(s10.width, a7.width), h7 = c7[0]?.padClearance ?? this.getCandidatePadClearance("via-pair", e50, i10, r10), d7 = (n11) => {
const o11 = t10.route[n11];
return !!n7(o11) && this.obstacleIndex.findCollisions({ start: o11, end: o11, layer: o11.layer, width: l7, connectionNames: this.getTraceConnectionNames(t10), ignoreTraceIndex: e50, ignoreRouteRange: { start: Math.max(0, i10 - 1), end: Math.min(t10.route.length - 1, r10 + 1) }, obstacleClearance: h7 }).some((e54) => e54.kind === "obstacle" && e54.obstacleKind === "pad");
}, u7 = t10.route[i10 - 1], p7 = t10.route[r10 + 1], m7 = c7.length > 0 && d7(i10) && n7(u7) && u7.layer === s10.layer ? i10 - 1 : i10, g7 = c7.length > 0 && d7(r10) && n7(p7) && p7.layer === a7.layer ? r10 + 1 : r10, f7 = [{ startIndex: i10, endIndex: r10 }, { startIndex: m7, endIndex: r10 }, { startIndex: i10, endIndex: g7 }, { startIndex: m7, endIndex: g7 }].filter((e54, t11, n11) => n11.findIndex((t12) => t12.startIndex === e54.startIndex && t12.endIndex === e54.endIndex) === t11).flatMap((t11) => t11.startIndex === i10 && t11.endIndex === r10 ? c7 : this.createCandidates({ kind: "via-pair", traceIndex: e50, startIndex: t11.startIndex, endIndex: t11.endIndex }));
f7.length !== 0 && this.beginCandidates(f7, "scan-via-pairs", true);
}
scanNextPadClearance() {
const e50 = this.traceIndices[this.traceCursor];
if (e50 === undefined)
return this.traceCursor = 0, this.routeCursor = 0, void (this.phase = "scan-simplification");
const t10 = this.traces[e50];
if (this.resolveNominalTraceWidth(t10) < 0.499999)
return void this.advanceTrace();
const n10 = this.routeCursor, o10 = t10.route[n10], i10 = t10.route[n10 + 1];
if (!n7(o10) || !n7(i10) || o10.layer !== i10.layer)
return void (n10 >= t10.route.length - 1 ? this.advanceTrace() : this.routeCursor++);
if (this.routeCursor++, !this.segmentHasPadClearanceViolation(e50, n10))
return;
const r10 = this.getPadClearanceIntervals(t10, n10).flatMap((t11) => this.getImprovedPadClearanceTiers(e50, t11.startIndex, t11.endIndex).flatMap((n11) => this.createCandidates({ kind: "pad-clearance", traceIndex: e50, startIndex: t11.startIndex, endIndex: t11.endIndex, padClearance: n11 }).slice(0, 8)));
r10.length !== 0 ? this.beginCandidates(r10.slice(0, 72), "scan-pad-clearance", true) : this.unresolvedPadClearanceCount++;
}
segmentHasPadClearanceViolation(e50, t10) {
const n10 = this.traces[e50], o10 = n10.route[t10], i10 = n10.route[t10 + 1];
return !(!n7(o10) || !n7(i10) || o10.layer !== i10.layer) && this.obstacleIndex.findCollisions({ start: o10, end: i10, layer: o10.layer, width: Math.max(o10.width, i10.width), connectionNames: this.getTraceConnectionNames(n10), ignoreTraceIndex: e50, ignoreRouteRange: { start: Math.max(0, t10 - 1), end: Math.min(n10.route.length - 1, t10 + 2) }, obstacleClearance: this.getPadClearanceForTrace(n10) }).some((e54) => e54.kind === "obstacle" && e54.obstacleKind === "pad");
}
getPadClearanceIntervals(e50, t10) {
const n10 = e50.route[t10];
if (!n7(n10))
return [];
const o10 = [t10];
let i10 = 0;
for (let r11 = t10 - 1;r11 >= 0; r11--) {
const t11 = e50.route[r11], s10 = e50.route[r11 + 1];
if (!n7(t11) || !n7(s10) || t11.layer !== n10.layer || s10.layer !== n10.layer)
break;
if (i10 += G6(t11, s10), i10 > this.maxRerouteLength / 2 + H6)
break;
o10.push(r11);
}
const r10 = [t10 + 1];
i10 = 0;
for (let o11 = t10 + 1;o11 < e50.route.length - 1; o11++) {
const t11 = e50.route[o11], s10 = e50.route[o11 + 1];
if (!n7(t11) || !n7(s10) || t11.layer !== n10.layer || s10.layer !== n10.layer)
break;
if (i10 += G6(t11, s10), i10 > this.maxRerouteLength / 2 + H6)
break;
r10.push(o11 + 1);
}
return o10.flatMap((t11) => r10.map((n11) => ({ startIndex: t11, endIndex: n11, length: this.measureRouteRange(e50, t11, n11).length }))).filter((e54) => e54.length <= this.maxRerouteLength + H6 && e54.startIndex < e54.endIndex).sort((e54, t11) => t11.length - e54.length).slice(0, 8);
}
scanNextSimplification() {
const e50 = this.traceIndices[this.traceCursor];
if (e50 === undefined)
return this.remainingPadClearanceViolationCount = this.countPadClearanceViolations(), this.remainingPadClearanceViolationCountByClearance = this.countPadClearanceViolationsByTier(), void (this.phase = "complete");
const t10 = this.traces[e50], n10 = this.routeCursor, o10 = t10.route[n10];
if (!n7(o10) || n10 >= t10.route.length - 1)
return void (n10 >= t10.route.length - 1 ? this.advanceTrace() : this.routeCursor++);
let i10 = 0;
const r10 = [];
for (let e54 = n10 + 1;e54 < t10.route.length; e54++) {
const s11 = t10.route[e54 - 1], a7 = t10.route[e54];
if (!n7(s11) || !n7(a7) || s11.layer !== o10.layer || a7.layer !== o10.layer)
break;
if (i10 += G6(s11, a7), i10 > this.maxRerouteLength + H6)
break;
const c7 = this.measureRouteRange(t10, n10, e54);
(c7.nonOctilinearSegmentCount > 0 || c7.pointCount > 3) && r10.push(e54);
}
const s10 = r10.slice(-6).reverse().flatMap((t11) => this.createCandidates({ kind: "simplification", traceIndex: e50, startIndex: n10, endIndex: t11 }));
s10.length !== 0 ? this.beginCandidates(s10, "scan-simplification") : this.routeCursor++;
}
createCandidates({ kind: e50, traceIndex: t10, startIndex: n10, endIndex: o10, padClearance: i10 }) {
const r10 = this.traces[t10], s10 = r10.route[n10], a7 = r10.route[o10];
if (!n7(s10) || !n7(a7) || s10.layer !== a7.layer)
return [];
const c7 = this.resolveNominalTraceWidth(r10), l7 = this.measureRouteRange(r10, n10, o10), h7 = i10 ?? this.getCandidatePadClearance(e50, t10, n10, o10), d7 = [], u7 = f8(s10, a7);
if (e50 === "pad-clearance" && p8([s10, a7]) === 0) {
const e54 = G6(s10, a7);
if (e54 > H6) {
const t11 = { x: -(a7.y - s10.y) / e54, y: (a7.x - s10.x) / e54 };
for (const e58 of [0.25, 0.5, 0.75, 1, 1.5, 2])
for (const n11 of [-1, 1])
u7.push([s10, { x: s10.x + t11.x * e58 * n11, y: s10.y + t11.y * e58 * n11 }, { x: a7.x + t11.x * e58 * n11, y: a7.y + t11.y * e58 * n11 }, a7]);
}
}
const p7 = new Map(u7.map((e54) => [e54.map((e58) => `${e58.x.toFixed(6)},${e58.y.toFixed(6)}`).join(";"), e54]));
for (const i11 of p7.values()) {
const u10 = m8(i11);
if (u10 > this.maxRerouteLength + H6 || e50 === "pad-clearance" && u10 > 1.35 * l7.length + 0.5 || e50 === "simplification" && (u10 > 1.1 * l7.length + H6 || this.measureTraceLength(r10) - l7.length + u10 > 1.01 * (this.initialTraceLengths.get(t10) ?? this.measureTraceLength(r10)) + H6))
continue;
const p10 = u10 <= H6 ? c7 : c7 - l7.deficitArea / u10;
if (p10 > c7 + H6)
continue;
const m7 = 0.05 * Math.ceil(Math.max(this.inputProblem.simpleRouteJson.minTraceWidth, p10) / 0.05 - H6), g7 = r7([c7, Math.min(c7, m7), Math.min(c7, Math.max(this.inputProblem.simpleRouteJson.minTraceWidth, p10))].map((e54) => Math.max(e54, s10.width)));
for (const r11 of g7) {
const u11 = this.measureCandidate(i11, r11, c7, a7.width, s10.width);
u11.deficitArea > l7.deficitArea + H6 || u11.conservativeDeficitArea > l7.conservativeDeficitArea + H6 || !this.preservesCoverage(u11, l7) || (e50 !== "simplification" || l7.nonOctilinearSegmentCount !== 0 || u11.pointCount < l7.pointCount && u11.length < l7.length - H6) && d7.push({ kind: e50, traceIndex: t10, startIndex: n10, endIndex: o10, layer: s10.layer, points: i11, width: r11, padClearance: h7, originalQuality: l7 });
}
}
return d7.slice(0, 18);
}
beginCandidates(e50, t10, n10 = false) {
this.candidates = e50, this.candidateCursor = 0, this.clearanceTierCursor = 0, this.candidateShoveCount = 0, this.rollbackTraces = null, this.baseCandidateValidated = false, this.resumePhase = t10, this.candidateSetMayUseGridFallback = n10, this.phase = "evaluate-candidate";
}
evaluateCurrentCandidate() {
const e50 = this.candidates[this.candidateCursor];
if (!e50)
return void this.finishCandidateSet(false);
if (!this.baseCandidateValidated) {
if (!this.candidateCollides(e50, 0))
return this.candidateShoveCount > 0 ? void this.applyCandidate(e50, 0) : (this.baseCandidateValidated = true, void (this.clearanceTierCursor = 0));
return this.getPushableTraceIndices(e50, 0) && this.candidateShoveCount < 2 && this.attemptedClearanceShoveCount < 48 ? void this.startClearanceShove(e50, 0) : void this.advanceCandidate();
}
const t10 = this.clearancePaddingTiers[this.clearanceTierCursor];
if (t10 === undefined || t10 <= H6)
return void this.applyCandidate(e50, 0);
if (this.attemptedCandidateCount++, !this.candidateCollides(e50, t10))
return void this.applyCandidate(e50, t10);
this.getPushableTraceIndices(e50, t10) && this.candidateShoveCount < 2 && this.attemptedClearanceShoveCount < 48 ? this.startClearanceShove(e50, t10) : (this.rollbackCandidateShoves(), this.clearanceTierCursor++, this.candidateShoveCount = 0);
}
advanceCandidate() {
this.rollbackCandidateShoves(), this.candidateCursor++, this.clearanceTierCursor = 0, this.candidateShoveCount = 0, this.baseCandidateValidated = false;
}
candidateCollides(e50, t10) {
const n10 = this.traces[e50.traceIndex], o10 = this.getTraceConnectionNames(n10);
for (let i10 = 0;i10 < e50.points.length - 1; i10++) {
const r10 = this.getCandidateSegmentWidth(e50, i10);
if (this.obstacleIndex.collides({ start: e50.points[i10], end: e50.points[i10 + 1], layer: e50.layer, width: r10 + 2 * t10, connectionNames: o10, ignoreTraceIndex: e50.traceIndex, ignoreRouteRange: { start: Math.max(0, e50.startIndex - 1), end: Math.min(n10.route.length - 1, e50.endIndex + 1) }, obstacleClearance: e50.padClearance }))
return true;
}
return false;
}
getPushableTraceIndices(e50, t10) {
const n10 = this.traces[e50.traceIndex], o10 = this.getTraceConnectionNames(n10), i10 = new Set;
for (let r10 = 0;r10 < e50.points.length - 1; r10++) {
const s10 = this.getCandidateSegmentWidth(e50, r10), a7 = { start: e50.points[r10], end: e50.points[r10 + 1], layer: e50.layer, width: s10 + 2 * t10, connectionNames: o10, ignoreTraceIndex: e50.traceIndex, ignoreRouteRange: { start: Math.max(0, e50.startIndex - 1), end: Math.min(n10.route.length - 1, e50.endIndex + 1) }, obstacleClearance: e50.padClearance };
if (!this.obstacleIndex.collides(a7))
continue;
const c7 = this.obstacleIndex.findCollisions(a7);
if (c7.length === 0)
return null;
for (const t11 of c7) {
if (t11.kind !== "trace" || t11.traceIndex === undefined || t11.traceIndex === e50.traceIndex || !this.mutableTraceIndexSet.has(t11.traceIndex))
return null;
const n11 = this.traces[t11.traceIndex];
if (!n11 || this.resolveNominalTraceWidth(n11) >= e50.width - H6)
return null;
i10.add(t11.traceIndex);
}
}
return i10.size > 0 && i10.size <= 2 ? [...i10] : null;
}
startClearanceShove(e50, t10) {
this.rollbackTraces ??= structuredClone(this.traces), this.activeShovePadding = t10;
const n10 = e50.width + 2 * t10, o10 = e50.points.slice(0, -1).map((n11, o11) => ({ start: n11, end: e50.points[o11 + 1], layer: e50.layer, width: this.getCandidateSegmentWidth(e50, o11) + 2 * t10 }));
this.attemptedClearanceShoveCount++, this.activeSubSolver = new S8({ simpleRouteJson: this.inputProblem.simpleRouteJson, traces: this.traces, powerTraceIndex: e50.traceIndex, nominalPowerWidth: n10, pushOnlyNominalWidthsBelow: e50.width, mutableTraceIndices: this.mutableTraceIndices, corridor: o10, maxRerouteLength: this.maxRerouteLength }, this.connectionNameResolver), this.phase = "shove-clearance";
}
getCandidateSegmentWidth(e50, t10) {
const n10 = this.traces[e50.traceIndex], o10 = n10.route[e50.startIndex], i10 = n10.route[e50.endIndex], r10 = t10 === 0 && n7(o10) ? o10.width : e50.width, s10 = t10 === e50.points.length - 2 && n7(i10) ? i10.width : e50.width;
return Math.max(r10, s10);
}
stepActiveShoveSolver() {
const e50 = this.activeSubSolver;
if (e50.step(), e50.solved || e50.failed)
if (this.pendingPushedViaRepair && e50 instanceof S8)
this.finishPushedViaRepairSolver(e50);
else if (e50 instanceof b8)
this.finishViaGridSolver(e50);
else {
if (this.activeSubSolver = null, this.phase = "evaluate-candidate", e50.solved) {
const t10 = e50.getOutput();
if (t10)
return this.traces = t10.traces, this.candidateShoveCount++, void this.rebuildObstacleIndex();
}
this.failedSubSolvers ??= [], this.failedSubSolvers.push(e50), this.rollbackCandidateShoves(), this.activeShovePadding <= H6 ? this.advanceCandidate() : this.clearanceTierCursor++, this.candidateShoveCount = 0;
}
}
rollbackCandidateShoves() {
this.rollbackTraces && (this.traces = this.rollbackTraces, this.rollbackTraces = null, this.rebuildObstacleIndex());
}
applyCandidate(e50, t10) {
const n10 = this.traces[e50.traceIndex], o10 = n10.route[e50.startIndex], i10 = n10.route[e50.endIndex], r10 = e50.points.map((t11, n11) => ({ ...n11 === 0 ? o10 : n11 === e50.points.length - 1 ? i10 : { route_type: "wire", layer: e50.layer, width: e50.width }, x: t11.x, y: t11.y, layer: e50.layer, width: n11 === 0 ? o10.width : n11 === e50.points.length - 1 ? i10.width : e50.width })), s10 = n10.route.slice(e50.startIndex, e50.endIndex + 1), a7 = e50.originalQuality.nonOctilinearSegmentCount;
if (n10.route.splice(e50.startIndex, e50.endIndex - e50.startIndex + 1, ...r10), e50.kind === "via-pair") {
const t11 = s10.filter((e54) => e54.route_type === "via").length;
this.viaPairCountRemoved++, this.viaCountRemoved += t11, this.routeCursor = Math.max(0, e50.startIndex - 1);
} else
e50.kind === "pad-clearance" ? (this.padClearanceRerouteCount++, this.routeCursor = e50.startIndex + Math.max(1, r10.length - 1)) : (this.simplifiedPathCount++, this.normalizedSegmentCount += a7, this.routeCursor = e50.startIndex + Math.max(1, r10.length - 1));
this.committedClearanceShoveCount += this.candidateShoveCount, t10 > H6 && this.achievedExtraClearanceCount++, this.rollbackTraces = null, this.candidateShoveCount = 0, this.rebuildObstacleIndex(), this.finishCandidateSet(true);
}
finishCandidateSet(e50) {
const t10 = this.candidates[0], n10 = r7(this.candidates.filter((e54) => e54.kind === t10?.kind).map((e54) => e54.width)), o10 = r7(this.candidates.filter((e54) => e54.kind === t10?.kind && e54.traceIndex === t10.traceIndex && e54.startIndex === t10.startIndex && e54.endIndex === t10.endIndex).map((e54) => e54.padClearance));
if (this.rollbackCandidateShoves(), this.candidates = [], this.candidateCursor = 0, this.clearanceTierCursor = 0, this.candidateShoveCount = 0, this.baseCandidateValidated = false, !e50 && this.candidateSetMayUseGridFallback && t10)
return this.candidateSetMayUseGridFallback = false, void this.beginViaGridAttempt(t10, n10, o10);
this.candidateSetMayUseGridFallback = false, e50 || this.routeCursor++, this.phase = this.resumePhase;
}
beginViaGridAttempt(e50, t10, n10 = [e50.padClearance]) {
this.viaGridAttempt = { kind: e50.kind, traceIndex: e50.traceIndex, startIndex: e50.startIndex, endIndex: e50.endIndex, layer: e50.layer, padClearances: n10, padClearanceCursor: 0, originalQuality: e50.originalQuality, widths: t10, widthCursor: 0, gridSizes: [], gridSizeCursor: 0, offsetCursor: 0 }, this.phase = "route-via-pair";
}
startNextViaGridCandidate() {
const e50 = this.viaGridAttempt;
if (!e50)
return void (this.phase = this.resumePhase);
if (e50.padClearanceCursor >= e50.padClearances.length)
return e50.kind === "pad-clearance" && this.unresolvedPadClearanceCount++, this.viaGridAttempt = null, this.routeCursor++, void (this.phase = this.resumePhase);
if (e50.widthCursor >= e50.widths.length)
return e50.padClearanceCursor++, e50.widthCursor = 0, e50.gridSizes = [], e50.gridSizeCursor = 0, void (e50.offsetCursor = 0);
const t10 = e50.widths[e50.widthCursor], n10 = e50.padClearances[e50.padClearanceCursor];
if (e50.gridSizes.length === 0 && (e50.gridSizes = r7([q6(t10 / 2, 0.2, 0.4), q6(t10 / 3, 0.15, 0.25)])), e50.gridSizeCursor >= e50.gridSizes.length)
return e50.widthCursor++, e50.gridSizes = [], e50.gridSizeCursor = 0, void (e50.offsetCursor = 0);
if (e50.offsetCursor >= e72.length)
return e50.gridSizeCursor++, void (e50.offsetCursor = 0);
const o10 = this.traces[e50.traceIndex], i10 = o10.route[e50.startIndex], r10 = o10.route[e50.endIndex];
if (!n7(i10) || !n7(r10))
return this.viaGridAttempt = null, this.routeCursor++, void (this.phase = this.resumePhase);
const s10 = e50.gridSizes[e50.gridSizeCursor], a7 = e72[e50.offsetCursor];
this.attemptedViaGridCount++, this.activeSubSolver = new b8({ start: i10, end: r10, layer: e50.layer, traceWidth: t10, gridSize: s10, gridOffset: { x: a7.x * s10, y: a7.y * s10 }, connectionNames: this.getTraceConnectionNames(o10), obstacleIndex: this.obstacleIndex, ignoreTraceIndex: e50.traceIndex, ignoreRouteRange: { start: Math.max(0, e50.startIndex - 1), end: Math.min(o10.route.length - 1, e50.endIndex + 1) }, bounds: this.inputProblem.simpleRouteJson.bounds, obstacleClearance: n10, searchPadding: Math.min(4, Math.max(2, G6(i10, r10) / 2, 3 * t10)), requireOctilinear: true });
}
finishViaGridSolver(e50) {
const t10 = this.viaGridAttempt;
if (this.activeSubSolver = null, e50.solved && t10) {
const n10 = e50.getOutput(), o10 = this.traces[t10.traceIndex];
if (n10 && o10) {
const e54 = this.resolveNominalTraceWidth(o10), i10 = this.measureCandidate(n10.points, n10.traceWidth, e54, o10.route[t10.endIndex].width, o10.route[t10.startIndex].width);
if (i10.nonOctilinearSegmentCount === 0 && i10.length <= this.maxRerouteLength + H6 && i10.deficitArea <= t10.originalQuality.deficitArea + H6 && i10.conservativeDeficitArea <= t10.originalQuality.conservativeDeficitArea + H6 && this.preservesCoverage(i10, t10.originalQuality)) {
const e58 = { kind: t10.kind, traceIndex: t10.traceIndex, startIndex: t10.startIndex, endIndex: t10.endIndex, layer: t10.layer, points: n10.points, width: n10.traceWidth, padClearance: t10.padClearances[t10.padClearanceCursor], originalQuality: t10.originalQuality };
return this.viaGridAttempt = null, void this.beginCandidates([e58], this.resumePhase, false);
}
}
}
e50.failed && (this.failedSubSolvers ??= [], this.failedSubSolvers.push(e50)), t10 && t10.offsetCursor++, this.phase = "route-via-pair";
}
measureRouteRange(e50, t10, n10) {
const o10 = this.resolveNominalTraceWidth(e50);
let i10 = 0, r10 = 0, s10 = 0, a7 = 0, c7 = 0, l7 = 0, h7 = 0;
for (let d7 = t10;d7 <= n10; d7++) {
if (n7(e50.route[d7]) && h7++, d7 >= n10)
continue;
const t11 = e50.route[d7], u7 = e50.route[d7 + 1];
if (!n7(t11) || !n7(u7) || t11.layer !== u7.layer)
continue;
const p7 = G6(t11, u7);
i10 += p7, r10 += p7 * Math.max(0, o10 - t11.width), t11.width >= o10 - H6 && (a7 += p7), s10 += p7 * Math.max(0, o10 - Math.min(t11.width, u7.width)), Math.min(t11.width, u7.width) >= o10 - H6 && (c7 += p7), l7 += p8([t11, u7]);
}
return { length: i10, deficitArea: r10, conservativeDeficitArea: s10, nominalLength: a7, conservativeNominalLength: c7, nonOctilinearSegmentCount: l7, pointCount: h7 };
}
measureTraceLength(e50) {
let t10 = 0;
for (let n10 = 0;n10 < e50.route.length - 1; n10++) {
const o10 = e50.route[n10], i10 = e50.route[n10 + 1];
n7(o10) && n7(i10) && o10.layer === i10.layer && (t10 += G6(o10, i10));
}
return t10;
}
measureCandidate(e50, t10, n10, o10 = t10, i10 = t10) {
const r10 = m8(e50);
let s10 = 0, a7 = 0, c7 = 0, l7 = 0;
for (let r11 = 0;r11 < e50.length - 1; r11++) {
const h7 = G6(e50[r11], e50[r11 + 1]), d7 = r11 === 0 ? i10 : t10, u7 = r11 === e50.length - 2 ? o10 : t10, p7 = Math.min(d7, u7);
s10 += h7 * Math.max(0, n10 - d7), a7 += h7 * Math.max(0, n10 - p7), d7 >= n10 - H6 && (c7 += h7), p7 >= n10 - H6 && (l7 += h7);
}
return { length: r10, deficitArea: s10, conservativeDeficitArea: a7, nominalLength: c7, conservativeNominalLength: l7, nonOctilinearSegmentCount: p8(e50), pointCount: e50.length };
}
preservesCoverage(e50, t10) {
const n10 = t10.length <= H6 ? 1 : t10.nominalLength / t10.length, o10 = e50.length <= H6 ? 1 : e50.nominalLength / e50.length, i10 = t10.length <= H6 ? 1 : t10.conservativeNominalLength / t10.length, r10 = e50.length <= H6 ? 1 : e50.conservativeNominalLength / e50.length;
return !(o10 + H6 < n10 || r10 + H6 < i10) && !(e50.length > t10.length + H6 && o10 < 0.999999);
}
advanceTrace() {
this.traceCursor++, this.routeCursor = 0, this.rebuildObstacleIndex();
}
createObstacleIndex() {
return new x8(this.inputProblem.simpleRouteJson, this.traces, this.phase === "repair-vias" ? undefined : this.traceIndices?.[this.traceCursor], [], this.connectionNameResolver);
}
rebuildObstacleIndex() {
this.obstacleIndex = this.createObstacleIndex();
}
resolveNominalTraceWidth(e50) {
const t10 = this.findConnectionForTrace(e50);
return Math.max(t10?.nominalTraceWidth ?? t10?.width ?? this.inputProblem.simpleRouteJson.nominalTraceWidth ?? this.inputProblem.simpleRouteJson.minTraceWidth, this.inputProblem.simpleRouteJson.minTraceWidth);
}
getPadClearanceForTrace(e50) {
const t10 = this.getBaseObstacleClearance();
return this.resolveNominalTraceWidth(e50) >= 0.499999 ? Math.max(t10, this.desiredPadClearance ?? this.resolveNominalTraceWidth(e50) / 2) : t10;
}
getBaseObstacleClearance() {
return Math.max(this.inputProblem.simpleRouteJson.defaultObstacleMargin ?? 0, this.inputProblem.simpleRouteJson.minTraceToPadEdgeClearance ?? 0, 0.1);
}
getCandidatePadClearance(e50, t10, n10, o10) {
const i10 = this.traces[t10], r10 = this.getBaseObstacleClearance(), s10 = this.getPadClearanceForTrace(i10);
if (e50 === "pad-clearance")
return s10;
const a7 = e50 === "via-pair" ? Math.min(s10, Math.max(r10, 0.15)) : s10;
return this.findExistingPadClearance(t10, n10, o10, r10, a7);
}
getImprovedPadClearanceTiers(e50, t10, n10) {
const o10 = this.traces[e50], i10 = this.getBaseObstacleClearance(), r10 = this.getPadClearanceForTrace(o10), s10 = this.findExistingPadClearance(e50, t10, n10, i10, r10), a7 = Math.max(0.025, Math.min(0.05, r10 / 10)), c7 = [r10];
for (let e54 = r10 - a7;e54 > s10 + a7 / 2; e54 -= a7)
c7.push(e54);
return r7(c7).filter((e54) => e54 > s10 + H6);
}
findExistingPadClearance(e50, t10, n10, o10, i10) {
if (this.routeRangeHasPadClearanceViolation(e50, t10, n10, o10))
return o10;
if (!this.routeRangeHasPadClearanceViolation(e50, t10, n10, i10))
return i10;
let r10 = o10, s10 = i10;
for (let o11 = 0;o11 < 7; o11++) {
const o12 = (r10 + s10) / 2;
this.routeRangeHasPadClearanceViolation(e50, t10, n10, o12) ? s10 = o12 : r10 = o12;
}
return Math.max(o10, Number((r10 - 0.001).toFixed(6)));
}
routeRangeHasPadClearanceViolation(e50, t10, n10, o10) {
const i10 = this.traces[e50], r10 = this.getTraceConnectionNames(i10);
for (let s10 = t10;s10 < n10; s10++) {
const a7 = i10.route[s10], c7 = i10.route[s10 + 1];
if (!n7(a7) || !n7(c7) || a7.layer !== c7.layer)
continue;
if (this.obstacleIndex.findCollisions({ start: a7, end: c7, layer: a7.layer, width: Math.max(a7.width, c7.width), connectionNames: r10, ignoreTraceIndex: e50, ignoreRouteRange: { start: Math.max(0, t10 - 1), end: Math.min(i10.route.length - 1, n10 + 1) }, obstacleClearance: o10 }).some((e54) => e54.kind === "obstacle" && e54.obstacleKind === "pad"))
return true;
}
return false;
}
countPadClearanceViolations(e50) {
let t10 = 0;
for (const n10 of this.traceIndices) {
const o10 = this.traces[n10];
if (!o10)
continue;
const i10 = this.getTraceConnectionNames(o10);
for (let r10 = 0;r10 < o10.route.length - 1; r10++) {
const s10 = o10.route[r10], a7 = o10.route[r10 + 1];
if (!n7(s10) || !n7(a7) || s10.layer !== a7.layer)
continue;
this.obstacleIndex.findCollisions({ start: s10, end: a7, layer: s10.layer, width: Math.max(s10.width, a7.width), connectionNames: i10, ignoreTraceIndex: n10, ignoreRouteRange: { start: Math.max(0, r10 - 1), end: Math.min(o10.route.length - 1, r10 + 2) }, obstacleClearance: e50 ?? this.getPadClearanceForTrace(o10) }).some((e54) => e54.kind === "obstacle" && e54.obstacleKind === "pad") && t10++;
}
}
return t10;
}
countPadClearanceViolationsByTier() {
return Object.fromEntries(t7.map((e50) => [e50.toFixed(2), this.countPadClearanceViolations(e50)]));
}
findConnectionForTrace(e50) {
const t10 = this.connectionByTraceId.get(e50.pcb_trace_id);
if (t10 !== undefined)
return t10 ?? undefined;
const n10 = new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(e50))), o10 = this.inputProblem.simpleRouteJson.connections.find((e54) => this.connectionNameResolver.canonicalize(this.getConnectionNames(e54)).some((e58) => n10.has(e58))) ?? null;
return this.connectionByTraceId.set(e50.pcb_trace_id, o10), o10 ?? undefined;
}
getConnectionNames(e50) {
return [e50.name, e50.source_trace_id, e50.rootConnectionName, e50.netConnectionName, ...e50.mergedConnectionNames ?? []].filter((e54) => Boolean(e54));
}
getTraceConnectionNames(e50) {
return [e50.pcb_trace_id, e50.connection_name, e50.source_trace_id, e50.rootConnectionName, ...e50.mergedConnectionNames ?? [], ...e50.connectsTo ?? []].filter((e54) => Boolean(e54));
}
ensureConnectivitySafeOutput() {
if (!this.connectivityFinalized) {
this.connectivityFinalized = true, this.connectivityValidationCount++;
try {
const e50 = this.connectivityInvariant.validate(this.traces);
if (this.connectivityValidationError ??= e50.validationError ?? null, e50.safe)
return void (this.finalizedMutatedTraceIndices = this.getMutatedTraceIndices());
this.connectivityRegressionEndpointIds = [...new Set(e50.regressions.flatMap((e54) => e54.baselineEndpointLabels))];
} catch (e50) {
this.connectivityValidationError = e50 instanceof Error ? e50.message : String(e50);
}
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 x8(this.inputProblem.simpleRouteJson, this.traces, undefined, [], this.connectionNameResolver), this.remainingPadClearanceViolationCount = this.countPadClearanceViolations(), this.remainingPadClearanceViolationCountByClearance = this.countPadClearanceViolationsByTier(), this.finalizedMutatedTraceIndices = this.getMutatedTraceIndices();
}
}
getMutatedTraceIndices() {
const e50 = Math.max(this.initialConnectivitySafeTraces.length, this.traces.length);
return Array.from({ length: e50 }, (e54, t10) => t10).filter((e54) => JSON.stringify(this.initialConnectivitySafeTraces[e54]) !== JSON.stringify(this.traces[e54]));
}
createStats() {
const e50 = this.candidates[this.candidateCursor], t10 = this.phase === "repair-vias" ? this.viaRepairTraceIndices : this.traceIndices;
return { phase: this.phase, budgetLimited: this.budgetLimited, completionReason: this.phase === "complete" || this.solved ? this.connectivityRollbackCount > 0 ? "connectivity_rollback" : this.budgetLimited ? "iteration_budget" : this.connectivityValidationError ? "connectivity_validation_unavailable" : "completed" : null, resultStatus: this.connectivityRollbackCount > 0 || this.budgetLimited || this.connectivityValidationError !== null ? "best_effort" : "complete", traceCursor: this.traceCursor, traceCount: t10.length, traceIndex: t10[this.traceCursor], routeCursor: this.routeCursor, candidateCursor: this.candidateCursor, candidateCount: this.candidates.length, candidateKind: e50?.kind, candidateWidth: e50?.width, candidatePointCount: e50?.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: this.connectivityRollbackMutationStats === null ? null : { ...this.connectivityRollbackMutationStats }, mutatedTraceIndices: [...this.finalizedMutatedTraceIndices], spatialIndexRectCount: this.obstacleIndex.items.length };
}
computeProgress() {
if (this.solved || this.phase === "complete")
return 1;
const e50 = this.phase === "repair-vias" ? this.viaRepairTraceIndices : this.traceIndices;
if (e50.length === 0)
return 1;
const t10 = this.resumePhase === "scan-via-pairs" ? 0 : 0.5;
return Math.min(0.99, t10 + this.traceCursor / e50.length * 0.5);
}
getConstructorParams() {
return [this.inputProblem];
}
tryFinalAcceptance() {
const e50 = this.pushedViaRepairRollbackTraces ?? this.rollbackTraces;
e50 && (this.traces = e50), 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 = false, this.candidateSetMayUseGridFallback = false, this.ensureConnectivitySafeOutput(), this.obstacleIndex = new x8(this.inputProblem.simpleRouteJson, this.traces, undefined, [], this.connectionNameResolver), this.remainingPadClearanceViolationCount = this.countPadClearanceViolations(), this.remainingPadClearanceViolationCountByClearance = this.countPadClearanceViolationsByTier(), this.budgetLimited = true, this.phase = "complete", this.solved = true, this.progress = 1, this.stats = this.createStats();
}
getOutput() {
return structuredClone(this.solved ? this.traces : this.initialConnectivitySafeTraces);
}
visualize() {
const e50 = [], t10 = [], n10 = this.candidates[this.candidateCursor];
for (let n11 = 0;n11 < this.traces.length; n11++) {
const o10 = this.traces[n11];
for (const e54 of o10.route)
e54.route_type === "via" && t10.push({ center: e54, radius: (e54.via_diameter ?? 0.6) / 2, fill: "#d4a017", stroke: "#7a5700" });
for (let t11 = 0;t11 < o10.route.length - 1; t11++) {
const n12 = o10.route[t11], i10 = o10.route[t11 + 1];
n7(n12) && n7(i10) && n12.layer === i10.layer && e50.push({ points: [n12, i10], strokeColor: n12.layer === "bottom" ? "#376fc4" : "#777", strokeWidth: n12.width });
}
}
if (n10)
for (let t11 = 0;t11 < n10.points.length - 1; t11++)
e50.push({ points: [n10.points[t11], n10.points[t11 + 1]], strokeColor: "#ff7400", strokeWidth: n10.width + 2 * (this.clearancePaddingTiers[this.clearanceTierCursor] ?? 0) });
return { coordinateSystem: "cartesian", title: `Power trace cleanup: ${this.phase}`, lines: e50, points: [], circles: t10, rects: [], texts: [] };
}
};
var a7 = (e50) => e50?.route_type === "wire";
var c7 = class extends Y6 {
inputProblem;
traces;
obstacleIndex;
traceCursor = 0;
routeCursor = 0;
repairedSegmentCount = 0;
repairedPadNeckSegmentCount = 0;
unresolvedSegmentCount = 0;
totalWidthReduction = 0;
budgetLimited = false;
connectivityValidationCount = 0;
connectivityRollbackCount = 0;
connectivityRegressionEndpointIds = [];
connectivityValidationError = null;
connectivityRollbackMutationStats = null;
connectionNameResolver;
nominalWidthByTraceId = new Map;
connectivityInvariant;
initialConnectivitySafeTraces;
minimumTraceWidth;
traceIndices;
connectivityFinalized = false;
constructor(e50) {
super(), this.inputProblem = structuredClone(e50), this.traces = structuredClone(e50.traces), this.initialConnectivitySafeTraces = structuredClone(e50.traces), this.connectivityInvariant = new K8(this.inputProblem.simpleRouteJson, this.initialConnectivitySafeTraces), this.connectionNameResolver = new V6(e50.simpleRouteJson, this.traces), this.minimumTraceWidth = e50.simpleRouteJson.minTraceWidth;
const t10 = e50.traceIndices ? [...new Set(e50.traceIndices)] : this.traces.map((e54, t11) => t11);
for (const e54 of t10)
if (!Number.isInteger(e54) || e54 < 0 || e54 >= this.traces.length)
throw new RangeError(`Invalid clearance-repair trace index: ${e54}`);
this.traceIndices = t10, this.obstacleIndex = this.createConservativeObstacleIndex();
const n10 = this.traceIndices.reduce((e54, t11) => e54 + Math.max(0, this.traces[t11].route.length - 1), 0);
this.MAX_ITERATIONS = Math.max(10, 8 * n10 + 2 * this.traceIndices.length), this.stats = this.createStats();
}
getSolverName() {
return "PowerTraceClearanceRepairSolver";
}
_step() {
const e50 = this.traceIndices[this.traceCursor], t10 = e50 === undefined ? undefined : this.traces[e50];
if (!t10)
return this.ensureConnectivitySafeOutput(), this.solved = true, void (this.stats = this.createStats());
if (this.routeCursor >= t10.route.length - 1)
return this.traceCursor++, this.routeCursor = 0, void (this.stats = this.createStats());
const n10 = this.routeCursor++, o10 = t10.route[n10], i10 = t10.route[n10 + 1];
if (!a7(o10) || !a7(i10) || o10.layer !== i10.layer)
return void (this.stats = this.createStats());
const r10 = Math.max(o10.width, i10.width), s10 = { start: o10, end: i10, layer: o10.layer, width: r10, connectionNames: this.getTraceConnectionNames(t10), ignoreTraceIndex: e50, ignoreRouteRange: { start: n10, end: n10 + 1 } };
if (this.repairConnectedPadNeck(t10, n10, s10))
return void (this.stats = this.createStats());
if (!this.segmentHasForeignTraceCollision(n10, r10))
return void (this.stats = this.createStats());
if (this.segmentHasForeignTraceCollision(n10, this.minimumTraceWidth))
return this.unresolvedSegmentCount++, void (this.stats = this.createStats());
let a10 = this.minimumTraceWidth, c10 = r10;
for (let e54 = 0;e54 < 10; e54++) {
const e58 = (a10 + c10) / 2;
this.segmentHasForeignTraceCollision(n10, e58) ? c10 = e58 : a10 = e58;
}
const l7 = r10 >= 0.5 ? 0.025 : 0.0125, h7 = Math.max(this.minimumTraceWidth, Math.floor((a10 + H6) / l7) * l7), d7 = this.segmentHasForeignTraceCollision(n10, h7) ? a10 : h7, u7 = o10.width, p7 = i10.width;
o10.width = Math.min(o10.width, d7), i10.width = Math.min(i10.width, d7);
const m7 = u7 - o10.width + (p7 - i10.width);
if (m7 <= H6)
return this.unresolvedSegmentCount++, void (this.stats = this.createStats());
this.repairedSegmentCount++, this.totalWidthReduction += m7, this.obstacleIndex = this.createConservativeObstacleIndex(), this.routeCursor = Math.max(0, n10 - 1), this.stats = this.createStats();
}
repairConnectedPadNeck(e50, t10, n10) {
const o10 = e50.route[t10], i10 = e50.route[t10 + 1];
if (!a7(o10) || !a7(i10))
return false;
let r10 = this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n10, o10), s10 = this.obstacleIndex.getConnectedPadWidthLimitAtPoint(n10, i10);
t10 === 0 && (r10 = this.getSmallerLimit(r10, this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n10, o10))), t10 + 1 === e50.route.length - 1 && (s10 = this.getSmallerLimit(s10, this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(n10, i10)));
const a10 = r10, c10 = s10;
if ((a10 === null || o10.width <= a10 + H6) && (c10 === null || i10.width <= c10 + H6))
return false;
const l7 = o10.width, h7 = i10.width;
if (a10 !== null && (o10.width = Math.min(o10.width, a10)), c10 !== null && (i10.width = Math.min(i10.width, c10)), a10 !== null && c10 === null)
this.insertPadBoundaryTransition(e50, t10, n10, "start", o10.width, h7);
else if (a10 === null && c10 !== null)
this.insertPadBoundaryTransition(e50, t10, n10, "end", i10.width, l7);
else if (a10 !== null && c10 !== null) {
const r11 = this.obstacleIndex.getConnectedPadBoundaryPoint(n10, "start"), s11 = this.obstacleIndex.getConnectedPadBoundaryPoint(n10, "end");
r11 && s11 && (this.insertPadBoundaryTransition(e50, t10, n10, "start", o10.width, h7), this.insertPadBoundaryTransition(e50, t10 + 2, n10, "end", i10.width, l7));
}
return this.totalWidthReduction += l7 - o10.width + (h7 - i10.width), this.repairedPadNeckSegmentCount++, this.obstacleIndex = this.createConservativeObstacleIndex(), this.routeCursor = Math.max(0, t10 - 1), true;
}
getSmallerLimit(e50, t10) {
return e50 === null ? t10 : t10 === null ? e50 : Math.min(e50, t10);
}
insertPadBoundaryTransition(e50, t10, n10, o10, i10, r10) {
const s10 = this.obstacleIndex.getConnectedPadBoundaryPoint(n10, o10);
if (!s10)
return;
const a10 = o10 === "start" ? n10.start : n10.end, c10 = o10 === "start" ? n10.end : n10.start, l7 = Math.hypot(c10.x - a10.x, c10.y - a10.y);
if (l7 <= 0.000000001)
return;
const h7 = Math.min(0.000001, l7 / 4), d7 = (c10.x - a10.x) / l7, u7 = (c10.y - a10.y) / l7, p7 = { route_type: "wire", x: s10.x - d7 * h7, y: s10.y - u7 * h7, width: i10, layer: n10.layer }, m7 = { ...p7, x: s10.x + d7 * h7, y: s10.y + u7 * h7, width: r10 }, g7 = o10 === "start" ? e50.route[t10 + 1] : e50.route[t10], f7 = o10 === "start" ? e50.route[t10 + 2] : e50.route[t10 - 1];
if (a7(g7) && f7?.route_type === "via") {
const t11 = this.resolveNominalTraceWidth(e50);
this.obstacleIndex.collides({ ...n10, start: g7, end: m7, width: t11 }) || (g7.width = Math.max(g7.width, t11), m7.width = g7.width);
}
e50.route.splice(t10 + 1, 0, ...o10 === "start" ? [p7, m7] : [m7, p7]);
}
resolveNominalTraceWidth(e50) {
const t10 = this.nominalWidthByTraceId.get(e50.pcb_trace_id);
if (t10 !== undefined)
return t10;
const n10 = new Set(this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(e50))), o10 = this.inputProblem.simpleRouteJson.connections.find((e54) => this.connectionNameResolver.canonicalize([e54.name, e54.source_trace_id, e54.rootConnectionName, e54.netConnectionName, ...e54.mergedConnectionNames ?? []].filter((e58) => Boolean(e58))).some((e58) => n10.has(e58))), i10 = Math.max(o10?.nominalTraceWidth ?? o10?.width ?? this.inputProblem.simpleRouteJson.nominalTraceWidth ?? this.minimumTraceWidth, this.minimumTraceWidth);
return this.nominalWidthByTraceId.set(e50.pcb_trace_id, i10), i10;
}
segmentHasForeignTraceCollision(e50, t10) {
const n10 = this.traceIndices[this.traceCursor], o10 = n10 === undefined ? undefined : this.traces[n10], i10 = o10?.route[e50], r10 = o10?.route[e50 + 1];
return !!(o10 && a7(i10) && a7(r10) && i10.layer === r10.layer) && this.obstacleIndex.findCollisions({ start: i10, end: r10, layer: i10.layer, width: t10, connectionNames: this.getTraceConnectionNames(o10), ignoreTraceIndex: n10, ignoreRouteRange: { start: e50, end: e50 + 1 } }).some((e54) => e54.kind === "trace" && e54.traceIndex !== undefined && e54.traceIndex !== n10);
}
createConservativeObstacleIndex() {
const e50 = structuredClone(this.traces);
for (const t10 of e50)
for (let e54 = 0;e54 < t10.route.length - 1; e54++) {
const n10 = t10.route[e54], o10 = t10.route[e54 + 1];
a7(n10) && a7(o10) && n10.layer === o10.layer && (n10.width = Math.max(n10.width, o10.width));
}
return new x8(this.inputProblem.simpleRouteJson, e50, undefined, [], this.connectionNameResolver);
}
getTraceConnectionNames(e50) {
return [e50.pcb_trace_id, e50.connection_name, e50.source_trace_id, e50.rootConnectionName, ...e50.mergedConnectionNames ?? [], ...e50.connectsTo ?? []].filter((e54) => Boolean(e54));
}
ensureConnectivitySafeOutput() {
if (!this.connectivityFinalized) {
this.connectivityFinalized = true, this.connectivityValidationCount++;
try {
const e50 = this.connectivityInvariant.validate(this.traces);
if (this.connectivityValidationError ??= e50.validationError ?? null, e50.safe)
return;
this.connectivityRegressionEndpointIds = [...new Set(e50.regressions.flatMap((e54) => e54.baselineEndpointLabels))];
} catch (e50) {
this.connectivityValidationError = e50 instanceof Error ? e50.message : String(e50);
}
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 || this.connectivityValidationError !== null ? "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: this.connectivityRollbackMutationStats === null ? null : { ...this.connectivityRollbackMutationStats }, spatialIndexRectCount: this.obstacleIndex.items.length };
}
computeProgress() {
return this.solved || this.traceIndices.length === 0 ? 1 : Math.min(0.99, this.traceCursor / this.traceIndices.length);
}
tryFinalAcceptance() {
this.ensureConnectivitySafeOutput(), this.budgetLimited = true, this.solved = true, this.progress = 1, this.stats = this.createStats();
}
getConstructorParams() {
return [this.inputProblem];
}
getOutput() {
return structuredClone(this.solved ? this.traces : this.initialConnectivitySafeTraces);
}
visualize() {
const e50 = [];
for (let t10 = 0;t10 < this.traces.length; t10++) {
const n10 = this.traces[t10];
for (let o10 = 0;o10 < n10.route.length - 1; o10++) {
const i10 = n10.route[o10], r10 = n10.route[o10 + 1];
a7(i10) && a7(r10) && i10.layer === r10.layer && e50.push({ points: [i10, r10], strokeColor: t10 === this.traceIndices[this.traceCursor] && o10 === this.routeCursor ? "#ff7400" : i10.layer === "bottom" ? "#376fc4" : "#777", strokeWidth: Math.max(i10.width, r10.width) });
}
}
return { coordinateSystem: "cartesian", title: "Power trace direction-independent clearance repair", lines: e50, points: [], circles: [], rects: [], texts: [] };
}
};
var l7 = [{ x: 0, y: 0 }, { x: 0.5, y: 0 }, { x: 0, y: 0.5 }, { x: 0.5, y: 0.5 }];
var h7 = [{ offset: { x: 0, y: 0 }, strictNecking: true }, { offset: { x: 0.5, y: 0.5 }, strictNecking: true }, { offset: { x: 0, y: 0 }, strictNecking: false }, { offset: { x: 0.5, y: 0.5 }, strictNecking: false }];
var d7 = (e50) => [...new Set(e50.map((e54) => Number(e54.toFixed(6))))].sort((e54, t10) => t10 - e54);
var u7 = (e50) => e50?.route_type === "wire";
var p7 = class extends Y6 {
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 = false;
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 = false;
finalAcceptanceUsed = false;
cleanupCompleted = false;
clearanceRepairCompleted = false;
cleanupBestEffortAccepted = false;
clearanceRepairBestEffortAccepted = false;
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(e50, t10 = {}) {
super(), this.inputProblem = structuredClone(e50), this.options = structuredClone(t10), this.traces = structuredClone(e50.traces ?? []), this.connectionNameResolver = new V6(this.inputProblem, this.traces), this.lastConnectivitySafeTraces = structuredClone(this.traces), this.connectivityInvariant = new K8(this.inputProblem, this.lastConnectivitySafeTraces);
const n10 = t10.onlyConnectionNames ? new Set(this.connectionNameResolver.canonicalize([...t10.onlyConnectionNames])) : null, o10 = this.traces.flatMap((e54, t11) => {
if (!n10)
return [t11];
return this.connectionNameResolver.canonicalize(this.getTraceConnectionNames(e54)).some((e58) => n10.has(e58)) ? [t11] : [];
}), i10 = new Map(o10.map((e54) => [e54, this.getInitialTracePriority(this.traces[e54])]));
this.traceOrder = o10.sort((e54, t11) => i10.get(t11) - i10.get(e54) || e54 - t11), this.selectedOwnedTraceIndices = this.traceOrder.filter((e54) => this.findConnectionForTrace(this.traces[e54])), this.selectedCleanupTraceIndices = [...this.selectedOwnedTraceIndices], this.selectedViaRepairTraceIndices = [...this.selectedOwnedTraceIndices], this.mutableBlockerTraceIndices = this.traces.flatMap((e54, t11) => this.findConnectionForTrace(e54) ? [t11] : []);
const r10 = new Set(this.mutableBlockerTraceIndices);
this.immutableTraceIndices = this.traces.flatMap((e54, t11) => r10.has(t11) ? [] : (this.initialImmutableTraceSignatures.set(t11, JSON.stringify(e54)), [t11])), this.previousWidthDeficit = this.calculateWidthDeficit().deficit, this.obstacleIndex = new x8(this.inputProblem, this.traces, this.traceIndex >= 0 ? this.traceIndex : undefined, [], 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 = 8000000, 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 = true;
}
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 e50 = this.traces[this.traceIndex];
this.findConnectionForTrace(e50) ? (this.nominalTraceWidth = this.resolveNominalTraceWidth(e50), this.traceMeetsNominalWidth(e50, this.nominalTraceWidth) ? this.keptTraceCount++ : (this.rebuildObstacleIndex(), e50.route = function(e54, t10) {
if (e54.length < 2)
return e54.map((e58) => ({ ...e58 }));
const n10 = [];
for (let o10 = 0;o10 < e54.length - 1; o10++) {
const i10 = e54[o10], r10 = e54[o10 + 1];
if (n10.push({ ...i10 }), i10.route_type !== "wire" || r10.route_type !== "wire" || i10.layer !== r10.layer || i10.width >= t10 - H6)
continue;
const s10 = G6(i10, r10), a10 = Math.max(1, Math.ceil(s10 / t10));
for (let e58 = 1;e58 < a10; e58++) {
const t11 = e58 / a10;
n10.push({ route_type: "wire", x: i10.x + (r10.x - i10.x) * t11, y: i10.y + (r10.y - i10.y) * t11, width: i10.width, layer: i10.layer });
}
}
return n10.push({ ...e54[e54.length - 1] }), n10;
}(e50.route, this.nominalTraceWidth), this.recreatedTraceCount++, this.phase = "evaluate-segment")) : this.keptTraceCount++;
}
finishOrStartNextPass() {
const { deficit: e50, nominalArea: t10 } = this.calculateWidthDeficit(), n10 = this.previousWidthDeficit - e50;
if (this.lastNormalizedWidthDeficitGain = t10 <= H6 ? 0 : n10 / t10, this.normalizedWidthDeficitGainByPass.push(this.lastNormalizedWidthDeficitGain), this.plateauReached = this.lastNormalizedWidthDeficitGain < 0.001, this.completedPassCount = this.passIndex + 1, this.passIndex + 1 < this.maxPassCount && this.lastNormalizedWidthDeficitGain >= 0.001)
return this.previousWidthDeficit = e50, 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 e50 = new s7({ simpleRouteJson: this.inputProblem, traces: this.traces, traceIndices: this.selectedCleanupTraceIndices, viaRepairTraceIndices: this.selectedViaRepairTraceIndices, mutableTraceIndices: this.mutableBlockerTraceIndices, maxRerouteLength: 10, desiredPadClearance: this.options.powerTraceToPadClearance }), t10 = this.getRemainingParentIterationsAfterCurrentStep(), n10 = t10 === 0 ? 0 : Math.max(1, Math.floor(0.75 * t10));
e50.MAX_ITERATIONS = Math.min(e50.MAX_ITERATIONS, n10), this.cleanupIterationBudget = e50.MAX_ITERATIONS, this.activeSubSolver = e50;
}
shouldStartBudgetFinalization() {
return !this.budgetLimitedExpansion && (this.phase !== "cleanup" && this.phase !== "repair-trace-clearance" && this.phase !== "complete" && this.iterations >= this.getExpansionIterationBudget());
}
getFinalizationIterationReserve() {
return Math.min(Math.max(0, this.MAX_ITERATIONS - 1), Math.max(1, Math.floor(0.125 * this.MAX_ITERATIONS)));
}
getExpansionIterationBudget() {
return Math.max(1, this.MAX_ITERATIONS - this.getFinalizationIterationReserve());
}
startBudgetFinalization() {
this.budgetLimitedExpansion = true, 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 e50 = { 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(), e50;
}
restoreLastConnectivitySafeTraces() {
this.traces = structuredClone(this.lastConnectivitySafeTraces), this.rebuildObstacleIndex();
}
getRemainingParentIterationsAfterCurrentStep() {
return Math.max(0, this.MAX_ITERATIONS - this.iterations - 1);
}
calculateWidthDeficit() {
let e50 = 0, t10 = 0;
for (const n10 of this.traceOrder) {
const o10 = this.traces[n10];
if (!this.findConnectionForTrace(o10))
continue;
const i10 = this.resolveNominalTraceWidth(o10);
for (let n11 = 0;n11 < o10.route.length - 1; n11++) {
const r10 = o10.route[n11], s10 = o10.route[n11 + 1];
if (!u7(r10) || !u7(s10) || r10.layer !== s10.layer)
continue;
const a10 = G6(r10, s10), c10 = r10.width;
t10 += a10 * i10, e50 += a10 * Math.max(0, i10 - c10);
}
}
return { deficit: e50, nominalArea: t10 };
}
getInitialTracePriority(e50) {
const t10 = this.resolveNominalTraceWidth(e50);
let n10 = 0;
for (let o10 = 0;o10 < e50.route.length - 1; o10++) {
const i10 = e50.route[o10], r10 = e50.route[o10 + 1];
u7(i10) && u7(r10) && i10.layer === r10.layer && (n10 += G6(i10, r10) * Math.max(0, t10 - Math.min(i10.width, r10.width)));
}
return t10 * n10;
}
evaluateNextSegment() {
const e50 = this.traces[this.traceIndex];
if (!e50)
return void (this.phase = "scan-trace");
const t10 = this.findNextUnderWidthSegment(e50, this.routeSegmentIndex, this.nominalTraceWidth);
if (t10 === -1)
return void (this.phase = "scan-trace");
this.routeSegmentIndex = t10;
const n10 = e50.route[t10], o10 = e50.route[t10 + 1];
if (!u7(n10) || !u7(o10))
return void this.routeSegmentIndex++;
const i10 = this.getTraceConnectionNames(e50), r10 = Math.min(n10.width, o10.width), s10 = this.findMaximumSafeInPlaceWidth(e50, t10, i10);
if (s10 > r10 + H6) {
if (n10.width = Math.max(n10.width, s10), o10.width = Math.max(o10.width, s10), s10 >= this.nominalTraceWidth - H6)
return this.expandedSegmentCount++, void this.routeSegmentIndex++;
this.intermediateExpandedSegmentCount++;
}
this.startTraceInflation(e50, t10) || this.prepareLayerRouteAttempt(e50, t10) || this.prepareRegularGridCandidates(e50, t10);
}
prepareRegularGridCandidates(e50, t10) {
if (this.currentIntervals = this.getExponentialIntervalCandidates(e50, t10, this.nominalTraceWidth), this.intervalCursor = 0, this.candidateWidths = this.getCandidateWidths(this.nominalTraceWidth), this.widthCursor = 0, this.gridResolutions = [], this.resolutionCursor = 0, this.offsetCursor = 0, this.currentIntervals.length === 0)
return this.unresolvedSegmentCount++, void this.routeSegmentIndex++;
this.phase = "try-grid-candidate";
}
prepareLayerRouteAttempt(e50, t10) {
if (this.nominalTraceWidth < 0.499999)
return false;
const n10 = this.options.allowNewVias !== false && this.inputProblem.layerCount >= 2, o10 = n10 ? 2 : this.maxPassCount, i10 = this.layerAttemptCountByTrace.get(this.traceIndex) ?? 0, r10 = this.layerRerouteCountByTrace.get(this.traceIndex) ?? 0;
if (r10 >= o10 || i10 >= o10 || i10 > this.passIndex || i10 > 0 && r10 === 0)
return false;
const s10 = e50.route[t10], a10 = e50.route[t10 + 1];
if (!u7(s10) || !u7(a10) || Math.min(s10.width, a10.width) >= 0.5 * this.nominalTraceWidth - H6)
return false;
const c10 = this.getExponentialIntervalCandidates(e50, t10, this.nominalTraceWidth).filter((t11) => this.intervalSupportsLayerRouting(e50, t11)).sort((t11, n11) => n11.endIndex - t11.endIndex || t11.startIndex - n11.startIndex || this.getRouteIntervalLength(e50, n11.startIndex, n11.endIndex) - this.getRouteIntervalLength(e50, t11.startIndex, t11.endIndex))[0];
if (!c10)
return false;
const l10 = this.getRouteQuality(e50.route.slice(c10.startIndex, c10.endIndex + 1));
if (l10.deficitArea < this.nominalTraceWidth)
return false;
if (i10 > 0 && l10.deficitArea / Math.max(l10.length, H6) < 0.25)
return false;
const h10 = e50.route[c10.startIndex], d10 = e50.route[c10.endIndex], u10 = this.getTraceConnectionNames(e50), p10 = n10 ? this.getEndpointLayers(h10, u10) : [h10.layer], m7 = n10 ? this.getEndpointLayers(d10, u10) : [d10.layer], g7 = Math.min(this.nominalTraceWidth, Math.max(h10.width, this.findMaximumSafeInPlaceWidth(e50, c10.startIndex, u10))), f7 = Math.min(this.nominalTraceWidth, Math.max(d10.width, this.findMaximumSafeInPlaceWidth(e50, c10.endIndex - 1, u10))), _7 = this.getSoftTraceIndices(this.nominalTraceWidth);
return this.layerAttemptCountByTrace.set(this.traceIndex, i10 + 1), this.layerAttempt = { interval: c10, minViaCount: n10 ? 1 : 0, maxViaCount: n10 ? 2 : 0, candidateWidths: [this.nominalTraceWidth], widthCursor: 0, gridResolutions: [q6(this.nominalTraceWidth / 4, 0.2, 0.3)], resolutionCursor: 0, offsetCursor: 0, startLayers: p10, endLayers: m7, startNeckWidth: g7, endNeckWidth: f7, softTraceIndices: _7 }, this.phase = "try-layer-candidate", true;
}
intervalSupportsLayerRouting(e50, t10) {
if (t10.startIndex >= t10.endIndex)
return false;
for (let n11 = t10.startIndex;n11 <= t10.endIndex; n11++) {
const t11 = e50.route[n11];
if (!u7(t11))
return false;
}
const n10 = e50.route[t10.startIndex], o10 = e50.route[t10.endIndex];
return n10.layer === o10.layer;
}
getEndpointLayers(e50, t10) {
return [...new Set([e50.layer, ...this.obstacleIndex.getConnectedLayersAtPoint({ x: e50.x, y: e50.y }, t10)])].filter((e54) => this.obstacleIndex.boardLayers.includes(e54));
}
getSoftTraceIndices(e50) {
const t10 = [];
for (let n10 = 0;n10 < this.traces.length; n10++) {
if (n10 === this.traceIndex)
continue;
const o10 = this.traces[n10], i10 = this.findConnectionForTrace(o10);
if (!i10)
continue;
Math.max(i10.nominalTraceWidth ?? i10.width ?? this.inputProblem.nominalTraceWidth ?? this.inputProblem.minTraceWidth, this.inputProblem.minTraceWidth) < e50 - H6 && t10.push(n10);
}
return t10;
}
startNextLayerCandidate() {
const e50 = this.layerAttempt, t10 = this.traces[this.traceIndex];
if (!e50 || !t10)
return this.layerAttempt = null, void (this.phase = "evaluate-segment");
if (e50.widthCursor >= e50.candidateWidths.length) {
const e54 = this.routeSegmentIndex;
return this.layerAttempt = null, void this.prepareRegularGridCandidates(t10, e54);
}
const n10 = e50.candidateWidths[e50.widthCursor];
if (e50.gridResolutions.length === 0 && (e50.gridResolutions = this.getGridResolutions(n10)), e50.resolutionCursor >= e50.gridResolutions.length)
return e50.widthCursor++, e50.gridResolutions = [], e50.resolutionCursor = 0, void (e50.offsetCursor = 0);
if (e50.offsetCursor >= h7.length)
return e50.resolutionCursor++, void (e50.offsetCursor = 0);
const o10 = t10.route[e50.interval.startIndex], i10 = t10.route[e50.interval.endIndex];
if (!u7(o10) || !u7(i10))
return this.layerAttempt = null, void this.prepareRegularGridCandidates(t10, this.routeSegmentIndex);
const r10 = e50.gridResolutions[e50.resolutionCursor], s10 = h7[e50.offsetCursor], a10 = s10.offset, c10 = Math.min(e50.startNeckWidth, e50.endNeckWidth), l10 = this.inputProblem.min_via_hole_diameter ?? this.inputProblem.minViaHoleDiameter ?? 0.3, h10 = Math.max(l10, this.inputProblem.min_via_pad_diameter ?? this.inputProblem.minViaPadDiameter ?? this.inputProblem.minViaDiameter ?? 0.6), d10 = Math.max(this.inputProblem.minTraceWidth, Math.min(s10.strictNecking ? e50.startNeckWidth : c10, n10)), u10 = Math.max(this.inputProblem.minTraceWidth, Math.min(s10.strictNecking ? e50.endNeckWidth : c10, n10)), p10 = q6(3 * this.nominalTraceWidth, 1.5, 3);
e50.maxViaCount > 0 ? this.attemptedLayerGridCount++ : this.attemptedGridCount++, this.activeSubSolver = new c8({ start: o10, end: i10, originalStartLayer: o10.layer, originalEndLayer: i10.layer, startLayers: e50.startLayers, endLayers: e50.endLayers, layers: this.obstacleIndex.boardLayers, traceWidth: n10, startNeckWidth: d10, endNeckWidth: u10, maxStartNeckLength: p10, maxEndNeckLength: p10, neckPenaltyExponent: s10.strictNecking ? 2 : 1, viaDiameter: h10, viaHoleDiameter: l10, minViaCount: e50.minViaCount, maxViaCount: e50.maxViaCount, viaCost: Math.max(1, 2 * this.nominalTraceWidth), gridSize: r10, gridOffset: { x: a10.x * r10, y: a10.y * r10 }, connectionNames: this.getTraceConnectionNames(t10), obstacleIndex: this.obstacleIndex, ignoreTraceIndex: this.traceIndex, ignoreRouteRange: { start: Math.max(0, e50.interval.startIndex - 1), end: Math.min(t10.route.length - 1, e50.interval.endIndex + 1) }, softTraceIndices: e50.softTraceIndices, fixedVias: this.getFixedViasOutsideInterval(t10, e50.interval), bounds: this.inputProblem.bounds, obstacleClearance: this.getDesiredPadClearance(n10), searchPadding: Math.min(5, Math.max(2.5, G6(o10, i10) / 2, 4 * n10)) });
}
startNextGridCandidate() {
const e50 = this.traces[this.traceIndex];
if (!e50)
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 t10 = this.candidateWidths[this.widthCursor], n10 = e50.route[this.routeSegmentIndex], o10 = e50.route[this.routeSegmentIndex + 1];
if (u7(n10) && u7(o10) && t10 <= Math.min(n10.width, o10.width) + H6)
return void (this.widthCursor = this.candidateWidths.length);
if (this.gridResolutions.length === 0 && (this.gridResolutions = this.getGridResolutions(t10)), this.resolutionCursor >= this.gridResolutions.length)
return this.intervalCursor++, this.resolutionCursor = 0, void (this.offsetCursor = 0);
if (this.offsetCursor >= l7.length)
return this.resolutionCursor++, void (this.offsetCursor = 0);
const i10 = this.currentIntervals[this.intervalCursor], r10 = e50.route[i10.startIndex], s10 = e50.route[i10.endIndex];
if (!u7(r10) || !u7(s10) || r10.layer !== s10.layer)
return this.intervalCursor++, this.resolutionCursor = 0, void (this.offsetCursor = 0);
if (this.endpointCollides(e50, i10, r10, t10) || this.endpointCollides(e50, i10, s10, t10))
return this.intervalCursor++, this.resolutionCursor = 0, void (this.offsetCursor = 0);
const a10 = this.gridResolutions[this.resolutionCursor], c10 = l7[this.offsetCursor], l10 = { x: c10.x * a10, y: c10.y * a10 };
this.attemptedGridCount++, this.activeSubSolver = new b8({ start: r10, end: s10, layer: r10.layer, traceWidth: t10, gridSize: a10, gridOffset: l10, connectionNames: this.getTraceConnectionNames(e50), obstacleIndex: this.obstacleIndex, ignoreTraceIndex: this.traceIndex, ignoreRouteRange: { start: Math.max(0, i10.startIndex - 1), end: Math.min(e50.route.length - 1, i10.endIndex + 1) }, bounds: this.inputProblem.bounds, obstacleClearance: this.getDesiredPadClearance(t10), searchPadding: Math.min(5, Math.max(1.5, G6(r10, s10) / 2, 3 * t10)) });
}
endpointCollides(e50, t10, n10, o10) {
return this.obstacleIndex.collides({ start: n10, end: n10, layer: n10.layer, width: o10, connectionNames: this.getTraceConnectionNames(e50), ignoreTraceIndex: this.traceIndex, ignoreRouteRange: { start: Math.max(0, t10.startIndex - 1), end: Math.min(e50.route.length - 1, t10.endIndex + 1) }, obstacleClearance: this.getDesiredPadClearance(o10) });
}
stepActiveGridSolver() {
if (this.activeSubSolver instanceof c7)
return void this.stepActiveTraceClearanceRepairSolver();
if (this.activeSubSolver instanceof s7)
return void this.stepActiveCleanupSolver();
if (this.activeSubSolver instanceof S8)
return void this.stepActiveInflationSolver();
if (this.activeSubSolver instanceof c8)
return void this.stepActiveLayerSolver();
const e50 = this.activeSubSolver;
if (e50.step(), e50.solved || e50.failed) {
if (e50.solved) {
const t10 = e50.getOutput();
if (t10) {
const e54 = this.gridRouteReplacementCollides(t10) || this.gridRouteBoundaryCollides(t10);
if (!e54 && this.gridRoutePreservesSameNetContacts(t10))
return this.applyGridRoute(this.maximizeGridRouteWidth(t10)), void (this.activeSubSolver = null);
e54 || this.sameNetContactRejectionCount++;
}
}
this.retainFailedSubSolver(e50), this.activeSubSolver = null, this.offsetCursor++;
}
}
stepActiveCleanupSolver() {
const e50 = this.activeSubSolver;
if (e50.step(), e50.solved || e50.failed) {
if (e50.solved)
return this.adoptCleanupOutput(e50), this.activeSubSolver = null, void this.startTraceClearanceRepair();
this.retainFailedSubSolver(e50), this.activeSubSolver = null, this.startTraceClearanceRepair();
}
}
adoptCleanupOutput(e50) {
const t10 = this.acceptConnectivityCheckpoint(e50.getOutput(), "cleanup");
this.cleanupCompleted = !e50.budgetLimited;
const n10 = e50.stats;
this.connectivityValidationError ??= n10.connectivityValidationError ?? null, this.connectivityValidationCount += Number(n10.connectivityValidationCount ?? 0);
const o10 = Number(n10.connectivityRollbackCount ?? 0);
o10 > 0 && (this.connectivityRollbackCount += o10, this.connectivityRollbackPhases.includes("cleanup") || this.connectivityRollbackPhases.push("cleanup"), this.connectivityRegressionEndpointIds = [...new Set([...this.connectivityRegressionEndpointIds, ...n10.connectivityRegressionEndpointIds ?? []])]);
const i10 = t10 && o10 === 0;
this.cleanupBestEffortAccepted = e50.budgetLimited && i10, this.cleanupMutatedTraceIndices = i10 ? [...n10.mutatedTraceIndices ?? []] : [], this.removedViaPairCount = i10 ? Number(n10.viaPairCountRemoved ?? 0) : 0, this.removedViaCount = i10 ? Number(n10.viaCountRemoved ?? 0) : 0, this.simplifiedPathCount = i10 ? Number(n10.simplifiedPathCount ?? 0) : 0, this.normalizedSegmentCount = i10 ? Number(n10.normalizedSegmentCount ?? 0) : 0, this.cleanupClearanceShoveCount = i10 ? Number(n10.committedClearanceShoveCount ?? 0) : 0, this.relocatedViaCount = i10 ? Number(n10.relocatedViaCount ?? 0) : 0, this.unresolvedViaCount = Number(n10.unresolvedViaCount ?? 0), this.padClearanceRerouteCount = i10 ? Number(n10.padClearanceRerouteCount ?? 0) : 0, this.unresolvedPadClearanceCount = Number(n10.unresolvedPadClearanceCount ?? 0), this.initialPadClearanceViolationCount = Number(n10.initialPadClearanceViolationCount ?? 0), this.remainingPadClearanceViolationCount = Number(n10.remainingPadClearanceViolationCount ?? 0), this.initialPadClearanceViolationCountByClearance = { ...n10.initialPadClearanceViolationCountByClearance ?? {} }, this.remainingPadClearanceViolationCountByClearance = { ...n10.remainingPadClearanceViolationCountByClearance ?? {} }, this.rebuildObstacleIndex();
}
startTraceClearanceRepair() {
this.phase = "repair-trace-clearance";
const e50 = [...new Set([...this.getOwnedTraceIndices(), ...this.expansionPushedTraceIndices, ...this.cleanupMutatedTraceIndices])], t10 = new c7({ simpleRouteJson: this.inputProblem, traces: this.traces, traceIndices: e50 });
t10.MAX_ITERATIONS = Math.min(t10.MAX_ITERATIONS, this.getRemainingParentIterationsAfterCurrentStep()), this.clearanceRepairIterationBudget = t10.MAX_ITERATIONS, this.activeSubSolver = t10;
}
stepActiveTraceClearanceRepairSolver() {
const e50 = this.activeSubSolver;
if (e50.step(), e50.solved || e50.failed) {
if (e50.solved)
return this.adoptClearanceRepairOutput(e50), this.activeSubSolver = null, void (this.phase = "complete");
this.retainFailedSubSolver(e50), this.activeSubSolver = null, this.phase = "complete";
}
}
adoptClearanceRepairOutput(e50) {
const t10 = this.acceptConnectivityCheckpoint(e50.getOutput(), "clearance-repair");
this.clearanceRepairCompleted = !e50.budgetLimited;
const n10 = e50.stats;
this.connectivityValidationError ??= n10.connectivityValidationError ?? null, this.connectivityValidationCount += Number(n10.connectivityValidationCount ?? 0);
const o10 = Number(n10.connectivityRollbackCount ?? 0);
o10 > 0 && (this.connectivityRollbackCount += o10, this.connectivityRollbackPhases.includes("clearance-repair") || this.connectivityRollbackPhases.push("clearance-repair"), this.connectivityRegressionEndpointIds = [...new Set([...this.connectivityRegressionEndpointIds, ...n10.connectivityRegressionEndpointIds ?? []])]);
const i10 = t10 && o10 === 0;
this.clearanceRepairBestEffortAccepted = e50.budgetLimited && i10, this.repairedTraceClearanceSegmentCount = i10 ? Number(n10.repairedSegmentCount ?? 0) : 0, this.repairedPadNeckSegmentCount = i10 ? Number(n10.repairedPadNeckSegmentCount ?? 0) : 0, this.unresolvedTraceClearanceSegmentCount = Number(n10.unresolvedSegmentCount ?? 0), this.rebuildObstacleIndex();
}
stepActiveLayerSolver() {
const e50 = this.activeSubSolver;
if (e50.step(), e50.solved || e50.failed) {
if (e50.solved) {
const t10 = e50.getOutput();
if (t10) {
const e54 = !this.layerRouteReplacementCollides(t10, true) && this.layerRouteImprovesInterval(t10), n10 = e54 && this.layerRoutePreservesSameNetContacts(t10);
if (n10) {
if (this.activeSubSolver = null, this.pendingLayerOutput = t10, this.pendingLayerPushCount = 0, !this.layerRouteReplacementCollides(t10, false))
return void this.applyLayerRoute(t10);
if (this.startPendingLayerInflation())
return;
this.pendingLayerOutput = null;
}
e54 && !n10 && this.sameNetContactRejectionCount++;
}
}
this.retainFailedSubSolver(e50), this.activeSubSolver = null, this.layerAttempt && this.layerAttempt.offsetCursor++, this.phase = "try-layer-candidate";
}
}
layerRouteReplacementCollides(e50, t10) {
const n10 = this.traces[this.traceIndex], o10 = this.layerAttempt;
if (!n10 || !o10)
return true;
const i10 = this.getTraceConnectionNames(n10), r10 = t10 ? o10.softTraceIndices : undefined, s10 = { start: Math.max(0, o10.interval.startIndex - 1), end: Math.min(n10.route.length - 1, o10.interval.endIndex + 1) }, a10 = this.getFixedViasOutsideInterval(n10, o10.interval);
for (let t11 = 0;t11 < e50.route.length; t11++) {
const n11 = e50.route[t11];
if (n11?.route_type === "via") {
if (this.obstacleIndex.collidesVia({ point: n11, layers: this.obstacleIndex.boardLayers, padDiameter: n11.via_diameter ?? 0.6, holeDiameter: n11.via_hole_diameter ?? this.obstacleIndex.defaultViaHoleDiameter, connectionNames: i10, ignoreTraceIndex: this.traceIndex, ignoreTraceIndices: r10, otherNewViaPoints: e50.route.slice(0, t11).filter((e54) => e54.route_type === "via").map((e54) => ({ x: e54.x, y: e54.y })), fixedVias: a10, ignoreRouteRange: s10, obstacleClearance: this.getDesiredPadClearance(e50.traceWidth), blockSameNetObstacles: true, sameNetObstacleClearance: 0 }))
return true;
continue;
}
const o11 = e50.route[t11 + 1];
if (n11?.route_type === "wire" && o11?.route_type === "wire" && n11.layer === o11.layer && this.obstacleIndex.collides({ start: n11, end: o11, layer: n11.layer, width: Math.max(n11.width, o11.width), connectionNames: i10, ignoreTraceIndex: this.traceIndex, ignoreTraceIndices: r10, ignoreRouteRange: s10, obstacleClearance: this.getDesiredPadClearance(e50.traceWidth) }))
return true;
}
return this.layerRouteBoundaryCollides(e50, t10);
}
getFixedViasOutsideInterval(e50, t10) {
return e50.route.flatMap((e54, n10) => e54.route_type !== "via" || n10 >= t10.startIndex && n10 <= t10.endIndex ? [] : [{ point: { x: e54.x, y: e54.y }, padDiameter: e54.via_diameter ?? 0.6, holeDiameter: e54.via_hole_diameter ?? this.obstacleIndex.defaultViaHoleDiameter }]);
}
layerRouteBoundaryCollides(e50, t10) {
const n10 = this.traces[this.traceIndex], o10 = this.layerAttempt, i10 = e50.route.find((e54) => e54.route_type === "wire");
let r10;
for (let t11 = e50.route.length - 1;t11 >= 0; t11--) {
const n11 = e50.route[t11];
if (n11?.route_type === "wire") {
r10 = n11;
break;
}
}
if (!i10 || !r10)
return true;
const s10 = [{ outside: n10.route[o10.interval.startIndex - 1], inside: i10 }, { outside: n10.route[o10.interval.endIndex + 1], inside: r10 }];
for (const i11 of s10)
if (u7(i11.outside) && i11.outside.layer === i11.inside.layer && this.obstacleIndex.collides({ start: i11.outside, end: i11.inside, layer: i11.inside.layer, width: Math.max(i11.outside.width, i11.inside.width), connectionNames: this.getTraceConnectionNames(n10), ignoreTraceIndex: this.traceIndex, ignoreTraceIndices: t10 ? o10.softTraceIndices : undefined, ignoreRouteRange: { start: Math.max(0, o10.interval.startIndex - 1), end: Math.min(n10.route.length - 1, o10.interval.endIndex + 1) }, obstacleClearance: this.getDesiredPadClearance(e50.traceWidth) }))
return true;
return false;
}
layerRouteImprovesInterval(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.layerAttempt.interval, o10 = this.getRouteQuality(t10.route.slice(n10.startIndex, n10.endIndex + 1)), i10 = this.getRouteQuality(e50.route);
return i10.length <= o10.length + 10 + H6 && i10.deficitArea <= o10.deficitArea - Math.max(0.05, 0.1 * o10.deficitArea);
}
getRouteQuality(e50) {
let t10 = 0, n10 = 0;
for (let o10 = 0;o10 < e50.length - 1; o10++) {
const i10 = e50[o10], r10 = e50[o10 + 1];
if (!u7(i10) || !u7(r10) || i10.layer !== r10.layer)
continue;
const s10 = G6(i10, r10), a10 = Math.min(i10.width, r10.width);
t10 += s10, n10 += s10 * Math.max(0, this.nominalTraceWidth - a10);
}
return { length: t10, deficitArea: n10 };
}
getLayerInflationCorridor(e50) {
const t10 = [];
for (let n10 = 0;n10 < e50.route.length; n10++) {
const o10 = e50.route[n10];
if (o10?.route_type === "via") {
for (const e54 of this.obstacleIndex.boardLayers)
t10.push({ start: o10, end: o10, layer: e54, width: o10.via_diameter ?? 0.6 });
continue;
}
const i10 = e50.route[n10 + 1];
o10?.route_type === "wire" && i10?.route_type === "wire" && o10.layer === i10.layer && t10.push({ start: o10, end: i10, layer: o10.layer, width: Math.max(o10.width, i10.width) });
}
return t10;
}
startPendingLayerInflation() {
const e50 = this.pendingLayerOutput;
if (!e50 || this.pendingLayerPushCount >= 2)
return false;
const t10 = this.getLayerInflationCorridor(e50);
return t10.length !== 0 && (this.pendingLayerPushCount++, this.attemptedInflationCount++, this.activeSubSolver = new S8({ simpleRouteJson: this.inputProblem, traces: this.traces, powerTraceIndex: this.traceIndex, nominalPowerWidth: e50.traceWidth, mutableTraceIndices: this.mutableBlockerTraceIndices, corridor: t10, maxRerouteLength: 10 }, this.connectionNameResolver), this.phase = "try-trace-inflation", true);
}
applyLayerRoute(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.layerAttempt.interval, o10 = this.createLayerRouteReplacement(e50);
t10.route.splice(n10.startIndex, n10.endIndex - n10.startIndex + 1, ...o10), e50.viaCount > 0 && this.layerReroutedTraceCount++, this.layerRerouteCountByTrace.set(this.traceIndex, (this.layerRerouteCountByTrace.get(this.traceIndex) ?? 0) + 1), this.reroutedSegmentCount++, this.insertedViaCount += e50.viaCount, e50.viaCount > 0 && (this.neckedLayerSegmentCount += o10.filter((e54) => e54.route_type === "wire" && e54.width < this.nominalTraceWidth - H6).length), this.routeSegmentIndex = n10.startIndex, this.currentIntervals = [], this.layerAttempt = null, this.pendingLayerOutput = null, this.pendingLayerPushCount = 0, this.phase = "evaluate-segment";
}
createLayerRouteReplacement(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.layerAttempt.interval, o10 = t10.route[n10.startIndex], i10 = t10.route[n10.endIndex], r10 = structuredClone(e50.route), s10 = r10.findIndex((e54) => e54.route_type === "wire");
let a10 = -1;
for (let e54 = r10.length - 1;e54 >= 0; e54--)
if (r10[e54]?.route_type === "wire") {
a10 = e54;
break;
}
return s10 >= 0 && (r10[s10] = { ...o10, ...r10[s10] }), a10 >= 0 && (r10[a10] = { ...i10, ...r10[a10] }), r10;
}
layerRoutePreservesSameNetContacts(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.layerAttempt.interval;
return this.routeReplacementPreservesSameNetContacts(t10, n10, this.createLayerRouteReplacement(e50));
}
startTraceInflation(e50, t10) {
const n10 = e50.route[t10], o10 = e50.route[t10 + 1];
if (!u7(n10) || !u7(o10))
return false;
const i10 = Math.min(n10.width, o10.width), r10 = this.findBestPushableInflationWidth(e50, t10, i10);
if (!r10)
return false;
const s10 = this.getLocalInflationCorridor(e50, t10, r10);
if (s10.length === 0)
return false;
const a10 = [this.traceIndex, n10.x, n10.y, o10.x, o10.y].join(":"), c10 = this.inflationAttemptsBySegment.get(a10) ?? 0;
return !(c10 >= 2) && (this.inflationAttemptsBySegment.set(a10, c10 + 1), this.activeInflationKey = a10, this.activeInflationWidth = r10, this.attemptedInflationCount++, this.activeSubSolver = new S8({ simpleRouteJson: this.inputProblem, traces: this.traces, powerTraceIndex: this.traceIndex, nominalPowerWidth: r10, mutableTraceIndices: this.mutableBlockerTraceIndices, corridor: s10, maxRerouteLength: 10 }, this.connectionNameResolver), this.phase = "try-trace-inflation", true);
}
hasOnlyPushableTraceBlockers(e50, t10, n10) {
const o10 = Math.max(0, t10 - 1), i10 = Math.min(e50.route.length - 2, t10 + 1), r10 = new Set;
for (let t11 = o10;t11 <= i10; t11++) {
const s10 = e50.route[t11], a10 = e50.route[t11 + 1];
if (!u7(s10) || !u7(a10) || s10.layer !== a10.layer)
continue;
const c10 = { start: s10, end: a10, layer: s10.layer, width: n10, connectionNames: this.getTraceConnectionNames(e50), ignoreTraceIndex: this.traceIndex, ignoreRouteRange: { start: o10, end: i10 + 1 }, obstacleClearance: this.getDesiredPadClearance(n10) }, l10 = this.obstacleIndex.findCollisions(c10);
if (l10.length === 0 && this.obstacleIndex.collides(c10))
return false;
for (const e54 of l10) {
if (e54.kind !== "trace" || e54.traceIndex === undefined)
return false;
const t12 = this.traces[e54.traceIndex];
if (!t12)
return false;
const o11 = this.findConnectionForTrace(t12);
if (!o11 || (o11.nominalTraceWidth ?? o11.width ?? this.inputProblem.nominalTraceWidth ?? this.inputProblem.minTraceWidth) >= n10 - H6)
return false;
r10.add(e54.traceIndex);
}
}
return r10.size > 0 && r10.size <= 2;
}
findBestPushableInflationWidth(e50, t10, n10) {
const o10 = this.nominalTraceWidth >= 0.5 ? 0.05 : 0.0125;
for (let i10 = this.nominalTraceWidth;i10 > n10 + H6; i10 -= o10) {
const n11 = Number(i10.toFixed(6));
if (this.hasOnlyPushableTraceBlockers(e50, t10, n11))
return n11;
}
return null;
}
stepActiveInflationSolver() {
const e50 = this.activeSubSolver;
if (e50.step(), e50.solved || e50.failed) {
if (e50.solved) {
const t10 = e50.getOutput(), n10 = t10 && this.sameNetContactsArePreserved(this.traces[t10.pushedTraceIndex].route, t10.traces[t10.pushedTraceIndex].route, this.getTraceConnectionNames(this.traces[t10.pushedTraceIndex]), t10.pushedTraceIndex);
if (t10 && n10) {
if (this.traces = t10.traces, this.pushedTraceCount++, this.expansionPushedTraceIndices.add(t10.pushedTraceIndex), t10.strategy === "elastic" && this.elasticPushedTraceCount++, this.activeSubSolver = null, this.activeInflationKey = null, this.activeInflationWidth = null, this.rebuildObstacleIndex(), this.pendingLayerOutput) {
if (!this.layerRouteReplacementCollides(this.pendingLayerOutput, false) && 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");
}
t10 && !n10 && this.sameNetContactRejectionCount++;
}
if (this.retainFailedSubSolver(e50), 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(e50, t10, n10) {
const o10 = e50.route[t10], i10 = e50.route[t10 + 1];
if (!u7(o10) || !u7(i10) || o10.layer !== i10.layer)
return [];
const r10 = q6(4 * n10, 2, 4), s10 = r10 / 2;
let a10 = t10, c10 = 0;
for (;a10 > 0; ) {
const t11 = e50.route[a10 - 1], n11 = e50.route[a10];
if (!u7(t11) || !u7(n11) || t11.layer !== n11.layer)
break;
const o11 = G6(t11, n11);
if (c10 + o11 > s10 + H6)
break;
c10 += o11, a10--;
}
let l10 = t10 + 1, h10 = 0;
for (;l10 < e50.route.length - 1; ) {
const t11 = e50.route[l10], n11 = e50.route[l10 + 1];
if (!u7(t11) || !u7(n11) || t11.layer !== n11.layer)
break;
const o11 = G6(t11, n11);
if (h10 + o11 > s10 + H6)
break;
h10 += o11, l10++;
}
let d10 = r10 - c10 - h10;
for (;d10 > H6 && a10 > 0; ) {
const t11 = e50.route[a10 - 1], n11 = e50.route[a10];
if (!u7(t11) || !u7(n11) || t11.layer !== n11.layer)
break;
const o11 = G6(t11, n11);
if (o11 > d10 + H6)
break;
d10 -= o11, a10--;
}
for (;d10 > H6 && l10 < e50.route.length - 1; ) {
const t11 = e50.route[l10], n11 = e50.route[l10 + 1];
if (!u7(t11) || !u7(n11) || t11.layer !== n11.layer)
break;
const o11 = G6(t11, n11);
if (o11 > d10 + H6)
break;
d10 -= o11, l10++;
}
const u10 = [];
for (let t11 = a10;t11 < l10; t11++) {
const o11 = e50.route[t11], i11 = e50.route[t11 + 1];
u7(o11) && u7(i11) && o11.layer === i11.layer && u10.push({ start: o11, end: i11, layer: o11.layer, width: n10 });
}
return u10;
}
applyGridRoute(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.currentIntervals[this.intervalCursor], o10 = this.createGridRouteReplacement(e50);
t10.route.splice(n10.startIndex, n10.endIndex - n10.startIndex + 1, ...o10), this.reroutedSegmentCount++, this.routeSegmentIndex = n10.startIndex + o10.length - 1, this.currentIntervals = [], this.phase = "evaluate-segment";
}
createGridRouteReplacement(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.currentIntervals[this.intervalCursor], o10 = t10.route[n10.startIndex], i10 = t10.route[n10.endIndex], r10 = e50.points.map((t11) => ({ route_type: "wire", x: t11.x, y: t11.y, width: e50.traceWidth, layer: o10.layer }));
return r10[0].width = Math.max(o10.width, e50.traceWidth), r10[r10.length - 1].width = Math.max(i10.width, e50.traceWidth), r10;
}
gridRoutePreservesSameNetContacts(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.currentIntervals[this.intervalCursor];
return this.routeReplacementPreservesSameNetContacts(t10, n10, this.createGridRouteReplacement(e50));
}
routeReplacementPreservesSameNetContacts(e50, t10, n10) {
const o10 = this.getTraceConnectionNames(e50), i10 = this.getSameNetContactIds(e50.route.slice(t10.startIndex, t10.endIndex + 1), o10, this.traceIndex), r10 = new Set([...this.getSameNetContactIds(e50.route.slice(0, t10.startIndex + 1), o10, this.traceIndex), ...this.getSameNetContactIds(e50.route.slice(t10.endIndex), o10, this.traceIndex)]), s10 = new Set([...i10].filter((e54) => !r10.has(e54)));
if (s10.size === 0)
return true;
const a10 = this.getSameNetContactIds(n10, o10, this.traceIndex);
return [...s10].every((e54) => a10.has(e54));
}
sameNetContactsArePreserved(e50, t10, n10, o10) {
const i10 = this.getSameNetContactIds(e50, n10, o10);
if (i10.size === 0)
return true;
const r10 = this.getSameNetContactIds(t10, n10, o10);
return [...i10].every((e54) => r10.has(e54));
}
getSameNetContactIds(e50, t10, n10) {
const o10 = new Set;
for (let i10 = 0;i10 < e50.length; i10++) {
const r10 = e50[i10];
if (r10?.route_type === "via") {
for (const e54 of this.getViaLayers(r10))
for (const i11 of this.obstacleIndex.getSameNetCopperContactIds({ start: r10, end: r10, layer: e54, width: r10.via_diameter ?? 0.6, connectionNames: t10, ignoreTraceIndex: n10 }))
o10.add(i11);
continue;
}
const s10 = e50[i10 + 1];
if (r10?.route_type === "wire" && s10?.route_type === "wire" && r10.layer === s10.layer)
for (const e54 of this.obstacleIndex.getSameNetCopperContactIds({ start: r10, end: s10, layer: r10.layer, width: Math.min(r10.width, s10.width), connectionNames: t10, ignoreTraceIndex: n10 }))
o10.add(e54);
}
return o10;
}
getViaLayers(e50) {
const t10 = this.obstacleIndex.boardLayers.indexOf(e50.from_layer), n10 = this.obstacleIndex.boardLayers.indexOf(e50.to_layer);
return t10 < 0 || n10 < 0 ? this.obstacleIndex.boardLayers : this.obstacleIndex.boardLayers.slice(Math.min(t10, n10), Math.max(t10, n10) + 1);
}
gridRouteReplacementCollides(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.currentIntervals[this.intervalCursor], o10 = t10.route[n10.startIndex], i10 = t10.route[n10.endIndex], r10 = this.getTraceConnectionNames(t10);
for (let s10 = 0;s10 < e50.points.length - 1; s10++) {
const a10 = Math.max(e50.traceWidth, s10 === 0 ? o10.width : 0, s10 === e50.points.length - 2 ? i10.width : 0);
if (this.obstacleIndex.collides({ start: e50.points[s10], end: e50.points[s10 + 1], layer: o10.layer, width: a10, connectionNames: r10, ignoreTraceIndex: this.traceIndex, ignoreRouteRange: { start: Math.max(0, n10.startIndex - 1), end: Math.min(t10.route.length - 1, n10.endIndex + 1) }, obstacleClearance: this.getDesiredPadClearance(a10) }))
return true;
}
return false;
}
gridRouteBoundaryCollides(e50) {
const t10 = this.traces[this.traceIndex], n10 = this.currentIntervals[this.intervalCursor], o10 = this.getTraceConnectionNames(t10), i10 = [{ startIndex: n10.startIndex - 1, endIndex: n10.startIndex }, { startIndex: n10.endIndex, endIndex: n10.endIndex + 1 }];
for (const n11 of i10) {
const i11 = t10.route[n11.startIndex], r10 = t10.route[n11.endIndex];
if (u7(i11) && u7(r10) && i11.layer === r10.layer && this.obstacleIndex.collides({ start: i11, end: r10, layer: i11.layer, width: Math.max(i11.width, r10.width, e50.traceWidth), connectionNames: o10, ignoreTraceIndex: this.traceIndex, ignoreRouteRange: { start: n11.startIndex, end: n11.endIndex }, obstacleClearance: this.getDesiredPadClearance(Math.max(i11.width, r10.width, e50.traceWidth)) }))
return true;
}
return false;
}
canExpandSegmentAndEndpoints(e50, t10, n10, o10 = this.nominalTraceWidth) {
const i10 = Math.max(0, t10 - 1), r10 = Math.min(e50.route.length - 2, t10 + 1);
for (let s10 = i10;s10 <= r10; s10++) {
const a10 = e50.route[s10], c10 = e50.route[s10 + 1];
if (!u7(a10) || !u7(c10) || a10.layer !== c10.layer)
continue;
const l10 = s10 <= t10 + 1 && s10 + 1 >= t10, h10 = Math.max(a10.width, c10.width, l10 ? o10 : 0);
if (this.obstacleIndex.collides({ start: a10, end: c10, layer: a10.layer, width: h10, connectionNames: n10, ignoreTraceIndex: this.traceIndex, ignoreRouteRange: { start: i10, end: r10 + 1 }, obstacleClearance: this.getDesiredPadClearance(h10) }))
return false;
}
return true;
}
findMaximumSafeInPlaceWidth(e50, t10, n10) {
const o10 = e50.route[t10], i10 = e50.route[t10 + 1];
if (!u7(o10) || !u7(i10))
return 0;
const r10 = Math.min(o10.width, i10.width);
if (this.probeInPlaceWidth(e50, t10, n10, this.nominalTraceWidth))
return this.nominalTraceWidth;
let s10 = r10, a10 = this.nominalTraceWidth;
for (let o11 = 0;o11 < 7; o11++) {
const o12 = (s10 + a10) / 2;
if (o12 <= s10 + H6)
break;
this.probeInPlaceWidth(e50, t10, n10, o12) ? s10 = o12 : a10 = o12;
}
const c10 = this.nominalTraceWidth >= 0.5 ? 0.025 : 0.0125, l10 = Math.max(r10, Math.floor((s10 + H6) / c10) * c10);
return l10 > r10 + H6 && this.probeInPlaceWidth(e50, t10, n10, l10) ? l10 : r10;
}
probeInPlaceWidth(e50, t10, n10, o10) {
return this.inPlaceWidthProbeCount++, this.canExpandSegmentAndEndpoints(e50, t10, n10, o10);
}
maximizeGridRouteWidth(e50) {
if (e50.traceWidth >= this.nominalTraceWidth - H6)
return e50;
let t10 = e50.traceWidth, n10 = this.nominalTraceWidth;
for (let o11 = 0;o11 < 7; o11++) {
const o12 = (t10 + n10) / 2, i11 = { ...e50, traceWidth: o12 };
this.gridRouteReplacementCollides(i11) || this.gridRouteBoundaryCollides(i11) ? n10 = o12 : t10 = o12;
}
const o10 = this.nominalTraceWidth >= 0.5 ? 0.025 : 0.0125, i10 = Math.max(e50.traceWidth, Math.floor((t10 + H6) / o10) * o10);
if (i10 > e50.traceWidth + H6) {
const t11 = { ...e50, traceWidth: i10 };
if (!this.gridRouteReplacementCollides(t11) && !this.gridRouteBoundaryCollides(t11))
return this.pathWidthUpgradeCount++, t11;
}
return e50;
}
getExponentialIntervalCandidates(e50, t10, n10) {
const o10 = this.getExponentialIndices(e50, t10, -1, n10, 5), i10 = this.getExponentialIndices(e50, t10, 1, n10, 10).filter((e54) => e54 > t10), r10 = [];
for (const t11 of o10)
for (const n11 of i10) {
const o11 = this.getRouteIntervalLength(e50, t11, n11);
o11 > 10.000001 || r10.push({ startIndex: t11, endIndex: n11, routeLength: o11 });
}
return r10.sort((e54, t11) => e54.routeLength - t11.routeLength).filter((e54, t11, n11) => n11.findIndex((t12) => t12.startIndex === e54.startIndex && t12.endIndex === e54.endIndex) === t11).slice(0, 10).map(({ startIndex: e54, endIndex: t11 }) => ({ startIndex: e54, endIndex: t11 }));
}
getExponentialIndices(e50, t10, n10, o10, i10) {
const r10 = [t10];
let s10 = 0, a10 = Math.max(o10, 0.3), c10 = t10, l10 = t10;
for (;; ) {
const t11 = c10 + n10;
if (t11 < 0 || t11 >= e50.route.length)
break;
const o11 = e50.route[c10], h10 = e50.route[t11];
if (!u7(o11) || !u7(h10) || o11.layer !== h10.layer)
break;
const d10 = G6(o11, h10);
if (s10 + d10 > i10 + H6)
break;
s10 += d10, c10 = t11, l10 = t11, s10 + H6 >= a10 && (r10.push(t11), a10 *= 2);
}
return r10.includes(l10) || r10.push(l10), r10;
}
getRouteIntervalLength(e50, t10, n10) {
let o10 = 0;
for (let i10 = t10;i10 < n10; i10++) {
const t11 = e50.route[i10], n11 = e50.route[i10 + 1];
if (!u7(t11) || !u7(n11) || t11.layer !== n11.layer)
return Number.POSITIVE_INFINITY;
o10 += G6(t11, n11);
}
return o10;
}
getCandidateWidths(e50) {
const t10 = this.inputProblem.minTraceWidth;
return d7([e50, 0.875 * e50, 0.75 * e50, 0.625 * e50, 0.5 * e50, 0.375 * e50, 0.25 * e50, t10]).filter((e54) => e54 >= t10 - H6);
}
getGridResolutions(e50) {
return d7([Math.max(0.1, Math.min(0.5, e50 / 2)), Math.max(0.1, Math.min(0.25, e50 / 3))]);
}
resolveNominalTraceWidth(e50) {
const t10 = this.findConnectionForTrace(e50);
return Math.max(t10?.nominalTraceWidth ?? t10?.width ?? this.inputProblem.nominalTraceWidth ?? this.inputProblem.minTraceWidth, this.inputProblem.minTraceWidth);
}
getDesiredPadClearance(e50 = this.nominalTraceWidth) {
const t10 = Math.max(this.inputProblem.defaultObstacleMargin ?? 0, this.inputProblem.minTraceToPadEdgeClearance ?? 0, 0.1);
return e50 < 0.499999 || this.phase !== "cleanup" ? t10 : Math.max(t10, this.options.powerTraceToPadClearance ?? e50 / 2);
}
findConnectionForTrace(e50) {
const t10 = this.connectionByTraceId.get(e50.pcb_trace_id);
if (t10 !== undefined)
return t10 ?? undefined;
const n10 = this.getTraceConnectionNames(e50), o10 = this.inputProblem.connections.find((e54) => this.connectionMatchesTrace(e54, n10)) ?? null;
return this.connectionByTraceId.set(e50.pcb_trace_id, o10), o10 ?? undefined;
}
getOwnedTraceIndices() {
return [...this.selectedOwnedTraceIndices];
}
connectionMatchesTrace(e50, t10) {
return [e50.name, e50.source_trace_id, e50.rootConnectionName, e50.netConnectionName, ...e50.mergedConnectionNames ?? []].filter((e54) => Boolean(e54)).some((e54) => t10.includes(e54));
}
getTraceConnectionNames(e50) {
return [e50.connection_name, e50.source_trace_id, e50.rootConnectionName, ...e50.mergedConnectionNames ?? []].filter((e54) => Boolean(e54));
}
traceMeetsNominalWidth(e50, t10) {
return e50.route.every((e54) => e54.route_type !== "wire" || e54.width >= t10 - H6);
}
findNextUnderWidthSegment(e50, t10, n10) {
for (let o10 = t10;o10 < e50.route.length - 1; o10++) {
const t11 = e50.route[o10], i10 = e50.route[o10 + 1];
if (u7(t11) && u7(i10) && t11.layer === i10.layer && (t11.width < n10 - H6 || i10.width < n10 - H6))
return o10;
}
return -1;
}
getMutatedImmutableTraceIds(e50) {
return this.immutableTraceIndices.flatMap((t10) => {
const n10 = e50[t10];
return JSON.stringify(n10) === this.initialImmutableTraceSignatures.get(t10) ? [] : [n10?.pcb_trace_id ?? this.traces[t10]?.pcb_trace_id ?? String(t10)];
});
}
getImmutableViaViolationSignatures(e50) {
const t10 = new Set;
if (this.immutableTraceIndices.length === 0)
return t10;
const n10 = new V6(this.inputProblem, e50), o10 = new x8(this.inputProblem, e50, undefined, [], n10);
for (const n11 of this.immutableTraceIndices) {
const i10 = e50[n11];
if (!i10)
continue;
const r10 = [i10.pcb_trace_id, i10.connection_name, i10.source_trace_id, i10.rootConnectionName, ...i10.mergedConnectionNames ?? [], ...i10.connectsTo ?? []].filter((e54) => Boolean(e54));
for (let e54 = 0;e54 < i10.route.length; e54++) {
const s10 = i10.route[e54];
if (s10?.route_type !== "via")
continue;
const a10 = `${i10.pcb_trace_id}:${e54}`, c10 = o10.getViaViolationSignatures({ point: s10, layers: o10.boardLayers, padDiameter: s10.via_diameter ?? this.inputProblem.min_via_pad_diameter ?? this.inputProblem.minViaPadDiameter ?? this.inputProblem.minViaDiameter ?? 0.6, holeDiameter: s10.via_hole_diameter ?? o10.defaultViaHoleDiameter, connectionNames: r10, ignoreTraceIndex: n11, ignoreRouteRange: { start: e54, end: e54 }, blockSameNetObstacles: true, sameNetObstacleClearance: 0 });
for (const e58 of c10)
t10.add(`${a10}|${e58}`);
}
}
return t10;
}
countViolatingImmutableVias(e50) {
return new Set([...e50].map((e54) => e54.split("|")[0])).size;
}
acceptConnectivityCheckpoint(e50, t10) {
this.connectivityValidationCount++;
let n10 = false, o10 = false;
try {
const t11 = this.connectivityInvariant.validate(e50), i10 = this.getMutatedImmutableTraceIds(e50), r10 = this.getImmutableViaViolationSignatures(e50), s10 = [...r10].filter((e54) => !this.lastSafeImmutableViaViolationSignatures.has(e54)), a10 = s10.length > 0;
if (n10 = !t11.safe, o10 = i10.length > 0 || a10, this.connectivityValidationError ??= t11.validationError ?? null, !n10 && !o10)
return this.traces = structuredClone(e50), this.lastConnectivitySafeTraces = structuredClone(e50), this.remainingImmutableViaViolationCount = this.countViolatingImmutableVias(r10), this.remainingImmutableViaViolationPairCount = r10.size, this.lastSafeImmutableViaViolationSignatures = r10, this.connectivityInvariant = new K8(this.inputProblem, this.lastConnectivitySafeTraces), true;
this.immutableTraceMutationIds = [...new Set([...this.immutableTraceMutationIds, ...i10])], a10 && (this.immutableViaViolationRollbackCount++, this.attemptedImmutableViaViolationCount = this.countViolatingImmutableVias(r10), this.attemptedImmutableViaViolationPairCount = r10.size, this.immutableViaViolationRegressionIds = [...new Set([...this.immutableViaViolationRegressionIds, ...s10])]), this.connectivityRegressionEndpointIds = [...new Set([...this.connectivityRegressionEndpointIds, ...t11.regressions.flatMap((e54) => e54.baselineEndpointLabels)])];
} catch (e54) {
n10 = true, this.connectivityValidationError = e54 instanceof Error ? e54.message : String(e54);
}
return n10 && (this.connectivityRollbackCount++, this.connectivityRollbackPhases.includes(t10) || this.connectivityRollbackPhases.push(t10)), o10 && (this.immutableSafetyRollbackCount++, this.immutableSafetyRollbackPhases.includes(t10) || this.immutableSafetyRollbackPhases.push(t10)), t10 === "expansion" ? n10 ? this.rollbackConnectivityRegressedExpansion() : this.rollbackImmutableUnsafeExpansion() : this.restoreLastConnectivitySafeTraces(), this.remainingImmutableViaViolationCount = this.countViolatingImmutableVias(this.lastSafeImmutableViaViolationSignatures), this.remainingImmutableViaViolationPairCount = this.lastSafeImmutableViaViolationSignatures.size, false;
}
rebuildObstacleIndex() {
this.obstacleIndex = new x8(this.inputProblem, this.traces, this.traceIndex, [], this.connectionNameResolver);
}
retainFailedSubSolver(e50) {
this.failedSubSolverCount++, this.failedSubSolvers ??= [], this.failedSubSolvers.length < 16 ? this.failedSubSolvers.push(e50) : this.failedSubSolvers[15] = e50;
}
tryFinalAcceptance() {
this.finalAcceptanceUsed = true;
let e50 = false;
this.activeSubSolver instanceof s7 ? (this.activeSubSolver.tryFinalAcceptance(), this.adoptCleanupOutput(this.activeSubSolver), e50 = true) : this.activeSubSolver instanceof c7 && (this.activeSubSolver.tryFinalAcceptance(), this.adoptClearanceRepairOutput(this.activeSubSolver), e50 = true), e50 || this.phase === "cleanup" || this.phase === "repair-trace-clearance" || this.phase === "complete" || 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 = true, 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: this.connectivityRollbackMutationStats === null ? null : { ...this.connectivityRollbackMutationStats }, immutableSafetyRollbackMutationStats: this.immutableSafetyRollbackMutationStats === null ? null : { ...this.immutableSafetyRollbackMutationStats }, expansionPushedTraceIndices: [...this.expansionPushedTraceIndices], cleanupMutatedTraceIndices: [...this.cleanupMutatedTraceIndices], discardedExpansionMutationStats: this.discardedExpansionMutationStats === null ? 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" : this.phase === "cleanup" ? "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" : this.phase === "repair-trace-clearance" ? "in_progress" : "not_started", cleanupIterationBudget: this.cleanupIterationBudget, clearanceRepairIterationBudget: this.clearanceRepairIterationBudget, completionReason: this.phase === "complete" || 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 || this.connectivityValidationError !== null || 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 || this.phase === "complete" ? 1 : this.budgetLimitedExpansion ? 0.99 : this.traceOrder.length === 0 ? 1 : Math.min(0.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 e50 = [], t10 = [];
for (let n10 = 0;n10 < this.traces.length; n10++) {
const o10 = this.traces[n10], i10 = this.resolveNominalTraceWidth(o10);
for (const e54 of o10.route)
e54.route_type === "via" && t10.push({ center: e54, radius: (e54.via_diameter ?? 0.6) / 2, fill: "#d4a017", stroke: "#7a5700" });
for (let t11 = 0;t11 < o10.route.length - 1; t11++) {
const r10 = o10.route[t11], s10 = o10.route[t11 + 1];
if (!u7(r10) || !u7(s10) || r10.layer !== s10.layer)
continue;
const a10 = n10 === this.traceIndex && t11 === this.routeSegmentIndex, c10 = r10.width >= i10 - H6 && s10.width >= i10 - H6, l10 = r10.layer === "bottom";
e50.push({ points: [r10, s10], strokeColor: a10 ? "#ff8c00" : c10 ? l10 ? "#2468c7" : "#169c45" : l10 ? "#8b4bb8" : "#cc3344", strokeWidth: Math.max(r10.width, s10.width) });
}
}
return { coordinateSystem: "cartesian", title: `Power trace expander: ${this.phase}`, lines: e50, points: [], circles: t10, rects: this.obstacleIndex.items.filter((e54) => e54.kind === "obstacle").slice(0, 2000).map((e54) => ({ center: { x: (e54.minX + e54.maxX) / 2, y: (e54.minY + e54.maxY) / 2 }, width: e54.maxX - e54.minX, height: e54.maxY - e54.minY, fill: "rgba(80,80,80,0.12)", stroke: "rgba(80,80,80,0.35)" })), texts: [] };
}
};
var m7 = class extends ai {
constructor(e50, t10 = {}) {
if (super(), this.inputSrj = e50, this.options = t10, this.powerTraceExpanderSolver = new p7(e50, t10), t10.onlyConnectionNames?.length === 0)
return this.MAX_ITERATIONS = 1, this.progress = 1, this.solved = true, void (this.stats = { selectedTraceCount: 0, bypassed: true });
this.MAX_ITERATIONS = this.powerTraceExpanderSolver.MAX_ITERATIONS + 1;
}
inputSrj;
options;
powerTraceExpanderSolver;
_step() {
const e50 = this.powerTraceExpanderSolver;
if (e50.step(), this.progress = e50.progress, this.stats = e50.stats, e50.failed)
return this.error = e50.error, void (this.failed = true);
e50.solved && (this.solved = true);
}
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 Go({ ...this.inputSrj, traces: this.getOutput() }, { traceColorMode: "layer" });
}
};
var g7 = ({ connections: e50, originalConnections: t10, layerCount: n10, obstacles: o10, defaultViaHoleDiameter: i10, connMap: r10 }) => {
const s10 = new Map;
for (const e54 of t10)
s10.has(e54.name) || s10.set(e54.name, e54.__netConnectionName);
const a10 = e50.map((e54) => {
if (e54.pointsToConnect.length !== 2)
throw new Error(`Expected Pipeline7 output connection "${e54.name}" to have two points, got ${e54.pointsToConnect.length}`);
const [t11, n11] = e54.pointsToConnect;
return { connection: e54, connectsTo: [t11?.pointId, n11?.pointId].filter((e58) => Boolean(e58)), outputConnectionName: e54.__netConnectionName ?? s10.get(e54.name) ?? e54.__rootConnectionNames?.[0] ?? e54.name };
}), c10 = o10.filter((e54) => (e54.__zLayers?.length ?? e54.layers?.length ?? 0) > 1), l10 = new Map, h10 = (e54) => {
let t11 = l10.get(e54.connectionName);
t11 || (t11 = new Map, l10.set(e54.connectionName, t11));
const n11 = t11.get(e54.rootConnectionName);
if (n11)
return n11;
const o11 = c10.filter((t12) => vo(t12, e54, r10));
return t11.set(e54.rootConnectionName, o11), o11;
};
return (e54) => {
const t11 = [], o11 = new Map;
for (const t12 of e54) {
const e58 = o11.get(t12.connectionName);
e58 ? e58.push(t12) : o11.set(t12.connectionName, [t12]);
}
for (const { connection: e58, connectsTo: s11, outputConnectionName: c11 } of a10) {
const a11 = o11.get(e58.name) ?? [];
for (let o12 = 0;o12 < a11.length; o12 += 1) {
const l11 = a11[o12];
t11.push({ type: "pcb_trace", pcb_trace_id: `${e58.name}_${o12}`, connection_name: c11, connectsTo: s11, route: Ro(l11, n10, { connectionPoints: e58.pointsToConnect, defaultViaHoleDiameter: i10, connectedMultilayerObstacles: h10(l11), connMap: r10 }) });
}
}
return t11;
};
};
var f7 = ({ connections: e50, originalConnections: t10, hdRoutes: n10, layerCount: o10, obstacles: i10, defaultViaHoleDiameter: r10, connMap: s10 }) => g7({ connections: e50, originalConnections: t10, layerCount: o10, obstacles: i10, defaultViaHoleDiameter: r10, connMap: s10 })(n10);
var _7 = (e50) => {
const t10 = Math.max(e50.minTraceWidth + 0.1, 2 * e50.minTraceWidth);
return e50.connections.flatMap((n10) => (n10.nominalTraceWidth ?? e50.nominalTraceWidth ?? e50.minTraceWidth) + 0.000001 >= t10 ? [n10.name] : []);
};
var y7 = (e50, t10, n10 = new Map(e50.map((e54) => [e54.connectionName, e54]))) => {
const o10 = new Map(t10.map((e54) => [e54.name, e54]));
return e50.map((e54) => {
if (e54.route.length === 0)
throw new Error(`Cannot lock PCB terminals for empty route "${e54.connectionName}"`);
const t11 = o10.get(e54.connectionName);
if (!t11)
throw new Error(`Cannot lock PCB terminals: connection "${e54.connectionName}" was not found`);
if (t11.pointsToConnect.length !== 2)
throw new Error(`Cannot lock PCB terminals for "${e54.connectionName}": expected 2 connection points, found ${t11.pointsToConnect.length}`);
const i10 = n10.get(e54.connectionName) ?? e54, r10 = new Map;
for (const n11 of t11.pointsToConnect)
if (n11.pcb_port_id) {
if (r10.has(n11.pcb_port_id))
throw new Error(`Cannot lock duplicate PCB terminal "${n11.pcb_port_id}" for "${e54.connectionName}"`);
r10.set(n11.pcb_port_id, n11);
}
if (r10.size === 0)
return e54;
const s10 = [i10.startPcbPortId, i10.endPcbPortId].filter((e58) => e58 !== undefined);
if (s10.length === 0)
return e54;
if (new Set(s10).size !== s10.length || s10.some((e58) => !r10.has(e58)))
throw new Error(`Cannot lock PCB terminals for "${e54.connectionName}": route endpoint IDs do not match connection terminal IDs`);
const a10 = i10.startPcbPortId ? r10.get(i10.startPcbPortId) : undefined, c10 = i10.endPcbPortId ? r10.get(i10.endPcbPortId) : undefined, l10 = e54.route.map((t12, n11) => {
if (n11 === 0 && a10)
return { ...t12, x: a10.x, y: a10.y, pcb_port_id: a10.pcb_port_id };
if (n11 === e54.route.length - 1 && c10)
return { ...t12, x: c10.x, y: c10.y, pcb_port_id: c10.pcb_port_id };
const o11 = { ...t12 };
return delete o11.pcb_port_id, o11;
});
return { ...e54, route: l10 };
});
};
var b7 = ({ originalSrj: e50, newlyRoutedTraces: t10, currentPreloadedTraces: n10, expandedConnectionNames: o10, resolveConnectedTraceAliases: i10 = false }) => {
const r10 = n10 ?? e50.traces ?? [], s10 = i10 ? x7({ originalSrj: e50, newlyRoutedTraces: t10, preloadedTraces: r10, expandedConnectionNames: o10 }) : new Set(r10.filter((e54) => o10.includes(e54.connection_name))), a10 = r10.filter((e54) => !s10.has(e54)), c10 = new Set([...t10.map((e54) => e54.pcb_trace_id), ...a10.map((e54) => e54.pcb_trace_id)]), l10 = r10.filter((e54) => s10.has(e54)).map((e54) => {
const t11 = e54.pcb_trace_id;
let n11 = t11, o11 = 2;
for (;c10.has(n11); )
n11 = `${t11}_power_expansion_${o11++}`;
return c10.add(n11), { ...e54, pcb_trace_id: n11, __replaces_pcb_trace_id: e54.__replaces_pcb_trace_id ?? e54.pcb_trace_id };
});
return { ...e50, traces: [...t10, ...l10], fixedTraces: a10 };
};
var x7 = ({ originalSrj: e50, newlyRoutedTraces: t10, preloadedTraces: n10, expandedConnectionNames: o10 }) => {
const i10 = new Set(n10.map((e54) => e54.pcb_trace_id)), r10 = new Set([...i10, ...t10.map((e54) => e54.pcb_trace_id)]), s10 = t10.map((e54, t11) => {
if (!i10.has(e54.pcb_trace_id))
return e54;
const n11 = `__pipeline7_new_trace_${t11}_${e54.pcb_trace_id}`;
let o11 = n11, s11 = 2;
for (;r10.has(o11); )
o11 = `${n11}_${s11++}`;
return r10.add(o11), { ...e54, pcb_trace_id: o11 };
}), a10 = new V6({ ...e50, traces: [...s10, ...n10] }), c10 = new Set(a10.canonicalize([...o10]));
return new Set(n10.filter((e54) => a10.canonicalize([e54.connection_name]).some((e58) => c10.has(e58))));
};
var R7 = class extends ai {
bestRoutes;
bestCost;
completedPasses = 0;
extraPasses;
simplifier;
params;
constructor(e50) {
super(), this.params = e50, this.bestRoutes = structuredClone([...e50.config.hdRoutes]), this.bestCost = e50.getCost(this.bestRoutes), this.extraPasses = Math.max(0, Math.ceil(2 * (e50.effort - 1))), this.MAX_ITERATIONS = 1e8 * Math.max(1, this.extraPasses), this.extraPasses !== 0 ? (this.simplifier = new ZB({ ...e50.config, hdRoutes: structuredClone(this.bestRoutes) }), this.simplifier.simplificationPipelineLoops = 2, this.simplifier.MAX_SIMPLIFICATION_PIPELINE_LOOPS = 2 + this.extraPasses, this.simplifier.MAX_ITERATIONS = this.MAX_ITERATIONS) : this.solved = true;
}
_step() {
const e50 = this.simplifier;
if (!e50)
throw new Error("Cleanup has no active simplifier");
if (e50.step(), e50.failed)
return this.failed = true, void (this.error = e50.error);
const t10 = e50.simplificationPipelineLoops - 2;
if (t10 > this.completedPasses) {
this.completedPasses = t10;
const n10 = e50.simplifiedHdRoutes, o10 = this.params.getCost(n10);
(o10.vias < this.bestCost.vias || o10.vias === this.bestCost.vias && o10.points < this.bestCost.points) && this.params.isValid(n10) && (this.bestRoutes = structuredClone(n10), this.bestCost = o10);
}
this.solved = e50.solved;
}
getOutput() {
if (!this.solved)
throw new Error("Cleanup is not complete");
return this.bestRoutes;
}
};
var E7 = { traceClearance: 0.1, viaClearance: 0.1 };
var A7 = (e50, t10) => {
const n10 = new Set(t10.flatMap((e54) => e54.__replaces_pcb_trace_id ? [e54.__replaces_pcb_trace_id] : []));
return [...e50.filter((e54) => !n10.has(e54.pcb_trace_id)), ...t10];
};
var O7 = ({ inputSrj: e50, srjWithPointPairs: t10, routedTraces: n10, drcOptions: o10, includeBoardClearance: i10 = false, connectivityMaps: r10 }) => {
const s10 = e50.traces ?? [], a10 = NL(t10, A7(s10, n10), { minTraceWidth: e50.minTraceWidth, minViaDiameter: e50.minViaDiameter, originalSrj: e50, includeOriginalConnections: true, connectivityMaps: r10 });
return i10 && a10.push(wL({ ...e50, minBoardEdgeClearance: e50.minBoardEdgeClearance ?? 0 })), { circuitJson: a10, ...RM(a10, { ...E7, holeClearance: e50.minTraceToHoleEdgeClearance, ...o10 }) };
};
var k7 = (e50, t10) => {
const n10 = e50.filter((e54) => (e54.rootConnectionName ?? e54.connectionName) === t10);
if (n10.length !== 0)
return n10.reduce((e54, t11) => e54 + t11.route.slice(1).reduce((e58, n11, o10) => {
const i10 = t11.route[o10];
return e58 + Math.hypot(n11.x - i10.x, n11.y - i10.y);
}, 0), 0);
};
var D7 = (e50, t10) => {
const n10 = new Set(e50.flatMap((e54) => e54.maxLengthSkew === undefined ? [] : e54.connectionNames));
return t10.flatMap((e54) => {
if (!n10.has(e54.name))
return [];
const t11 = e54.pointsToConnect[0], o10 = e54.pointsToConnect.at(-1);
if (!t11 || !o10 || t11 === o10)
throw new Error(`Length matching: bus connection "${e54.name}" needs at least two points`);
return [{ ...e54, pointsToConnect: [t11, o10] }];
});
};
var L7 = class extends ai {
constructor(e50) {
super(), this.params = e50, this.differentialPairSolver = new T4({ hdRoutes: e50.hdRoutes, differentialPairs: e50.differentialPairs, traces: e50.traces, obstacles: e50.obstacles, bounds: e50.bounds, layerCount: e50.layerCount, minTraceToPadEdgeClearance: e50.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 = true, this.error = this.differentialPairSolver.error));
if (!this.busLengthMatchingSolver) {
const n10 = this.differentialPairSolver.getOutput().hdRoutes, o10 = (e50 = this.params.buses, t10 = n10, e50.flatMap((e54) => {
const n11 = e54.maxLengthSkew;
if (n11 === undefined || e54.connectionNames.length < 2)
return [];
const o11 = e54.connectionNames.map((n12) => {
const o12 = k7(t10, n12);
if (o12 === undefined)
throw new Error(`Length matching: bus "${e54.busId}" has no routed geometry for connection "${n12}"`);
return { connectionName: n12, length: o12 };
}), i10 = o11.reduce((e58, t11) => t11.length > e58.length ? t11 : e58);
return o11.flatMap((e58) => e58.connectionName === i10.connectionName ? [] : [{ connectionNames: [e58.connectionName, i10.connectionName], lengthTolerance: n11 }]);
}));
return o10.length === 0 ? (this.outputHdRoutes = n10, void (this.solved = true)) : void (this.busLengthMatchingSolver = new Q3({ hdRoutes: n10, originalConnections: D7(this.params.buses, this.params.connections), differentialPairs: o10, traces: this.params.traces, obstacles: this.params.obstacles, bounds: this.params.bounds, layerCount: this.params.layerCount, obstacleMargin: this.params.obstacleMargin }));
}
var e50, t10;
if (this.busLengthMatchingSolver.step(), this.busLengthMatchingSolver.failed)
return this.failed = true, void (this.error = this.busLengthMatchingSolver.error);
this.busLengthMatchingSolver.solved && (this.outputHdRoutes = this.busLengthMatchingSolver.getOutput().matchedHdRoutes, ((e54, t11) => {
for (const n10 of e54) {
if (n10.maxLengthSkew === undefined || n10.connectionNames.length < 2)
continue;
const e58 = n10.connectionNames.map((e59) => {
const o11 = k7(t11, e59);
if (o11 === undefined)
throw new Error(`Length matching: bus "${n10.busId}" lost routed geometry for connection "${e59}"`);
return o11;
}), o10 = Math.max(...e58) - Math.min(...e58);
if (o10 > n10.maxLengthSkew + 0.000001)
throw new Error(`Length matching: bus "${n10.busId}" routed length skew ${o10.toFixed(4)}mm exceeds ${n10.maxLengthSkew.toFixed(4)}mm`);
}
})(this.params.buses, this.outputHdRoutes), this.solved = true);
}
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();
}
};
var z7 = 0.000000001;
var B7 = (e50, t10) => Math.abs(e50.x - t10.x) <= z7 && Math.abs(e50.y - t10.y) <= z7 && e50.z === t10.z;
var F7 = (e50, t10) => {
if (e50.length === 0)
return void e50.push(...t10.route);
const n10 = e50.at(-1);
if (t10.route[0] && B7(n10, t10.route[0]))
e50.push(...t10.route.slice(1));
else {
if (!t10.route.at(-1) || !B7(n10, t10.route.at(-1)))
throw new Error(`Pipeline9 could not reconnect mutated preloaded segment "${t10.connectionName}"`);
e50.push(...t10.route.slice(0, -1).reverse());
}
};
var j7 = (e50, t10) => {
const n10 = e50.preloadedRoutePositionStart ?? e50.preloadedRouteIndex, o10 = t10.preloadedRoutePositionStart ?? t10.preloadedRouteIndex, i10 = e50.preloadedRoutePositionEnd ?? n10, r10 = t10.preloadedRoutePositionEnd ?? o10;
return n10 - o10 || i10 - r10 || e50.preloadedRouteIndex - t10.preloadedRouteIndex || e50.connectionName.localeCompare(t10.connectionName);
};
var $7 = (e50) => {
const t10 = e50.route.flatMap((e54) => e54.route_type === "wire" || e54.route_type === "through_obstacle" ? [e54.width] : []);
return t10.length > 0 ? Math.max(...t10) : undefined;
};
var Y7 = ({ trace: e50, updatedTraceRoutes: t10, layerCount: n10, defaultViaHoleDiameter: o10, obstacles: i10, connMap: r10 }) => {
if (t10.length === 0)
throw new Error(`Pipeline9 lost every fixed route for mutated trace "${e50.pcb_trace_id}"`);
const s10 = [];
let a10, c10 = 0, l10 = 0;
for (const e54 of [...t10].sort(j7))
F7(s10, e54), c10 = Math.max(c10, e54.traceThickness), l10 = Math.max(l10, e54.viaDiameter), a10 ??= e54.rootConnectionName;
const h10 = { connectionName: e50.connection_name, rootConnectionName: a10, traceThickness: $7(e50) ?? c10, viaDiameter: l10, route: s10, vias: s10.slice(0, -1).flatMap((e54, t11) => {
const n11 = s10[t11 + 1];
return e54.z !== n11.z && Math.abs(e54.x - n11.x) <= z7 && Math.abs(e54.y - n11.y) <= z7 ? [{ x: n11.x, y: n11.y }] : [];
}) };
return Ro(h10, n10, { defaultViaHoleDiameter: o10, obstacles: i10, connMap: r10 });
};
var X7 = (e50, t10) => e50.filter((e54) => {
if (e54.isThroughObstacle === true)
return false;
const { preloadedRoutePositionStart: n10, preloadedRoutePositionEnd: o10 } = e54;
if (n10 === undefined || o10 === undefined)
throw new Error(`Pipeline9 fixed route "${e54.connectionName}" is missing route-position metadata`);
const i10 = Math.min(n10, o10), r10 = Math.max(n10, o10);
return i10 >= t10.routePositionStart - z7 && r10 <= t10.routePositionEnd + z7;
});
var W7 = ({ trace: e50, originalTraceRoutes: t10, updatedTraceRoutes: n10, layerCount: o10, defaultViaHoleDiameter: i10, obstacles: r10, connMap: s10 }) => {
if (n10.length === 0)
throw new Error(`Pipeline9 lost every fixed route for mutated trace "${e50.pcb_trace_id}"`);
const a10 = ((e54) => {
const t11 = [];
let n11 = 0;
for (let o11 = 0;o11 < e54.route.length; o11++)
e54.route[o11]?.route_type === "through_obstacle" && (n11 < o11 && t11.push({ routePositionStart: n11, routePositionEnd: o11 - 1 }), n11 = o11 + 1);
return n11 < e54.route.length && t11.push({ routePositionStart: n11, routePositionEnd: e54.route.length - 1 }), t11;
})(e50), c10 = n10.filter((e54) => e54.isThroughObstacle !== true);
for (const e54 of c10) {
if (a10.filter((t11) => X7([e54], t11).includes(e54)).length !== 1)
throw new Error(`Pipeline9 fixed route "${e54.connectionName}" crosses an immutable through-obstacle primitive`);
}
const l10 = [];
let h10 = 0;
for (const c11 of a10) {
l10.push(...e50.route.slice(h10, c11.routePositionStart));
const a11 = X7(t10, c11), d10 = X7(n10, c11);
if (a11.length > 0 && d10.length === 0)
throw new Error(`Pipeline9 lost every fixed route for an ordinary section of mutated trace "${e50.pcb_trace_id}"`);
l10.push(...d10.length > 0 ? Y7({ trace: e50, updatedTraceRoutes: d10, layerCount: o10, defaultViaHoleDiameter: i10, obstacles: r10, connMap: s10 }) : e50.route.slice(c11.routePositionStart, c11.routePositionEnd + 1)), h10 = c11.routePositionEnd + 1;
}
return l10.push(...e50.route.slice(h10)), l10;
};
var V7 = (e50, t10) => {
const n10 = new Set(t10.map((e54) => e54.pcb_trace_id));
return e50.map((e54) => {
if (!n10.has(e54.pcb_trace_id))
return n10.add(e54.pcb_trace_id), e54;
const t11 = `${e54.pcb_trace_id}_routed`;
let o10 = t11, i10 = 2;
for (;n10.has(o10); )
o10 = `${t11}_${i10}`, i10 += 1;
return n10.add(o10), { ...e54, pcb_trace_id: o10 };
});
};
var H7 = (e50, t10, n10) => {
const o10 = (e54) => `${e54.x}:${e54.y}`, i10 = new Map;
for (const e54 of t10) {
const t11 = o10(e54.center), n11 = i10.get(t11) ?? [];
n11.push(e54), i10.set(t11, n11);
}
const r10 = new Map;
for (const t11 of e50)
for (const e54 of t11.pointsToConnect) {
if (!e54.pcb_port_id)
continue;
const t12 = r10.get(e54.pcb_port_id) ?? new Set, s10 = Co(e54);
for (const e58 of s10)
t12.add(go(e58, n10));
for (const r11 of i10.get(o10(e54)) ?? [])
if (!(r11.layers.length <= 1) && r11.connectedTo.includes(e54.pcb_port_id))
for (const e58 of r11.layers)
t12.add(go(e58, n10));
r10.set(e54.pcb_port_id, t12);
}
return r10;
};
var G7 = (e50, t10) => new Map(e50.flatMap((e54) => {
const n10 = t10.getNetConnectedToId(e54.connectionName) ?? (e54.rootConnectionName ? t10.getNetConnectedToId(e54.rootConnectionName) ?? (t10.netMap[e54.rootConnectionName] ? e54.rootConnectionName : undefined) : undefined);
return n10 ? [[e54.connectionName, n10]] : [];
}));
var U7 = 0.000000001;
var Z7 = 0.000001;
var q7 = (e50, t10) => Math.abs(e50.x - t10.x) <= Z7 && Math.abs(e50.y - t10.y) <= Z7 && e50.z === t10.z;
var J7 = (e50) => new Map(e50.map((e54, t10) => [e54.pcb_trace_id, t10]));
var Q7 = (e50, t10) => {
const n10 = e50[0], o10 = e50.at(-1);
if (!n10 || !o10)
throw new Error("Pipeline9 cannot split an empty preloaded route");
if (n10.z !== o10.z)
throw new Error("Pipeline9 cannot partially split a preloaded layer transition");
return { ...n10, x: n10.x + (o10.x - n10.x) * t10, y: n10.y + (o10.y - n10.y) * t10 };
};
var K7 = ({ traces: e50, fixedHdRoutes: t10, sections: n10 }) => {
const o10 = (({ traces: e54, sections: t11 }) => {
const n11 = J7(e54), o11 = new Map;
for (const e58 of t11) {
const t12 = n11.get(e58.traceId);
if (t12 === undefined)
throw new Error(`Pipeline9 hypergraph changed missing preloaded trace "${e58.traceId}"`);
const i10 = o11.get(t12) ?? [];
i10.push({ start: Math.min(e58.startRoutePosition, e58.endRoutePosition), end: Math.max(e58.startRoutePosition, e58.endRoutePosition) }), o11.set(t12, i10);
}
for (const e58 of o11.values())
e58.sort((e59, t12) => e59.start - t12.start || e59.end - t12.end);
return o11;
})({ traces: e50, sections: n10 });
return t10.flatMap((e54) => {
const t11 = o10.get(e54.preloadedTraceIndex);
if (!t11?.length)
return [e54];
const { preloadedRoutePositionStart: n11, preloadedRoutePositionEnd: i10 } = e54;
if (n11 === undefined || i10 === undefined)
throw new Error(`Pipeline9 fixed route "${e54.connectionName}" is missing route-position metadata`);
if (Math.abs(i10 - n11) <= U7)
return t11.some((e58) => e58.start - U7 <= n11 && n11 <= e58.end + U7) ? [] : [e54];
let r10 = [{ start: n11, end: i10 }];
for (const e58 of t11)
r10 = r10.flatMap((t12) => {
if (e58.end <= t12.start + U7 || e58.start >= t12.end - U7)
return [t12];
const n12 = [];
return e58.start > t12.start + U7 && n12.push({ start: t12.start, end: Math.min(e58.start, t12.end) }), e58.end < t12.end - U7 && n12.push({ start: Math.max(e58.end, t12.start), end: t12.end }), n12;
});
return r10.map((t12, o11) => {
const r11 = (t12.start - n11) / (i10 - n11), s10 = (t12.end - n11) / (i10 - n11);
return { ...e54, connectionName: `${e54.connectionName}_hypergraph_fixed_${o11}`, preloadedRoutePositionStart: t12.start, preloadedRoutePositionEnd: t12.end, route: [Q7(e54.route, r11), Q7(e54.route, s10)], vias: [] };
});
});
};
var eee = ({ traces: e50, sections: t10, stitchedHdRoutes: n10, layerCount: o10 }) => {
const i10 = J7(e50);
return t10.map((e54, r10) => {
const s10 = i10.get(e54.traceId);
if (s10 === undefined)
throw new Error(`Pipeline9 cannot materialize missing preloaded trace "${e54.traceId}"`);
const [a10, c10] = ((e58, t11) => {
const n11 = e58.connection.pointsToConnect.map((e59) => ({ x: e59.x, y: e59.y, z: go(So(e59), t11) }));
if (!n11[0] || !n11[1])
throw new Error(`Pipeline9 changed section "${e58.connectionName}" is missing an endpoint`);
return [n11[0], n11[1]];
})(e54, o10), l10 = n10.flatMap((t11) => {
if (t11.connectionName !== e54.connectionName)
return [];
const n11 = (({ route: e58, sectionStart: t12, sectionEnd: n12 }) => {
const o11 = e58.route[0], i11 = e58.route.at(-1);
if (!o11 || !i11)
return null;
const r11 = o11.z === t12.z && i11.z === n12.z, s11 = o11.z === n12.z && i11.z === t12.z, a11 = r11 ? vt(o11, t12) + vt(i11, n12) : Number.POSITIVE_INFINITY, c11 = s11 ? vt(o11, n12) + vt(i11, t12) : Number.POSITIVE_INFINITY;
return Number.isFinite(a11) || Number.isFinite(c11) ? a11 <= c11 ? { score: a11, reverse: false } : { score: c11, reverse: true } : null;
})({ route: t11, sectionStart: a10, sectionEnd: c10 });
return n11 ? [{ route: t11, ...n11 }] : [];
});
l10.sort((e58, t11) => e58.score - t11.score);
const h10 = l10[0], d10 = l10[1];
if (!h10 || d10 && Math.abs(d10.score - h10.score) <= Z7)
throw new Error(`Pipeline9 expected one nearest stitched route for changed preloaded section "${e54.connectionName}", got ${l10.length}`);
const u10 = (({ route: e58, reverse: t11, sectionStart: n11, sectionEnd: o11 }) => {
const i11 = t11 ? ((e59) => {
const t12 = [...e59].reverse().map((e60) => {
const { toNextSegmentType: t13, ...n12 } = e60;
return n12;
});
for (let n12 = 0;n12 < e59.length - 1; n12++) {
const o12 = e59[n12]?.toNextSegmentType;
o12 && (t12[e59.length - n12 - 2] = { ...t12[e59.length - n12 - 2], toNextSegmentType: o12 });
}
return t12;
})(e58.route) : [...e58.route];
if (!i11[0] || !i11.at(-1))
throw new Error(`Pipeline9 cannot materialize empty route "${e58.connectionName}"`);
return q7(i11[0], n11) || i11.unshift(n11), q7(i11.at(-1), o11) || i11.push(o11), { ...e58, route: i11 };
})({ route: h10.route, reverse: h10.reverse, sectionStart: a10, sectionEnd: c10 });
return { ...u10, preloadedTraceIndex: s10, preloadedRouteIndex: Number.MAX_SAFE_INTEGER - t10.length + r10, preloadedRoutePositionStart: e54.startRoutePosition, preloadedRoutePositionEnd: e54.endRoutePosition, isThroughObstacle: false };
});
};
var tee = 0.000001;
var nee = ({ hdRoute: e50, start: t10, end: n10 }) => {
if (Math.abs(t10.x - n10.x) <= tee && Math.abs(t10.y - n10.y) <= tee)
return "colocated";
const o10 = e50.vias.some((e54) => Math.abs(e54.x - t10.x) <= tee && Math.abs(e54.y - t10.y) <= tee), i10 = e50.vias.some((e54) => Math.abs(e54.x - n10.x) <= tee && Math.abs(e54.y - n10.y) <= tee);
if (!o10 && !i10)
throw new Error(`Pipeline9 route "${e50.connectionName}" changes layers from z=${t10.z} to z=${n10.z} without an explicit via`);
if (o10 === i10)
throw new Error(`Pipeline9 route "${e50.connectionName}" has an ambiguous layer transition between (${t10.x}, ${t10.y}) and (${n10.x}, ${n10.y})`);
return o10 ? "start" : "end";
};
var oee = (e50) => e50.map((e54) => {
const t10 = [];
for (const n10 of e54.route) {
const o10 = t10.at(-1);
if (!o10 || o10.z === n10.z || o10.toNextSegmentType === "through_obstacle") {
t10.push(n10);
continue;
}
const i10 = nee({ hdRoute: e54, start: o10, end: n10 });
i10 !== "colocated" ? (i10 === "start" ? t10.push({ x: o10.x, y: o10.y, z: n10.z }) : t10.push({ x: n10.x, y: n10.y, z: o10.z }), t10.push(n10)) : t10.push(n10);
}
return { ...e54, route: t10 };
});
var iee = (e50) => oee(e50).map((e54) => ({ ...e54, route: e54.route.flatMap((t10, n10) => {
const o10 = e54.route[n10 - 1];
return !o10 || o10.z === t10.z || o10.toNextSegmentType === "through_obstacle" || o10.x === t10.x && o10.y === t10.y ? [t10] : [{ x: t10.x, y: t10.y, z: o10.z }, t10];
}) }));
var ree = (e50) => {
const t10 = new Map;
for (const n10 of e50)
n10.regionId && t10.set(n10.regionId, (t10.get(n10.regionId) ?? 0) + n10.route.length);
return e50.map((e54) => {
if (!e54.regionId || t10.get(e54.regionId) < 4096)
return e54;
const n10 = [], o10 = [];
for (const [t11, i11] of e54.route.entries()) {
for (;n10.length >= 2; ) {
const t12 = n10[n10.length - 2], r10 = n10[n10.length - 1];
if (t12.z !== r10.z || r10.z !== i11.z || t12.toNextSegmentType || t12.traceThickness !== undefined || Object.keys(r10).some((e58) => e58 !== "x" && e58 !== "y" && e58 !== "z") || e54.vias.some((e58) => Math.hypot(e58.x - r10.x, e58.y - r10.y) < 0.000000001))
break;
const s10 = r10.x - t12.x, a10 = r10.y - t12.y, c10 = i11.x - r10.x, l10 = i11.y - r10.y, h10 = Math.hypot(i11.x - t12.x, i11.y - t12.y);
if (h10 === 0 || s10 * c10 + a10 * l10 < 0 || Math.abs(s10 * l10 - a10 * c10) > 0.000000001 * h10)
break;
n10.pop(), o10.pop();
}
n10.push(i11), o10.push(t11);
}
const i10 = [];
for (let t11 = 0;t11 < n10.length; t11++) {
const r10 = n10[t11];
if (n10[t11 - 1]) {
const n11 = o10[t11 - 1], r11 = o10[t11];
r11 - n11 < 64 && i10.push(...e54.route.slice(n11 + 1, r11));
}
i10.push(r10);
}
return { ...e54, route: i10 };
});
};
var see = 0.000000001;
var aee = (e50) => ({ minX: e50.center.x - e50.width / 2, maxX: e50.center.x + e50.width / 2, minY: e50.center.y - e50.height / 2, maxY: e50.center.y + e50.height / 2 });
var cee = (e50, t10) => e50.x >= t10.minX - see && e50.x <= t10.maxX + see && e50.y >= t10.minY - see && e50.y <= t10.maxY + see;
var lee = (e50, t10, n10) => n10 <= see ? e50 : n10 >= 0.999999999 ? t10 : { x: e50.x + (t10.x - e50.x) * n10, y: e50.y + (t10.y - e50.y) * n10, z: e50.z };
var hee = (e50, t10, n10) => {
const o10 = t10.x - e50.x, i10 = t10.y - e50.y;
if (Math.abs(o10) <= see && Math.abs(i10) <= see)
return cee(e50, n10) && cee(t10, n10) ? { start: e50, end: t10 } : null;
let r10 = 0, s10 = 1;
const a10 = [[-o10, e50.x - n10.minX], [o10, n10.maxX - e50.x], [-i10, e50.y - n10.minY], [i10, n10.maxY - e50.y]];
for (const [e54, t11] of a10) {
if (Math.abs(e54) <= see) {
if (t11 < 0)
return null;
continue;
}
const n11 = t11 / e54;
if (e54 < 0 ? r10 = Math.max(r10, n11) : s10 = Math.min(s10, n11), r10 > s10 + see)
return null;
}
return { start: lee(e50, t10, r10), end: lee(e50, t10, s10) };
};
var dee = (e50) => {
const t10 = e50.sourceRoutes[0], n10 = `pipeline9_fallback:${t10.connectionName}`, o10 = `${n10}:start`, i10 = `${n10}:end`;
return [{ ...e50.start.point, portPointId: o10, nextPortPointId: i10, connectionName: t10.connectionName, rootConnectionName: t10.rootConnectionName }, { ...e50.end.point, portPointId: i10, prevPortPointId: o10, connectionName: t10.connectionName, rootConnectionName: t10.rootConnectionName }];
};
var uee = (e50, t10) => Math.abs(e50.x - t10.x) <= see && Math.abs(e50.y - t10.y) <= see && e50.z === t10.z;
var pee = (e50, t10) => e50.sourceRoute.preloadedTraceIndex === t10.sourceRoute.preloadedTraceIndex && uee(e50.sourceRoute.route.at(-1), t10.sourceRoute.route[0]);
var mee = (e50, t10, n10 = new Set) => {
const o10 = new Map, i10 = [], r10 = new Set(e50.portPoints.map((e54) => e54.z)), s10 = t10.map((t11) => ((e54, t12) => {
const n11 = aee(t12);
let o11, i11;
for (let t13 = 0;t13 < e54.route.length - 1; t13++) {
const r11 = hee(e54.route[t13], e54.route[t13 + 1], n11);
r11 && (o11 ??= { segmentIndex: t13, point: r11.start }, i11 = { segmentIndex: t13, point: r11.end });
}
return o11 && i11 ? { sourceRoute: e54, start: o11, end: i11 } : null;
})(t11, e50)).filter((e54) => e54 !== null), a10 = s10.filter((e54) => e54.sourceRoute.isThroughObstacle !== true && (((e58, t11) => t11.size === 0 || [e58.start.point, ...e58.sourceRoute.route.slice(e58.start.segmentIndex + 1, e58.end.segmentIndex + 1), e58.end.point].some((e59) => t11.has(e59.z)))(e54, r10) || n10.has(e54.sourceRoute.connectionName))).sort((e54, t11) => e54.sourceRoute.preloadedTraceIndex - t11.sourceRoute.preloadedTraceIndex || e54.sourceRoute.preloadedRouteIndex - t11.sourceRoute.preloadedRouteIndex), c10 = new Set(a10.map((e54) => e54.sourceRoute)), l10 = s10.map((e54) => e54.sourceRoute).filter((e54) => !c10.has(e54)), h10 = [];
for (let e54 = 0;e54 < a10.length; e54++) {
const t11 = a10[e54], n11 = a10[e54 - 1], o11 = h10.at(-1);
n11 && o11 && pee(n11, t11) ? (o11.sourceRoutes.push(t11.sourceRoute), o11.end = t11.end) : h10.push({ sourceRoutes: [t11.sourceRoute], start: t11.start, end: t11.end });
}
for (const e54 of h10) {
if (uee(e54.start.point, e54.end.point))
continue;
const t11 = e54.sourceRoutes[0].connectionName;
if (o10.has(t11))
throw new Error(`Pipeline9 regional fallback found duplicate fixed route section identity "${t11}"`);
o10.set(t11, e54), i10.push(dee(e54));
}
return { nodeWithPortPoints: { ...e50, portPoints: [...e50.portPoints, ...i10.flatMap((e54) => e54)], portPointsInPairs: [...e50.portPointsInPairs ?? [], ...i10] }, fixedRouteSectionsByConnectionName: o10, fixedObstacleRoutes: l10 };
};
var gee = (e50) => {
const t10 = [];
for (let n10 = 0;n10 < e50.length - 1; n10++) {
const o10 = e50[n10], i10 = e50[n10 + 1];
o10.z !== i10.z && Math.abs(o10.x - i10.x) <= see && Math.abs(o10.y - i10.y) <= see && t10.push({ x: i10.x, y: i10.y });
}
return t10;
};
var fee = (e50, t10) => _ee({ section: e50, replacement: t10, sourceMutationMasks: new Map, replacementIsMutated: false }).route;
var _ee = ({ section: e50, replacement: t10, sourceMutationMasks: n10, replacementIsMutated: o10 }) => {
const i10 = e50.sourceRoutes[0], r10 = e50.sourceRoutes.at(-1), s10 = ((e54, t11) => {
const n11 = e54.route, o11 = n11[0], i11 = n11.at(-1);
if (!o11 || !i11)
throw new Error(`Pipeline9 regional fallback produced an empty replacement for "${t11.sourceRoutes[0].connectionName}"`);
const r11 = Math.hypot(o11.x - t11.start.point.x, o11.y - t11.start.point.y) + Math.hypot(i11.x - t11.end.point.x, i11.y - t11.end.point.y);
return Math.hypot(i11.x - t11.start.point.x, i11.y - t11.start.point.y) + Math.hypot(o11.x - t11.end.point.x, o11.y - t11.end.point.y) < r11 ? [...n11].reverse() : n11;
})(t10, e50), a10 = [], c10 = [], l10 = (e54, t11) => {
const o11 = n10.get(e54.connectionName);
if (o11 && o11.length !== e54.route.length - 1)
throw new Error(`Pipeline9 fixed route mutation mask for "${e54.connectionName}" has ${o11.length} segments, expected ${e54.route.length - 1}`);
return o11?.[t11] ?? false;
}, h10 = (e54, t11) => {
const n11 = a10.at(-1);
if (n11) {
if (!uee(n11, e54)) {
if (n11.z !== e54.z && (Math.abs(n11.x - e54.x) > see || Math.abs(n11.y - e54.y) > see)) {
const o11 = { ...e54, z: n11.z };
uee(n11, o11) || (a10.push(o11), c10.push(t11));
}
uee(a10.at(-1), e54) || (a10.push(e54), c10.push(t11));
}
} else
a10.push(e54);
};
h10(i10.route[0], false);
for (let t11 = 1;t11 <= e50.start.segmentIndex; t11++)
h10(i10.route[t11], l10(i10, t11 - 1));
h10(e50.start.point, l10(i10, e50.start.segmentIndex));
const d10 = c10.length;
for (const e54 of s10.slice(1, -1))
h10(e54, o10);
h10(e50.end.point, o10);
const u10 = c10.length > d10;
for (let t11 = e50.end.segmentIndex + 1;t11 < r10.route.length; t11++)
h10(r10.route[t11], l10(r10, t11 - 1));
if (c10.length !== a10.length - 1)
throw new Error(`Pipeline9 produced an invalid mutation mask while splicing "${i10.connectionName}"`);
return { route: { ...i10, preloadedRoutePositionStart: i10.preloadedRoutePositionStart, preloadedRoutePositionEnd: r10.preloadedRoutePositionEnd, traceThickness: Math.max(...e50.sourceRoutes.map((e54) => e54.traceThickness)), viaDiameter: Math.max(...e50.sourceRoutes.map((e54) => e54.viaDiameter)), route: a10, vias: gee(a10) }, mutatedSegments: c10, replacementProducedSegment: u10 };
};
var yee = 0.000001;
var bee = (e50, t10) => Math.abs(e50.x - t10.x) <= yee && Math.abs(e50.y - t10.y) <= yee && e50.z === t10.z;
var xee = (e50, t10) => {
for (const n10 of t10)
e50.at(-1) && bee(e50.at(-1), n10) || e50.push(n10);
};
var vee = (e50) => e50.slice(0, -1).flatMap((t10, n10) => {
const o10 = e50[n10 + 1];
return t10.z !== o10.z && Math.abs(t10.x - o10.x) <= yee && Math.abs(t10.y - o10.y) <= yee ? [{ x: o10.x, y: o10.y }] : [];
});
var Iee = (e50) => {
const { preloadedRoutePositionStart: t10, preloadedRoutePositionEnd: n10 } = e50;
if (t10 === undefined || n10 === undefined)
throw new Error(`Pipeline9 fixed route "${e50.connectionName}" is missing route-position metadata`);
return { start: Math.min(t10, n10), end: Math.max(t10, n10) };
};
var See = (e50, t10) => {
const n10 = Iee(e50), o10 = Iee(t10);
return e50.preloadedTraceIndex - t10.preloadedTraceIndex || n10.start - o10.start || n10.end - o10.end || e50.preloadedRouteIndex - t10.preloadedRouteIndex || e50.connectionName.localeCompare(t10.connectionName);
};
var Cee = (e50, t10) => {
const n10 = e50.route.at(-1), o10 = t10.route[0];
return Boolean(n10 && o10 && e50.preloadedTraceIndex === t10.preloadedTraceIndex && bee(n10, o10));
};
var Pee = (e50, t10) => {
const n10 = e50.preloadedRoutePositionStart ?? e50.preloadedRouteIndex;
return n10 + ((e50.preloadedRoutePositionEnd ?? e50.preloadedRouteIndex) - n10) * t10 / (e50.route.length - 1);
};
var Mee = (e50, t10) => e50.route[t10].z !== e50.route[t10 + 1].z;
var wee = ({ updatedFixedRoutes: e50, regionalMutationMasks: t10 }) => {
const n10 = [], o10 = (({ updatedFixedRoutes: e54, regionalMutationMasks: t11 }) => {
const n11 = new Map;
for (const o12 of e54) {
if (o12.route.length === 0)
throw new Error(`Pipeline9 cannot normalize empty fixed route "${o12.connectionName}"`);
const e58 = o12.route.length - 1;
if (n11.has(o12.connectionName))
throw new Error(`Pipeline9 cannot normalize duplicate fixed route "${o12.connectionName}"`);
const i11 = t11.get(o12.connectionName);
if (i11 && i11.length !== e58)
throw new Error(`Pipeline9 fixed route mutation mask for "${o12.connectionName}" has ${i11.length} segments, expected ${e58}`);
const r11 = o12.isThroughObstacle !== true && (o12.jumpers?.length ?? 0) === 0;
n11.set(o12.connectionName, Array.from({ length: e58 }, (e59, t12) => r11 && (i11?.[t12] ?? false)));
}
let o11 = [];
const i10 = () => {
for (;o11[0] && Mee(o11[0].route, o11[0].segmentIndex); ) {
const e58 = o11.shift();
n11.get(e58.route.connectionName)[e58.segmentIndex] = false;
}
for (;o11.at(-1) && Mee(o11.at(-1).route, o11.at(-1).segmentIndex); ) {
const e58 = o11.pop();
n11.get(e58.route.connectionName)[e58.segmentIndex] = false;
}
o11 = [];
};
let r10;
for (const t12 of [...e54].sort(See)) {
r10 && !Cee(r10, t12) && i10();
const e58 = n11.get(t12.connectionName);
if (e58.length !== 0) {
for (let n12 = 0;n12 < e58.length; n12++)
e58[n12] ? o11.push({ route: t12, segmentIndex: n12 }) : i10();
r10 = t12;
} else
i10(), r10 = t12;
}
return i10(), n11;
})({ updatedFixedRoutes: e50, regionalMutationMasks: t10 });
for (const t11 of e50) {
const e54 = t11.route.length - 1, i10 = o10.get(t11.connectionName);
if (e54 === 0) {
n10.push({ route: t11, mutated: false });
continue;
}
const r10 = [];
for (let t12 = 0;t12 < e54; t12++) {
const e58 = i10[t12], n11 = r10.at(-1);
n11?.mutated === e58 ? n11.end = t12 + 1 : r10.push({ start: t12, end: t12 + 1, mutated: e58 });
}
for (const [e58, o11] of r10.entries()) {
const i11 = t11.route.slice(o11.start, o11.end + 1), s10 = { ...t11, connectionName: r10.length === 1 ? t11.connectionName : `${t11.connectionName}_mutation_fragment_${e58}`, preloadedRouteIndex: t11.preloadedRouteIndex + e58 / (r10.length + 1), preloadedRoutePositionStart: Pee(t11, o11.start), preloadedRoutePositionEnd: Pee(t11, o11.end), route: i11, vias: vee(i11) };
n10.push({ route: s10, mutated: o11.mutated });
}
}
return n10;
};
var Nee = ({ updatedFixedRoutes: e50, regionalMutationMasks: t10 }) => {
const n10 = wee({ updatedFixedRoutes: e50, regionalMutationMasks: t10 }), o10 = n10.map(({ route: e54 }) => e54), i10 = ((e54) => {
const t11 = [];
let n11;
for (const o11 of [...e54].sort((e58, t12) => See(e58.route, t12.route))) {
const e58 = o11.route;
if (!o11.mutated) {
n11 = undefined;
continue;
}
const i11 = e58.route[0], r11 = e58.route.at(-1);
if (!i11 || !r11 || e58.route.length < 2)
throw new Error(`Pipeline9 cannot simplify empty fixed route "${e58.connectionName}"`);
const s11 = n11?.sourceRoutes.at(-1);
n11 && s11 && Cee(s11, e58) ? (n11.sourceRoutes.push(e58), n11.end = { segmentIndex: e58.route.length - 2, point: r11 }) : (n11 = { sourceRoutes: [e58], start: { segmentIndex: 0, point: i11 }, end: { segmentIndex: e58.route.length - 2, point: r11 } }, t11.push(n11));
}
return t11;
})(n10), r10 = i10.map((e54, t11) => {
const n11 = ((e58, t12) => {
const n12 = e58.sourceRoutes[0], o11 = e58.sourceRoutes.at(-1);
if (!n12 || !o11)
throw new Error("Pipeline9 cannot simplify an empty mutation section");
const i11 = [e58.start.point];
for (const [t13, n13] of e58.sourceRoutes.entries()) {
const o12 = t13 === 0, r11 = t13 === e58.sourceRoutes.length - 1, s11 = o12 ? e58.start.segmentIndex + 1 : 0, a10 = r11 ? e58.end.segmentIndex + 1 : n13.route.length;
xee(i11, n13.route.slice(s11, a10));
}
if (xee(i11, [e58.end.point]), i11.length < 2)
throw new Error(`Pipeline9 mutation section for "${n12.connectionName}" has no routable span`);
return { connectionName: `pipeline9_mutated_preload_${n12.preloadedTraceIndex}_${t12}`, rootConnectionName: n12.rootConnectionName, traceThickness: Math.max(...e58.sourceRoutes.map((e59) => e59.traceThickness)), viaDiameter: Math.max(...e58.sourceRoutes.map((e59) => e59.viaDiameter)), route: i11, vias: vee(i11) };
})(e54, t11);
return { connectionName: n11.connectionName, section: e54, hdRoute: n11 };
}), s10 = new Set(r10.flatMap(({ section: e54 }) => e54.sourceRoutes.map((e58) => e58.connectionName)));
return { sections: r10, immutableHdRoutes: o10.filter((e54) => !s10.has(e54.connectionName)), normalizedFixedRoutes: o10 };
};
var Tee = 0.000000001;
var Ree = (e50, t10, n10, o10, i10) => {
const r10 = i10.getNetConnectedToId(e50.connection_name) ?? e50.connection_name, s10 = [], a10 = (n11, i11, a11 = o10, c10 = [], l10, h10, d10 = false) => {
n11.length < 2 || s10.push({ connectionName: `${e50.connection_name}_fixed_${t10}_${s10.length}`, rootConnectionName: r10, preloadedTraceIndex: t10, preloadedRouteIndex: s10.length, preloadedRoutePositionStart: l10, preloadedRoutePositionEnd: h10, isThroughObstacle: d10, traceThickness: Math.max(Tee, i11), viaDiameter: Math.max(Tee, a11), route: n11, vias: c10 });
};
for (let t11 = 0;t11 < e50.route.length; t11++) {
const i11 = e50.route[t11];
if (i11.route_type === "via") {
a10([{ x: i11.x, y: i11.y, z: go(i11.from_layer, n10) }, { x: i11.x, y: i11.y, z: go(i11.to_layer, n10) }], Tee, i11.via_diameter ?? o10, [{ x: i11.x, y: i11.y }], t11, t11);
continue;
}
if (i11.route_type === "through_obstacle") {
const e54 = go(i11.from_layer, n10), r12 = go(i11.to_layer, n10);
for (let n11 = Math.min(e54, r12);n11 <= Math.max(e54, r12); n11++)
a10([{ ...i11.start, z: n11 }, { ...i11.end, z: n11 }], i11.width, o10, [], t11, t11 + 1, true);
continue;
}
const r11 = e50.route[t11 + 1];
i11.route_type === "wire" && r11?.route_type === "wire" && i11.layer === r11.layer && a10([{ x: i11.x, y: i11.y, z: go(i11.layer, n10) }, { x: r11.x, y: r11.y, z: go(r11.layer, n10) }], Math.max(i11.width, r11.width), o10, [], t11, t11 + 1);
}
return s10;
};
function Eee(e50, t10) {
return { x: e50.a * t10.x + e50.b * t10.y + e50.c, y: e50.d * t10.x + e50.e * t10.y + e50.f };
}
var Aee = { highResolutionCellSize: 0.1, highResolutionCellThickness: 8, lowResolutionCellSize: 0.4, traceMargin: 0.15, traceThickness: 0.1, viaDiameter: 0.3, viaMinDistFromBorder: 0.15 };
var Oee = { ...Aee };
var kee = (e50, t10, n10) => {
const [o10, i10] = e50;
if (o10 === i10)
return;
const r10 = ((e54, t11) => {
const n11 = e54.portPointId ?? `${e54.connectionName}:${e54.x}:${e54.y}:${e54.z}`, o11 = t11.portPointId ?? `${t11.connectionName}:${t11.x}:${t11.y}:${t11.z}`;
return n11 < o11 ? `${n11}|${o11}` : `${o11}|${n11}`;
})(o10, i10);
t10.has(r10) || (t10.add(r10), n10.push(e50));
};
var Dee = (e50, t10, n10) => {
for (let o10 = 0;o10 < e50.length - 1; o10++)
kee([e50[o10], e50[o10 + 1]], t10, n10);
};
var Lee = (e50) => {
const t10 = [], n10 = new Set, o10 = ((e54) => {
const t11 = new Map;
for (const n11 of e54)
n11.portPointId && t11.set(n11.portPointId, n11);
return t11;
})(e50);
for (const i11 of e50) {
if (i11.prevPortPointId) {
const e54 = o10.get(i11.prevPortPointId);
e54 && e54.connectionName === i11.connectionName && kee([e54, i11], n10, t10);
}
if (i11.nextPortPointId) {
const e54 = o10.get(i11.nextPortPointId);
e54 && e54.connectionName === i11.connectionName && kee([i11, e54], n10, t10);
}
}
if (t10.length === 0)
return Dee(e50, n10, t10), t10;
const i10 = ((e54) => {
const t11 = new Set;
for (const [n11, o11] of e54)
n11.portPointId && t11.add(n11.portPointId), o11.portPointId && t11.add(o11.portPointId);
return t11;
})(t10), r10 = e50.filter((e54) => !e54.portPointId || !i10.has(e54.portPointId));
return Dee(r10, n10, t10), t10;
};
function zee(e50, t10, n10) {
return Math.max(t10, Math.min(n10, e50));
}
var Bee = ["left", "top", "right", "bottom", "middle"];
var Fee = class {
f = new Float64Array(1024);
seq = new Uint32Array(1024);
id = new Int32Array(1024);
n = 0;
push(e50, t10, n10) {
this.ensureCapacity(this.n + 1);
let o10 = this.n++;
for (this.f[o10] = e50, this.seq[o10] = t10, this.id[o10] = n10;o10 > 0; ) {
const e54 = o10 - 1 >> 1;
if (this.less(e54, o10))
break;
this.swap(o10, e54), o10 = e54;
}
}
pop() {
const e50 = 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)), e50;
}
get size() {
return this.n;
}
clear() {
this.n = 0;
}
ensureCapacity(e50) {
if (e50 <= this.f.length)
return;
let t10 = this.f.length;
for (;t10 < e50; )
t10 *= 2;
const n10 = new Float64Array(t10);
n10.set(this.f), this.f = n10;
const o10 = new Uint32Array(t10);
o10.set(this.seq), this.seq = o10;
const i10 = new Int32Array(t10);
i10.set(this.id), this.id = i10;
}
siftDown(e50) {
for (;; ) {
const t10 = 2 * e50 + 1, n10 = t10 + 1;
if (t10 >= this.n)
return;
let o10 = t10;
if (n10 < this.n && !this.less(t10, n10) && (o10 = n10), this.less(e50, o10))
return;
this.swap(e50, o10), e50 = o10;
}
}
less(e50, t10) {
const n10 = this.f[e50], o10 = this.f[t10];
return n10 !== o10 ? n10 < o10 : this.seq[e50] < this.seq[t10];
}
swap(e50, t10) {
const n10 = this.f[e50];
this.f[e50] = this.f[t10], this.f[t10] = n10;
const o10 = this.seq[e50];
this.seq[e50] = this.seq[t10], this.seq[t10] = o10;
const i10 = this.id[e50];
this.id[e50] = this.id[t10], this.id[t10] = i10;
}
};
var jee = 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(e50, t10, n10, o10, i10, r10) {
this.ensureCapacity(this.length + 1);
const s10 = this.length++;
return this.z[s10] = e50, this.cellId[s10] = t10, this.g[s10] = n10, this.parent[s10] = o10, this.ripHead[s10] = i10, this.ripCount[s10] = r10, s10;
}
ensureCapacity(e50) {
if (e50 <= this.z.length)
return;
let t10 = this.z.length;
for (;t10 < e50; )
t10 *= 2;
const n10 = new Int32Array(t10);
n10.set(this.z), this.z = n10;
const o10 = new Int32Array(t10);
o10.set(this.cellId), this.cellId = o10;
const i10 = new Float64Array(t10);
i10.set(this.g), this.g = i10;
const r10 = new Int32Array(t10);
r10.set(this.parent), this.parent = r10;
const s10 = new Int32Array(t10);
s10.fill(-1), s10.set(this.ripHead.subarray(0, this.length)), this.ripHead = s10;
const a10 = new Int32Array(t10);
a10.set(this.ripCount.subarray(0, this.length)), this.ripCount = a10;
}
};
var $ee = class {
connId = new Int32Array(1024);
prev = new Int32Array(1024).fill(-1);
length = 0;
clear() {
this.length = 0;
}
append(e50, t10) {
this.ensureCapacity(this.length + 1);
const n10 = this.length++;
return this.connId[n10] = t10, this.prev[n10] = e50, n10;
}
contains(e50, t10) {
for (let n10 = e50;n10 >= 0; n10 = this.prev[n10])
if (this.connId[n10] === t10)
return true;
return false;
}
collect(e50, t10) {
t10.length = 0;
for (let n10 = e50;n10 >= 0; n10 = this.prev[n10])
t10.push(this.connId[n10]);
}
ensureCapacity(e50) {
if (e50 <= this.connId.length)
return;
let t10 = this.connId.length;
for (;t10 < e50; )
t10 *= 2;
const n10 = new Int32Array(t10);
n10.set(this.connId), this.connId = n10;
const o10 = new Int32Array(t10);
o10.fill(-1), o10.set(this.prev.subarray(0, this.length)), this.prev = o10;
}
};
function Yee(e50, t10) {
return t10 ?? e50.replace(/_mst\d+$/, "");
}
function Xee(e50, t10) {
const n10 = e50.x - t10.center.x, o10 = e50.y - t10.center.y, i10 = Math.cos(-t10.rotationRadians), r10 = Math.sin(-t10.rotationRadians);
return { x: n10 * i10 - o10 * r10, y: n10 * r10 + o10 * i10 };
}
function Wee(e50) {
return { minX: -e50.width / 2, minY: -e50.height / 2, maxX: e50.width / 2, maxY: e50.height / 2 };
}
function Vee(e50, t10, n10) {
return Math.max(t10, Math.min(n10, e50));
}
function Hee(e50, t10) {
for (let n10 = 0;n10 < e50.length; n10++)
if (e50[n10] === t10)
return;
e50.push(t10);
}
function Gee(e50, t10) {
for (let n10 = 0;n10 < e50.length; n10++)
if (e50[n10].cellId === t10.cellId)
return;
e50.push(t10);
}
function Uee(e50, t10, n10, o10, i10, r10, s10) {
const a10 = e50 - Vee(e50, o10, r10), c10 = t10 - Vee(t10, i10, s10);
return a10 * a10 + c10 * c10 <= n10 * n10;
}
function Zee(e50) {
const t10 = e50.segmentEnd.x - e50.segmentStart.x, n10 = e50.segmentEnd.y - e50.segmentStart.y, o10 = t10 ** 2 + n10 ** 2;
if (o10 === 0)
return (e50.point.x - e50.segmentStart.x) ** 2 + (e50.point.y - e50.segmentStart.y) ** 2;
const i10 = Vee(((e50.point.x - e50.segmentStart.x) * t10 + (e50.point.y - e50.segmentStart.y) * n10) / o10, 0, 1), r10 = e50.segmentStart.x + i10 * t10, s10 = e50.segmentStart.y + i10 * n10;
return (e50.point.x - r10) ** 2 + (e50.point.y - s10) ** 2;
}
function qee(e50) {
const t10 = Vee(e50.point.x, e50.rect.minX, e50.rect.maxX), n10 = Vee(e50.point.y, e50.rect.minY, e50.rect.maxY), o10 = e50.point.x - t10, i10 = e50.point.y - n10;
return o10 * o10 + i10 * i10;
}
function Jee(e50) {
return (e50.second.x - e50.first.x) * (e50.third.y - e50.first.y) - (e50.second.y - e50.first.y) * (e50.third.x - e50.first.x);
}
function Qee(e50) {
return !(Math.abs(Jee({ first: e50.segmentStart, second: e50.segmentEnd, third: e50.point })) > 0.000000001) && (e50.point.x >= Math.min(e50.segmentStart.x, e50.segmentEnd.x) && e50.point.x <= Math.max(e50.segmentStart.x, e50.segmentEnd.x) && e50.point.y >= Math.min(e50.segmentStart.y, e50.segmentEnd.y) && e50.point.y <= Math.max(e50.segmentStart.y, e50.segmentEnd.y));
}
function Kee(e50) {
const t10 = Jee({ first: e50.firstStart, second: e50.firstEnd, third: e50.secondStart }), n10 = Jee({ first: e50.firstStart, second: e50.firstEnd, third: e50.secondEnd }), o10 = Jee({ first: e50.secondStart, second: e50.secondEnd, third: e50.firstStart }), i10 = Jee({ first: e50.secondStart, second: e50.secondEnd, third: e50.firstEnd });
return t10 * n10 < 0 && o10 * i10 < 0 || (Qee({ point: e50.secondStart, segmentStart: e50.firstStart, segmentEnd: e50.firstEnd }) || Qee({ point: e50.secondEnd, segmentStart: e50.firstStart, segmentEnd: e50.firstEnd }) || Qee({ point: e50.firstStart, segmentStart: e50.secondStart, segmentEnd: e50.secondEnd }) || Qee({ point: e50.firstEnd, segmentStart: e50.secondStart, segmentEnd: e50.secondEnd }));
}
function ete(e50) {
return Kee(e50) ? 0 : Math.min(Zee({ point: e50.firstStart, segmentStart: e50.secondStart, segmentEnd: e50.secondEnd }), Zee({ point: e50.firstEnd, segmentStart: e50.secondStart, segmentEnd: e50.secondEnd }), Zee({ point: e50.secondStart, segmentStart: e50.firstStart, segmentEnd: e50.firstEnd }), Zee({ point: e50.secondEnd, segmentStart: e50.firstStart, segmentEnd: e50.firstEnd }));
}
function tte(e50) {
if (function(e54) {
if (qee({ point: e54.segmentStart, rect: e54.rect }) === 0 || qee({ point: e54.segmentEnd, rect: e54.rect }) === 0)
return true;
const t11 = [{ x: e54.rect.minX, y: e54.rect.minY }, { x: e54.rect.maxX, y: e54.rect.minY }, { x: e54.rect.maxX, y: e54.rect.maxY }, { x: e54.rect.minX, y: e54.rect.maxY }];
for (let n10 = 0;n10 < t11.length; n10++) {
const o10 = (n10 + 1) % t11.length;
if (Kee({ firstStart: e54.segmentStart, firstEnd: e54.segmentEnd, secondStart: t11[n10], secondEnd: t11[o10] }))
return true;
}
return false;
}(e50))
return true;
const t10 = e50.radius ** 2;
if (qee({ point: e50.segmentStart, rect: e50.rect }) <= t10 || qee({ point: e50.segmentEnd, rect: e50.rect }) <= t10)
return true;
return [{ x: e50.rect.minX, y: e50.rect.minY }, { x: e50.rect.maxX, y: e50.rect.minY }, { x: e50.rect.maxX, y: e50.rect.maxY }, { x: e50.rect.minX, y: e50.rect.maxY }].some((n10) => Zee({ point: n10, segmentStart: e50.segmentStart, segmentEnd: e50.segmentEnd }) <= t10);
}
var nte = class extends De {
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 e50 = new Map;
for (let t10 = 0;t10 < this.solvedRoutes.length; t10++) {
const n10 = this.getSolvedRoutesForConn(t10);
n10.length > 0 && e50.set(t10, n10);
}
return e50;
}
get activeConnection() {
if (!this.activeConnSeg)
return null;
const e50 = this.activeConnSeg.startCellId, t10 = this.activeConnSeg.endCellId;
return { connectionName: this.connIdToName[this.activeConnSeg.connId] ?? "", start: { cellId: e50, region: Bee[this.cellRegion[e50]], row: this.cellRow[e50], col: this.cellCol[e50], x: this.cellCenterX[e50], y: this.cellCenterY[e50], z: this.activeConnSeg.startZ }, end: { cellId: t10, region: Bee[this.cellRegion[t10]], row: this.cellRow[t10], col: this.cellCol[t10], x: this.cellCenterX[t10], y: this.cellCenterY[t10], 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((e50) => [e50.name, e50.rows * e50.cols])) : {}, obstacleTraceBlockedCells: this.obstacleTraceBlockedCellCount, obstacleViaBlockedCells: this.obstacleViaBlockedCellCount, obstacleRootCount: this.obstacleRootNames?.length ?? 0, obstacleRectCount: this.obstacleRectPrimitives?.length ?? 0 };
}
constructor(e50) {
super(), this.nodeWithPortPoints = e50.nodeWithPortPoints, this.obstacles = e50.obstacles, this.highResolutionCellSize = e50.highResolutionCellSize ?? 0.1, this.highResolutionCellThickness = Math.max(1, Math.floor(e50.highResolutionCellThickness ?? 8)), this.lowResolutionCellSize = e50.lowResolutionCellSize ?? 0.4, this.viaDiameter = e50.viaDiameter, this.maxCellCount = e50.maxCellCount, this.traceThickness = e50.traceThickness ?? 0.1, this.traceMargin = e50.traceMargin ?? 0.15, this.obstacleClearanceMargin = e50.obstacleClearanceMargin ?? 0, this.viaMinDistFromBorder = e50.viaMinDistFromBorder ?? 0.15, this.showPenaltyMap = e50.showPenaltyMap ?? false, this.showUsedCellMap = e50.showUsedCellMap ?? false, this.effort = e50.effort ?? 1, this.stepMultiplier = Math.max(1, Math.floor(e50.stepMultiplier ?? 1)), this.hyperParameters = { shuffleSeed: 0, ripCost: 8, ripTracePenalty: 0.5, ripViaPenalty: 0.75, viaBaseCost: 0.1, greedyMultiplier: 1.5, sameRootObstacleCostMultiplier: 1, ...e50.hyperParameters }, this.MAX_ITERATIONS = 1e8, this.MAX_RIPS = 200, this.initialPenaltyFn = e50.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: e50 } = this, { width: t10, height: n10, center: o10 } = e50;
if (t10 > 15 || n10 > 15)
return this.error = `HighDensitySolverB01 only supports routing windows up to 15x15mm; received ${t10}x${n10}mm`, void (this.failed = true);
const i10 = this.lowResolutionCellSize / this.highResolutionCellSize, r10 = Math.round(i10);
if (!Number.isFinite(i10) || i10 <= 0 || Math.abs(i10 - r10) > 0.000000001)
return this.error = "lowResolutionCellSize must be a positive integer multiple of highResolutionCellSize", void (this.failed = true);
this.lowScale = Math.max(1, r10), this.availableZ = e50.availableZ ?? [...new Set(e50.portPoints.map((e54) => e54.z))].sort((e54, t11) => e54 - t11), this.layers = this.availableZ.length, this.zToLayer = new Map, this.layerToZ = new Map;
for (let e54 = 0;e54 < this.availableZ.length; e54++) {
const t11 = this.availableZ[e54];
this.zToLayer.set(t11, e54), this.layerToZ.set(e54, t11);
}
this.boundsMinX = o10.x - t10 / 2, this.boundsMaxX = o10.x + t10 / 2, this.boundsMinY = o10.y - n10 / 2, this.boundsMaxY = o10.y + n10 / 2, this.traceKeepoutRadius = this.traceMargin + this.traceThickness / 2, this.viaKeepoutRadius = this.viaDiameter / 2 + this.traceKeepoutRadius, this.buildFiveRegionGrid(t10, n10), this.gridToBoundsTransform = this.computeGridToBoundsTransform();
const s10 = this.layers * this.planeSize;
if (this.maxCellCount !== undefined && s10 > this.maxCellCount)
return this.error = `Cell count ${s10} exceeds maxCellCount ${this.maxCellCount}`, void (this.failed = true);
this.connNameToId = new Map, this.connIdToName = [], this.connIdToRootNet = [], this.overlapFriendlyRootNets = new Set, this.unsolvedSegs = this.buildConnectionSegs(), this.penalty2d = new Float64Array(this.planeSize);
const a10 = t10 > 0 ? 1 / t10 : 0, c10 = n10 > 0 ? 1 / n10 : 0;
for (let e54 = 0;e54 < this.planeSize; e54++) {
let t11 = 0;
this.initialPenaltyFn && (t11 += this.initialPenaltyFn({ x: this.cellCenterX[e54], y: this.cellCenterY[e54], px: (this.cellCenterX[e54] - this.boundsMinX) * a10, py: (this.cellCenterY[e54] - this.boundsMinY) * c10, cellId: e54, region: Bee[this.cellRegion[e54]], row: this.cellRow[e54], col: this.cellCol[e54] })), this.penalty2d[e54] = t11;
}
this.usedCellsFlat = new Int32Array(s10).fill(-1), this.sharedCellsFlat = Array.from({ length: s10 }, () => {}), this.portOwnerFlat = new Int32Array(s10).fill(-1), this.sharedCrossRootPortFlat = new Uint8Array(s10), this.obstacleTraceRootIdsFlat = Array.from({ length: s10 }, () => {}), this.obstacleViaRootIdsByCell = Array.from({ length: this.planeSize }, () => {}), this.obstacleRootNameToId = new Map, this.obstacleRootNames = [], this.obstacleTracePrimitives = [], this.obstacleViaPrimitives = [], this.obstacleRectPrimitives = [];
const l10 = this.rasterizeObstacles();
if (l10)
return this.error = l10, void (this.failed = true);
this.ripStateBuckets = 1;
const h10 = s10;
this.visitedStamp = new Uint32Array(h10), this.bestGStamp = new Uint32Array(h10), this.bestGValue = new Float64Array(h10), this.visitedFlatStamp = new Uint32Array(s10), this.stamp = 0;
const d10 = new Map;
for (const e54 of this.nodeWithPortPoints.portPoints) {
const t11 = this.connNameToId.get(e54.connectionName);
if (t11 === undefined)
continue;
const n11 = this.pointToCell(e54), o11 = n11.z * this.planeSize + n11.cellId, i11 = this.connIdToRootNet[t11], r11 = d10.get(o11);
r11 === undefined ? d10.set(o11, i11) : r11 !== i11 && (this.sharedCrossRootPortFlat[o11] = 1);
const s11 = this.portOwnerFlat[o11];
this.portOwnerFlat[o11] = s11 === -1 || s11 === t11 ? t11 : -2;
}
this.solvedRoutes = [], this.usedIndicesByConn = [], this.ripCount = [], this.consecutiveSkips = 0, this.penaltyCap = 0.5 * this.hyperParameters.ripCost, this.shuffleConnections();
const u10 = function(e54) {
const t11 = e54.planeSize * e54.layers, n11 = e54.connectionCount, o11 = Math.sqrt(n11), i11 = Math.max(1, e54.maxIterations), r11 = zee(Math.round(t11 * (8 + 1.2 * o11)), 150000, 12000000), s11 = zee(Math.round(r11 * e54.effort), 150000, 12000000), a11 = zee(Math.round(0.2 * i11), 150000, 2000000);
return { maxIterationsIters: Math.max(1, Math.min(i11, Math.max(a11, s11))), baseSearchBudgetIters: zee(Math.round(t11 * (10 + 0.8 * o11) * e54.effort), 50000, 4000000) };
}({ planeSize: this.planeSize, layers: this.layers, connectionCount: this.unsolvedSegs.length, effort: this.effort, maxIterations: this.MAX_ITERATIONS });
this.baseSearchBudgetIters = u10.baseSearchBudgetIters, this.MAX_ITERATIONS = u10.maxIterationsIters, this.activeConnSeg = null, this.activeConnId = -1, this.nodePool = new jee, this.heap = new Fee, this.ripChain = new $ee, this.seqCounter = 0;
}
_step() {
for (let e50 = 0;e50 < this.stepMultiplier; e50++) {
if (this.solved || this.failed)
return;
this.stepOnce();
}
}
rasterizeObstacles() {
for (let e50 = 0;e50 < this.obstacles.length; e50++) {
const t10 = this.obstacles[e50];
if (t10.type === "rect") {
const n11 = this.rasterizeRectObstacle(t10, e50);
if (n11)
return n11;
continue;
}
if (t10.traceThickness <= 0 || t10.viaDiameter <= 0 || t10.route.length < 2)
return `Obstacle ${e50} must have positive trace/via sizes and at least two route points`;
const n10 = Yee(t10.connectionName, t10.rootConnectionName), o10 = this.internObstacleRootName(n10);
for (let n11 = 1;n11 < t10.route.length; n11++) {
const i10 = t10.route[n11 - 1], r10 = t10.route[n11];
if (!(Number.isFinite(i10.x) && Number.isFinite(i10.y) && Number.isFinite(i10.z) && Number.isFinite(r10.x) && Number.isFinite(r10.y) && Number.isFinite(r10.z)))
return `Obstacle ${e50} contains non-finite route coordinates`;
if (i10.z === r10.z) {
const n12 = this.zToLayer.get(i10.z);
if (n12 === undefined)
return `Obstacle ${e50} uses unavailable layer z=${i10.z}`;
this.rasterizeObstacleTraceSegment({ segmentStart: i10, segmentEnd: r10, layer: n12, obstacleRootId: o10, obstacleTraceThickness: t10.traceThickness });
} else if (!t10.vias.some((e54) => e54.x === r10.x && e54.y === r10.y)) {
const n12 = this.rasterizeObstacleVia({ center: r10, obstacleRootId: o10, obstacleViaDiameter: t10.viaDiameter, zStart: i10.z, zEnd: r10.z, obstacleIndex: e50 });
if (n12)
return n12;
}
}
for (const n11 of t10.vias) {
if (!Number.isFinite(n11.x) || !Number.isFinite(n11.y))
return `Obstacle ${e50} contains non-finite via coordinates`;
const i10 = this.rasterizeObstacleVia({ center: n11, obstacleRootId: o10, obstacleViaDiameter: t10.viaDiameter, zStart: n11.zStart, zEnd: n11.zEnd, obstacleIndex: e50 });
if (i10)
return i10;
}
}
return this.obstacleTraceBlockedCellCount = this.obstacleTraceRootIdsFlat.reduce((e50, t10) => e50 + (t10 ? 1 : 0), 0), this.obstacleViaBlockedCellCount = this.obstacleViaRootIdsByCell.reduce((e50, t10) => e50 + (t10 ? 1 : 0), 0), null;
}
rasterizeRectObstacle(e50, t10) {
if (!Number.isFinite(e50.center.x) || !Number.isFinite(e50.center.y) || !Number.isFinite(e50.width) || !Number.isFinite(e50.height) || e50.width <= 0 || e50.height <= 0)
return `Rect obstacle ${t10} must have finite geometry and positive dimensions`;
const n10 = [];
for (const o11 of e50.zLayers) {
const e54 = this.zToLayer.get(o11);
if (e54 === undefined)
return `Rect obstacle ${t10} uses unavailable layer z=${o11}`;
Hee(n10, e54);
}
if (n10.length === 0)
return `Rect obstacle ${t10} must apply to at least one layer`;
const o10 = this.internObstacleRootName(Yee(e50.connectionName, e50.rootConnectionName)), i10 = { rootId: o10, center: e50.center, width: e50.width, height: e50.height, rotationRadians: (e50.ccwRotationDegrees ?? 0) * Math.PI / 180, layers: n10 };
this.obstacleRectPrimitives.push(i10);
const r10 = this.transformBoundsPointToGrid(e50.center), s10 = Math.hypot(e50.width / 2, e50.height / 2), a10 = this.getConservativeGridRadius(s10 + this.traceThickness / 2 + this.traceMargin);
this.forEachCellNearCircle(r10.x, r10.y, a10, (e54) => {
for (const t11 of n10)
this.addObstacleRootId({ rootIdsByCell: this.obstacleTraceRootIdsFlat, cellIndex: t11 * this.planeSize + e54, obstacleRootId: o10 });
});
const c10 = this.getConservativeGridRadius(s10 + this.viaDiameter / 2 + this.traceMargin);
return this.forEachCellNearCircle(r10.x, r10.y, c10, (e54) => {
this.addObstacleRootId({ rootIdsByCell: this.obstacleViaRootIdsByCell, cellIndex: e54, obstacleRootId: o10 });
}), null;
}
internObstacleRootName(e50) {
const t10 = this.obstacleRootNameToId.get(e50);
if (t10 !== undefined)
return t10;
const n10 = this.obstacleRootNames.length;
return this.obstacleRootNames.push(e50), this.obstacleRootNameToId.set(e50, n10), n10;
}
rasterizeObstacleTraceSegment(e50) {
this.obstacleTracePrimitives.push({ rootId: e50.obstacleRootId, layer: e50.layer, segmentStart: e50.segmentStart, segmentEnd: e50.segmentEnd, traceRadius: e50.obstacleTraceThickness / 2 });
const t10 = this.transformBoundsPointToGrid(e50.segmentStart), n10 = this.transformBoundsPointToGrid(e50.segmentEnd), o10 = this.getConservativeGridRadius(e50.obstacleTraceThickness / 2 + this.traceMargin), i10 = this.getConservativeGridRadius(e50.obstacleTraceThickness / 2 + this.viaDiameter / 2 + this.traceMargin);
this.forEachCellNearSegment({ segmentStart: t10, segmentEnd: n10, radius: o10 }, (t11) => {
this.addObstacleRootId({ rootIdsByCell: this.obstacleTraceRootIdsFlat, cellIndex: e50.layer * this.planeSize + t11, obstacleRootId: e50.obstacleRootId });
}), this.forEachCellNearSegment({ segmentStart: t10, segmentEnd: n10, radius: i10 }, (t11) => {
this.addObstacleRootId({ rootIdsByCell: this.obstacleViaRootIdsByCell, cellIndex: t11, obstacleRootId: e50.obstacleRootId });
});
}
rasterizeObstacleVia(e50) {
if (e50.zStart === undefined != (e50.zEnd === undefined))
return `Obstacle ${e50.obstacleIndex} via must provide both zStart and zEnd`;
let t10 = Array.from({ length: this.layers }, (e54, t11) => t11);
if (e50.zStart !== undefined && e50.zEnd !== undefined) {
if (!Number.isFinite(e50.zStart) || !Number.isFinite(e50.zEnd))
return `Obstacle ${e50.obstacleIndex} contains a non-finite via layer span`;
const n11 = Math.min(e50.zStart, e50.zEnd), o11 = Math.max(e50.zStart, e50.zEnd);
t10 = this.availableZ.flatMap((e54, t11) => e54 >= n11 && e54 <= o11 ? [t11] : []);
}
if (t10.length === 0)
return null;
this.obstacleViaPrimitives.push({ rootId: e50.obstacleRootId, center: e50.center, viaRadius: e50.obstacleViaDiameter / 2, layers: t10 });
const n10 = this.transformBoundsPointToGrid(e50.center), o10 = this.getConservativeGridRadius(e50.obstacleViaDiameter / 2 + this.traceThickness / 2 + this.traceMargin), i10 = this.getConservativeGridRadius(e50.obstacleViaDiameter / 2 + this.viaDiameter / 2 + this.traceMargin);
return this.forEachCellNearCircle(n10.x, n10.y, Math.max(o10, i10), (r10) => {
const s10 = this.getCellRect(r10);
if (Uee(n10.x, n10.y, o10, s10.minX, s10.minY, s10.maxX, s10.maxY))
for (const n11 of t10)
this.addObstacleRootId({ rootIdsByCell: this.obstacleTraceRootIdsFlat, cellIndex: n11 * this.planeSize + r10, obstacleRootId: e50.obstacleRootId });
Uee(n10.x, n10.y, i10, s10.minX, s10.minY, s10.maxX, s10.maxY) && this.addObstacleRootId({ rootIdsByCell: this.obstacleViaRootIdsByCell, cellIndex: r10, obstacleRootId: e50.obstacleRootId });
}), null;
}
forEachCellNearSegment(e50, t10) {
const n10 = { x: (e50.segmentStart.x + e50.segmentEnd.x) / 2, y: (e50.segmentStart.y + e50.segmentEnd.y) / 2 }, o10 = Math.hypot(e50.segmentEnd.x - e50.segmentStart.x, e50.segmentEnd.y - e50.segmentStart.y) / 2 + e50.radius;
this.forEachCellNearCircle(n10.x, n10.y, o10, (n11) => {
tte({ segmentStart: e50.segmentStart, segmentEnd: e50.segmentEnd, radius: e50.radius, rect: this.getCellRect(n11) }) && t10(n11);
});
}
getCellRect(e50) {
return { minX: this.cellMinX[e50], minY: this.cellMinY[e50], maxX: this.cellMaxX[e50], maxY: this.cellMaxY[e50] };
}
transformBoundsPointToGrid(e50) {
const t10 = this.gridToBoundsTransform;
return { x: (e50.x - t10.c) / t10.a, y: (e50.y - t10.f) / t10.e };
}
getConservativeGridRadius(e50) {
return e50 / Math.min(Math.abs(this.gridToBoundsTransform.a), Math.abs(this.gridToBoundsTransform.e));
}
addObstacleRootId(e50) {
let t10 = e50.rootIdsByCell[e50.cellIndex];
t10 || (t10 = [], e50.rootIdsByCell[e50.cellIndex] = t10), Hee(t10, e50.obstacleRootId);
}
isBlockedByObstacleRoots(e50, t10) {
if (!e50)
return false;
const n10 = this.connIdToRootNet[t10];
for (const t11 of e50)
if (this.obstacleRootNames[t11] !== n10)
return true;
return false;
}
hasSameRootObstacle(e50, t10) {
if (!e50)
return false;
const n10 = this.connIdToRootNet[t10];
return e50.some((e54) => this.obstacleRootNames[e54] === n10);
}
isLateralMoveBlockedByObstacleGeometry(e50) {
const t10 = this.connIdToRootNet[e50.activeConn], n10 = this.activeConnSeg, o10 = n10 && e50.layer === n10.startZ && e50.fromCellId === n10.startCellId ? n10.startPoint : Eee(this.gridToBoundsTransform, { x: this.cellCenterX[e50.fromCellId], y: this.cellCenterY[e50.fromCellId] }), i10 = n10 && e50.layer === n10.endZ && e50.toCellId === n10.endCellId ? n10.endPoint : Eee(this.gridToBoundsTransform, { x: this.cellCenterX[e50.toCellId], y: this.cellCenterY[e50.toCellId] });
for (const n11 of this.obstacleTracePrimitives) {
if (n11.layer !== e50.layer || this.obstacleRootNames[n11.rootId] === t10)
continue;
const r10 = n11.traceRadius + this.traceThickness / 2 + this.obstacleClearanceMargin;
if (ete({ firstStart: o10, firstEnd: i10, secondStart: n11.segmentStart, secondEnd: n11.segmentEnd }) < r10 * r10)
return true;
}
for (const n11 of this.obstacleViaPrimitives) {
if (!n11.layers.includes(e50.layer) || this.obstacleRootNames[n11.rootId] === t10)
continue;
const r10 = n11.viaRadius + this.traceThickness / 2 + this.obstacleClearanceMargin;
if (Zee({ point: n11.center, segmentStart: o10, segmentEnd: i10 }) < r10 * r10)
return true;
}
for (const n11 of this.obstacleRectPrimitives)
if (n11.layers.includes(e50.layer) && this.obstacleRootNames[n11.rootId] !== t10 && tte({ segmentStart: Xee(o10, n11), segmentEnd: Xee(i10, n11), radius: this.traceThickness / 2 + this.obstacleClearanceMargin, rect: Wee(n11) }))
return true;
return false;
}
isViaMoveBlockedByObstacleGeometry(e50) {
const t10 = this.connIdToRootNet[e50.activeConn], n10 = Eee(this.gridToBoundsTransform, { x: this.cellCenterX[e50.cellId], y: this.cellCenterY[e50.cellId] });
for (const e54 of this.obstacleTracePrimitives) {
if (this.obstacleRootNames[e54.rootId] === t10)
continue;
const o10 = e54.traceRadius + this.viaDiameter / 2 + this.obstacleClearanceMargin;
if (Zee({ point: n10, segmentStart: e54.segmentStart, segmentEnd: e54.segmentEnd }) < o10 * o10)
return true;
}
for (const e54 of this.obstacleViaPrimitives) {
if (this.obstacleRootNames[e54.rootId] === t10)
continue;
const o10 = e54.viaRadius + this.viaDiameter / 2 + this.obstacleClearanceMargin;
if ((n10.x - e54.center.x) ** 2 + (n10.y - e54.center.y) ** 2 < o10 * o10)
return true;
}
for (const e54 of this.obstacleRectPrimitives) {
if (this.obstacleRootNames[e54.rootId] === t10)
continue;
const o10 = Xee(n10, e54), i10 = this.viaDiameter / 2 + this.obstacleClearanceMargin;
if (qee({ point: o10, rect: Wee(e54) }) < i10 * i10)
return true;
}
return false;
}
buildFiveRegionGrid(e50, t10) {
this.fineCols = Math.max(1, Math.ceil(e50 / this.highResolutionCellSize)), this.fineRows = Math.max(1, Math.ceil(t10 / 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 n10 = Math.max(0, this.fineCols - 2 * this.bandCols), o10 = Math.max(0, this.fineRows - 2 * this.bandRows), i10 = n10, r10 = n10;
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: i10, cellScale: 1, rows: this.bandRows, cols: i10, 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: r10, cellScale: 1, rows: this.bandRows, cols: r10, offset: 0 }, { id: 4, name: "middle", fineOriginRow: this.bandRows, fineOriginCol: this.bandCols, fineRows: o10, fineCols: n10, cellScale: this.lowScale, rows: o10 > 0 ? Math.ceil(o10 / this.lowScale) : 0, cols: n10 > 0 ? Math.ceil(n10 / this.lowScale) : 0, offset: 0 }];
let s10 = 0;
for (let e54 = 0;e54 < this.regions.length; e54++)
this.regions[e54].offset = s10, s10 += this.regions[e54].rows * this.regions[e54].cols;
this.planeSize = s10, 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 e54 = 0;e54 < this.regions.length; e54++) {
const t11 = this.regions[e54];
for (let e58 = 0;e58 < t11.rows; e58++) {
const n11 = t11.fineOriginRow + e58 * t11.cellScale, o11 = Math.min(t11.fineOriginRow + t11.fineRows, n11 + t11.cellScale), i11 = this.boundsMinY + n11 * this.highResolutionCellSize, r11 = Math.min(this.boundsMaxY, this.boundsMinY + o11 * this.highResolutionCellSize);
for (let n12 = 0;n12 < t11.cols; n12++) {
const o12 = t11.fineOriginCol + n12 * t11.cellScale, s11 = Math.min(t11.fineOriginCol + t11.fineCols, o12 + t11.cellScale), a11 = this.boundsMinX + o12 * this.highResolutionCellSize, c11 = Math.min(this.boundsMaxX, this.boundsMinX + s11 * this.highResolutionCellSize), l11 = this.cellIdFor(t11.id, e58, n12);
this.cellCenterX[l11] = (a11 + c11) / 2, this.cellCenterY[l11] = (i11 + r11) / 2, this.cellMinX[l11] = a11, this.cellMinY[l11] = i11, this.cellMaxX[l11] = c11, this.cellMaxY[l11] = r11, this.cellWidth[l11] = c11 - a11, this.cellHeight[l11] = r11 - i11, this.cellRegion[l11] = t11.id, this.cellRow[l11] = e58, this.cellCol[l11] = n12;
const h11 = Math.min(this.cellCenterX[l11] - this.boundsMinX, this.boundsMaxX - this.cellCenterX[l11], this.cellCenterY[l11] - this.boundsMinY, this.boundsMaxY - this.cellCenterY[l11]);
this.viaAllowed[l11] = h11 >= this.viaMinDistFromBorder ? 1 : 0;
}
}
}
const a10 = Array.from({ length: this.planeSize }, () => []), c10 = (e54, t11) => {
if (e54 === t11 || e54 < 0 || t11 < 0)
return;
const n11 = this.cellCenterX[e54] - this.cellCenterX[t11], o11 = this.cellCenterY[e54] - this.cellCenterY[t11], i11 = Math.hypot(n11, o11);
Gee(a10[e54], { cellId: t11, cost: i11 }), Gee(a10[t11], { cellId: e54, cost: i11 });
};
for (let e54 = 0;e54 < this.regions.length; e54++) {
const t11 = this.regions[e54];
for (let e58 = 0;e58 < t11.rows; e58++)
for (let n11 = 0;n11 < t11.cols; n11++) {
const o11 = this.cellIdFor(t11.id, e58, n11);
e58 + 1 < t11.rows && c10(o11, this.cellIdFor(t11.id, e58 + 1, n11)), n11 + 1 < t11.cols && c10(o11, this.cellIdFor(t11.id, e58, n11 + 1));
}
}
const l10 = this.regions[0], h10 = this.regions[1], d10 = this.regions[2], u10 = this.regions[3], p10 = this.regions[4], m10 = l10.rows > 0 && l10.cols > 0, g10 = h10.rows > 0 && h10.cols > 0, f10 = d10.rows > 0 && d10.cols > 0, _10 = u10.rows > 0 && u10.cols > 0, y10 = p10.rows > 0 && p10.cols > 0;
if (m10 && g10)
for (let e54 = 0;e54 < this.bandRows; e54++)
c10(this.cellIdFor(0, e54, l10.cols - 1), this.cellIdFor(1, e54, 0));
if (g10 && f10)
for (let e54 = 0;e54 < this.bandRows; e54++)
c10(this.cellIdFor(1, e54, h10.cols - 1), this.cellIdFor(2, e54, 0));
if (m10 && _10)
for (let e54 = this.fineRows - this.bandRows;e54 < this.fineRows; e54++)
c10(this.cellIdFor(0, e54, l10.cols - 1), this.cellIdFor(3, e54 - (this.fineRows - this.bandRows), 0));
if (_10 && f10)
for (let e54 = this.fineRows - this.bandRows;e54 < this.fineRows; e54++)
c10(this.cellIdFor(3, e54 - (this.fineRows - this.bandRows), u10.cols - 1), this.cellIdFor(2, e54, 0));
if (m10 && y10)
for (let e54 = this.bandRows;e54 < this.fineRows - this.bandRows; e54++)
c10(this.cellIdFor(0, e54, l10.cols - 1), this.cellIdFor(4, Math.floor((e54 - this.bandRows) / this.lowScale), 0));
if (f10 && y10)
for (let e54 = this.bandRows;e54 < this.fineRows - this.bandRows; e54++)
c10(this.cellIdFor(4, Math.floor((e54 - this.bandRows) / this.lowScale), p10.cols - 1), this.cellIdFor(2, e54, 0));
if (g10 && y10)
for (let e54 = this.bandCols;e54 < this.fineCols - this.bandCols; e54++)
c10(this.cellIdFor(1, h10.rows - 1, e54 - this.bandCols), this.cellIdFor(4, 0, Math.floor((e54 - this.bandCols) / this.lowScale)));
if (_10 && y10)
for (let e54 = this.bandCols;e54 < this.fineCols - this.bandCols; e54++)
c10(this.cellIdFor(4, p10.rows - 1, Math.floor((e54 - this.bandCols) / this.lowScale)), this.cellIdFor(3, 0, e54 - this.bandCols));
if (!y10 && !g10 && !_10 && m10 && f10)
for (let e54 = 0;e54 < Math.min(l10.rows, d10.rows); e54++)
c10(this.cellIdFor(0, e54, l10.cols - 1), this.cellIdFor(2, e54, 0));
if (!y10 && !m10 && !f10 && g10 && _10)
for (let e54 = 0;e54 < Math.min(h10.cols, u10.cols); e54++)
c10(this.cellIdFor(1, h10.rows - 1, e54), this.cellIdFor(3, 0, e54));
const b10 = this.flattenNeighborLists(a10);
this.neighborOffset = b10.offset, this.neighborIds = b10.ids, this.neighborCosts = b10.costs;
}
cellIdFor(e50, t10, n10) {
const o10 = this.regions[e50];
return o10.offset + t10 * o10.cols + n10;
}
stepOnce() {
if (!this.activeConnSeg) {
if (this.unsolvedSegs.length === 0)
return void (this.solved = true);
const e54 = this.unsolvedSegs.shift();
this.activeConnSeg = e54, this.activeConnId = e54.connId, this.nodePool.clear(), this.ripChain.clear(), this.heap.clear(), this.seqCounter = 0, this.searchIterations = 0, this.nextStamp();
const t11 = this.computeH(e54.startZ, e54.startCellId, e54.endZ, e54.endCellId) * this.hyperParameters.greedyMultiplier, n11 = this.nodePool.push(e54.startZ, e54.startCellId, 0, -1, -1, 0), o11 = e54.startZ * this.planeSize + e54.startCellId, i11 = this.getSearchStateIdx(o11, 0);
return this.bestGStamp[i11] = this.stamp, this.bestGValue[i11] = 0, void this.heap.push(t11, this.seqCounter++, n11);
}
this.searchIterations++;
const e50 = this.ripCount[this.activeConnId] ?? 0, t10 = Math.round(this.baseSearchBudgetIters * (1 + 0.25 * Math.min(e50, 10)));
if (this.searchIterations > t10) {
const e54 = this.penalty2d;
for (let t11 = 0;t11 < e54.length; t11++)
e54[t11] = 0.9 * e54[t11];
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 = true));
}
if (this.heap.size === 0)
return this.error = `No path found for ${this.connIdToName[this.activeConnId]}`, void (this.failed = true);
const n10 = this.heap.pop(), o10 = this.nodePool.z[n10], i10 = this.nodePool.cellId[n10], r10 = this.nodePool.g[n10], s10 = this.nodePool.ripHead[n10], a10 = this.nodePool.ripCount[n10], c10 = o10 * this.planeSize + i10, l10 = this.getSearchStateIdx(c10, a10);
if (this.visitedStamp[l10] === this.stamp)
return;
this.visitedStamp[l10] = this.stamp, this.visitedFlatStamp[c10] = this.stamp;
const h10 = this.activeConnSeg;
if (o10 === h10.endZ && i10 === h10.endCellId)
return this.finalizeRoute(n10), this.activeConnSeg = null, void (this.activeConnId = -1);
const d10 = this.visitedStamp, u10 = this.stamp, p10 = this.activeConnId, m10 = h10.endZ, g10 = h10.endCellId, f10 = this.neighborOffset[i10], _10 = this.neighborOffset[i10 + 1];
for (let e54 = f10;e54 < _10; e54++) {
const t11 = this.neighborIds[e54], c11 = o10 * this.planeSize + t11;
if (this.computeMoveCostAndRips(p10, o10, i10, t11, false, s10, a10, this.neighborCosts[e54]), this._moveCost < 0)
continue;
const l11 = this.getSearchStateIdx(c11, this._moveRipCount);
if (d10[l11] === u10)
continue;
const h11 = r10 + this._moveCost;
if (this.bestGStamp[l11] === u10 && h11 >= this.bestGValue[l11])
continue;
this.bestGStamp[l11] = u10, this.bestGValue[l11] = h11;
const f11 = h11 + this.computeH(o10, t11, m10, g10) * this.hyperParameters.greedyMultiplier, _11 = this.nodePool.push(o10, t11, h11, n10, this._moveRippedHead, this._moveRipCount);
this.heap.push(f11, this.seqCounter++, _11);
}
if (this.viaAllowed[i10])
for (let e54 = 0;e54 < this.layers; e54++) {
if (e54 === o10)
continue;
const t11 = e54 * this.planeSize + i10;
if (this.computeMoveCostAndRips(p10, e54, i10, i10, true, s10, a10, 0), this._moveCost < 0)
continue;
const c11 = this.getSearchStateIdx(t11, this._moveRipCount);
if (d10[c11] === u10)
continue;
const l11 = r10 + this._moveCost;
if (this.bestGStamp[c11] === u10 && l11 >= this.bestGValue[c11])
continue;
this.bestGStamp[c11] = u10, this.bestGValue[c11] = l11;
const h11 = l11 + this.computeH(e54, i10, m10, g10) * this.hyperParameters.greedyMultiplier, f11 = this.nodePool.push(e54, i10, l11, n10, this._moveRippedHead, this._moveRipCount);
this.heap.push(h11, this.seqCounter++, f11);
}
}
computeMoveCostAndRips(e50, t10, n10, o10, i10, r10, s10, a10) {
let c10 = 0, l10 = r10, h10 = s10;
const d10 = t10 * this.planeSize + o10, u10 = i10 ? this.obstacleViaRootIdsByCell[o10] : [...this.obstacleTraceRootIdsFlat[t10 * this.planeSize + n10] ?? [], ...this.obstacleTraceRootIdsFlat[d10] ?? []];
if (this.isBlockedByObstacleRoots(u10, e50) && (i10 ? this.isViaMoveBlockedByObstacleGeometry({ activeConn: e50, cellId: o10 }) : this.isLateralMoveBlockedByObstacleGeometry({ activeConn: e50, layer: t10, fromCellId: n10, toCellId: o10 })))
return this._moveCost = -1, this._moveRippedHead = l10, void (this._moveRipCount = h10);
const p10 = this.hasSameRootObstacle(u10, e50);
if (i10) {
c10 += this.hyperParameters.viaBaseCost, c10 += Math.min(this.penalty2d[o10], this.penaltyCap);
const n11 = this.portOwnerFlat[d10], i11 = this.allowSharedUse(e50, n11), r11 = this.activeConnSeg, s11 = !!r11 && t10 === r11.endZ && o10 === r11.endCellId;
if (n11 >= 0 && n11 !== e50 && !i11 && !s11)
return this._moveCost = -1, void (this._moveRippedHead = l10);
this.fillViaOccupants(o10, e50);
const a11 = this._viaOccs;
for (let e54 = 0;e54 < a11.length; e54++) {
const t11 = a11[e54];
this.ripChain.contains(l10, t11) || (c10 += this.hyperParameters.ripCost, l10 = this.ripChain.append(l10, t11), h10++), c10 += this.hyperParameters.ripViaPenalty;
}
} else {
c10 += a10, c10 += Math.min(this.penalty2d[o10], this.penaltyCap);
const n11 = this.portOwnerFlat[d10], i11 = this.allowSharedUse(e50, n11), r11 = this.activeConnSeg, s11 = !!r11 && t10 === r11.endZ && o10 === r11.endCellId;
if (n11 >= 0 && n11 !== e50 && !i11 && !s11)
return this._moveCost = -1, void (this._moveRippedHead = l10);
this.fillTraceOccupants(d10, e50, this._cellOccs);
for (let e54 = 0;e54 < this._cellOccs.length; e54++) {
const t11 = this._cellOccs[e54];
this.ripChain.contains(l10, t11) || (c10 += this.hyperParameters.ripCost, l10 = this.ripChain.append(l10, t11), h10++), c10 += this.hyperParameters.ripTracePenalty;
}
}
p10 && (c10 *= this.hyperParameters.sameRootObstacleCostMultiplier), this._moveCost = c10, this._moveRippedHead = l10, this._moveRipCount = h10;
}
fillViaOccupants(e50, t10) {
const n10 = this._viaOccs;
n10.length = 0;
const o10 = this.cellCenterX[e50], i10 = this.cellCenterY[e50];
this.forEachCellNearCircle(o10, i10, this.viaKeepoutRadius, (e54) => {
if (Uee(o10, i10, this.viaKeepoutRadius, this.cellMinX[e54], this.cellMinY[e54], this.cellMaxX[e54], this.cellMaxY[e54]))
for (let o11 = 0;o11 < this.layers; o11++)
this.pushFlatOccupants(o11 * this.planeSize + e54, t10, n10);
});
}
fillTraceOccupants(e50, t10, n10) {
n10.length = 0, this.pushFlatOccupants(e50, t10, n10);
}
pushFlatOccupants(e50, t10, n10) {
const o10 = this.usedCellsFlat[e50];
o10 === -1 || o10 === t10 || this.allowSharedUse(t10, o10) || Hee(n10, o10);
const i10 = this.sharedCellsFlat[e50];
if (i10)
for (let e54 = 0;e54 < i10.length; e54++) {
const o11 = i10[e54];
o11 !== t10 && (this.allowSharedUse(t10, o11) || Hee(n10, o11));
}
}
addSharedOccupant(e50, t10) {
if (this.usedCellsFlat[e50] === t10)
return;
let n10 = this.sharedCellsFlat[e50];
n10 || (n10 = [], this.sharedCellsFlat[e50] = n10), Hee(n10, t10);
}
replaceOccupants(e50, t10) {
this.usedCellsFlat[e50] = t10, this.sharedCellsFlat[e50] = undefined;
}
removeOccupant(e50, t10) {
const n10 = this.sharedCellsFlat[e50];
if (this.usedCellsFlat[e50] === t10)
return void (n10 && n10.length > 0 ? (this.usedCellsFlat[e50] = n10.pop(), n10.length === 0 && (this.sharedCellsFlat[e50] = undefined)) : this.usedCellsFlat[e50] = -1);
if (!n10)
return;
const o10 = n10.indexOf(t10);
o10 !== -1 && (n10.splice(o10, 1), n10.length === 0 && (this.sharedCellsFlat[e50] = undefined));
}
allowSharedUse(e50, t10) {
if (t10 < 0)
return false;
return this.connIdToRootNet[t10] === this.connIdToRootNet[e50];
}
shouldSkipFixedPortHalo(e50, t10) {
const n10 = this.portOwnerFlat[e50];
return n10 !== t10 && (n10 === -2 || !(n10 < 0) && !this.allowSharedUse(t10, n10));
}
nextStamp() {
this.stamp = this.stamp + 1 >>> 0, this.stamp === 0 && (this.visitedStamp.fill(0), this.bestGStamp.fill(0), this.visitedFlatStamp.fill(0), this.stamp = 1);
}
getSearchStateIdx(e50, t10) {
return e50;
}
computeH(e50, t10, n10, o10) {
const i10 = Math.hypot(this.cellCenterX[t10] - this.cellCenterX[o10], this.cellCenterY[t10] - this.cellCenterY[o10]);
return e50 === n10 ? i10 : i10 + this.hyperParameters.viaBaseCost;
}
internConn(e50, t10) {
const n10 = this.connNameToId.get(e50);
if (n10 !== undefined)
return n10;
const o10 = this.connIdToName.length;
return this.connIdToName.push(e50), this.connIdToRootNet.push(Yee(e50, t10)), this.connNameToId.set(e50, o10), o10;
}
buildConnectionSegs() {
const e50 = new Map;
for (const t11 of this.nodeWithPortPoints.portPoints) {
const n11 = t11.connectionName;
e50.has(n11) || e50.set(n11, { points: [], rootConnectionName: t11.rootConnectionName }), e50.get(n11).points.push(t11);
}
const t10 = [], n10 = new Map;
for (const [o10, i10] of e50) {
const e54 = i10.points, r10 = Lee(e54);
if (r10.length === 0)
continue;
const s10 = this.internConn(o10, i10.rootConnectionName);
for (const [e58, i11] of r10) {
const r11 = this.pointToCell(e58), a10 = this.pointToCell(i11), c10 = `${r11.z}:${r11.cellId}`, l10 = `${a10.z}:${a10.cellId}`, h10 = c10 < l10 ? `${c10}|${l10}` : `${l10}|${c10}`, d10 = this.connIdToRootNet[s10], u10 = `${d10}|${h10}`, p10 = n10.get(u10);
if (p10) {
if (this.overlapFriendlyRootNets.add(d10), !p10.connectionAliases.some((e59) => e59.connectionName === o10)) {
const t11 = p10.startZ === r11.z && p10.startCellId === r11.cellId && p10.endZ === a10.z && p10.endCellId === a10.cellId, n11 = p10.startZ === a10.z && p10.startCellId === a10.cellId && p10.endZ === r11.z && p10.endCellId === r11.cellId;
if (!t11 && !n11)
throw new Error(`Connection alias ${o10} does not match canonical segment ${u10}`);
p10.connectionAliases.push({ connectionName: o10, rootConnectionName: d10, startPoint: e58, endPoint: i11, reversedFromCanonical: !t11 && n11 });
}
continue;
}
const m10 = { connId: s10, startZ: r11.z, startCellId: r11.cellId, startPoint: e58, endZ: a10.z, endCellId: a10.cellId, endPoint: i11, connectionAliases: [{ connectionName: o10, rootConnectionName: d10, startPoint: e58, endPoint: i11, reversedFromCanonical: false }] };
n10.set(u10, m10), t10.push(m10);
}
}
return t10;
}
pointToCell(e50) {
const t10 = Vee(Math.floor((e50.x - this.boundsMinX) / this.highResolutionCellSize), 0, this.fineCols - 1), n10 = Vee(Math.floor((e50.y - this.boundsMinY) / this.highResolutionCellSize), 0, this.fineRows - 1);
let o10 = 4;
t10 < this.bandCols ? o10 = 0 : t10 >= this.fineCols - this.bandCols ? o10 = 2 : n10 < this.bandRows ? o10 = 1 : n10 >= this.fineRows - this.bandRows && (o10 = 3);
const i10 = this.regions[o10], r10 = n10 - i10.fineOriginRow, s10 = t10 - i10.fineOriginCol, a10 = Vee(Math.floor(r10 / i10.cellScale), 0, Math.max(0, i10.rows - 1)), c10 = Vee(Math.floor(s10 / i10.cellScale), 0, Math.max(0, i10.cols - 1));
return { z: this.zToLayer.get(e50.z) ?? 0, cellId: this.cellIdFor(o10, a10, c10) };
}
shuffleConnections() {
const e50 = this.unsolvedSegs;
let t10 = this.hyperParameters.shuffleSeed >>> 0;
const n10 = () => (t10 = Math.imul(t10, 1664525) + 1013904223 >>> 0, t10 / 4294967295);
for (let t11 = e50.length - 1;t11 > 0; t11--) {
const o10 = Math.floor(n10() * (t11 + 1)), i10 = e50[t11];
e50[t11] = e50[o10], e50[o10] = i10;
}
}
finalizeRoute(e50) {
this.consecutiveSkips = Math.max(0, this.consecutiveSkips - 1);
const t10 = [];
let n10 = e50;
for (;n10 >= 0; ) {
const e54 = this.nodePool.z[n10], o11 = this.nodePool.cellId[n10];
t10.push(e54 * this.planeSize + o11), n10 = this.nodePool.parent[n10];
}
for (t10.reverse();t10.length > 1 && this.sharedCrossRootPortFlat[t10[0]]; )
t10.shift();
for (;t10.length > 1 && this.sharedCrossRootPortFlat[t10[t10.length - 1]]; )
t10.pop();
const o10 = this.extractViaCellIds(t10), i10 = this.activeConnId;
this.ripChain.collect(this.nodePool.ripHead[e50], this._rippedIds);
for (let e54 = 0;e54 < this._rippedIds.length; e54++)
if (this.ripTrace(this._rippedIds[e54]), this.failed)
return;
const r10 = [];
for (let e54 = 0;e54 < t10.length; e54++) {
const n11 = t10[e54], o11 = Math.floor(n11 / this.planeSize), s11 = n11 - o11 * this.planeSize;
this.markTraceFootprint(i10, o11, s11, r10);
}
const s10 = [];
for (let e54 = 0;e54 < o10.length; e54++)
this.markViaFootprint(i10, o10[e54], r10, s10);
for (;this.usedIndicesByConn.length <= i10; )
this.usedIndicesByConn.push(undefined);
const a10 = this.usedIndicesByConn[i10] ?? [];
for (a10.push(...r10), this.usedIndicesByConn[i10] = a10;this.solvedRoutes.length <= i10; )
this.solvedRoutes.push(undefined);
const c10 = this.solvedRoutes[i10] ?? [];
c10.push({ connId: i10, states: Int32Array.from(t10), viaCellIds: Int32Array.from(o10), startPoint: this.activeConnSeg.startPoint, endPoint: this.activeConnSeg.endPoint, connectionAliases: this.activeConnSeg.connectionAliases }), this.solvedRoutes[i10] = c10;
for (let e54 = 0;e54 < s10.length; e54++)
if (this.ripTrace(s10[e54]), this.failed)
return;
if (this._rippedIds.length > 0 || s10.length > 0) {
const e54 = this.penalty2d, t11 = this.penaltyCap;
if (this.totalRipEvents > 50)
for (let t12 = 0;t12 < e54.length; t12++)
e54[t12] = 0.99 * e54[t12];
else
for (let n11 = 0;n11 < e54.length; n11++)
e54[n11] > t11 && (e54[n11] = 0.5 * e54[n11]);
}
}
extractViaCellIds(e50) {
const t10 = [];
for (let n10 = 1;n10 < e50.length; n10++) {
const o10 = e50[n10 - 1], i10 = e50[n10], r10 = Math.floor(o10 / this.planeSize), s10 = Math.floor(i10 / this.planeSize);
r10 !== s10 && t10.push(i10 - s10 * this.planeSize);
}
return t10;
}
markTraceFootprint(e50, t10, n10, o10) {
const i10 = this.cellCenterX[n10], r10 = this.cellCenterY[n10];
this.forEachCellNearCircle(i10, r10, this.traceKeepoutRadius, (s10) => {
if (!Uee(i10, r10, this.traceKeepoutRadius, this.cellMinX[s10], this.cellMinY[s10], this.cellMaxX[s10], this.cellMaxY[s10]))
return;
const a10 = t10 * this.planeSize + s10;
if (s10 !== n10 && this.shouldSkipFixedPortHalo(a10, e50))
return;
const c10 = this.usedCellsFlat[a10], l10 = this.allowSharedUse(e50, c10);
(c10 === -1 || c10 === e50 || l10) && (c10 !== -1 && c10 !== e50 ? this.addSharedOccupant(a10, e50) : this.usedCellsFlat[a10] = e50, o10.push(a10));
});
}
markViaFootprint(e50, t10, n10, o10) {
const i10 = this.cellCenterX[t10], r10 = this.cellCenterY[t10];
this.forEachCellNearCircle(i10, r10, this.viaKeepoutRadius, (s10) => {
if (Uee(i10, r10, this.viaKeepoutRadius, this.cellMinX[s10], this.cellMinY[s10], this.cellMaxX[s10], this.cellMaxY[s10]))
for (let i11 = 0;i11 < this.layers; i11++) {
const r11 = i11 * this.planeSize + s10;
if (s10 !== t10 && this.shouldSkipFixedPortHalo(r11, e50))
continue;
if (this.fillTraceOccupants(r11, e50, this._cellOccs), this._cellOccs.length > 0) {
for (let e54 = 0;e54 < this._cellOccs.length; e54++)
Hee(o10, this._cellOccs[e54]);
this.replaceOccupants(r11, e50), n10.push(r11);
continue;
}
const a10 = this.usedCellsFlat[r11];
a10 !== -1 && a10 !== e50 ? this.addSharedOccupant(r11, e50) : this.usedCellsFlat[r11] = e50, n10.push(r11);
}
});
}
forEachCellNearCircle(e50, t10, n10, o10) {
const i10 = Vee(Math.floor((e50 - n10 - this.boundsMinX) / this.highResolutionCellSize), 0, this.fineCols - 1), r10 = Vee(Math.floor((e50 + n10 - this.boundsMinX) / this.highResolutionCellSize), 0, this.fineCols - 1), s10 = Vee(Math.floor((t10 - n10 - this.boundsMinY) / this.highResolutionCellSize), 0, this.fineRows - 1), a10 = Vee(Math.floor((t10 + n10 - this.boundsMinY) / this.highResolutionCellSize), 0, this.fineRows - 1);
for (let e54 = 0;e54 < this.regions.length; e54++) {
const t11 = this.regions[e54];
if (t11.rows === 0 || t11.cols === 0)
continue;
const n11 = Math.max(s10, t11.fineOriginRow), c10 = Math.min(a10, t11.fineOriginRow + t11.fineRows - 1), l10 = Math.max(i10, t11.fineOriginCol), h10 = Math.min(r10, t11.fineOriginCol + t11.fineCols - 1);
if (n11 > c10)
continue;
if (l10 > h10)
continue;
const d10 = Math.floor((n11 - t11.fineOriginRow) / t11.cellScale), u10 = Math.floor((c10 - t11.fineOriginRow) / t11.cellScale), p10 = Math.floor((l10 - t11.fineOriginCol) / t11.cellScale), m10 = Math.floor((h10 - t11.fineOriginCol) / t11.cellScale);
for (let e58 = d10;e58 <= u10; e58++)
for (let n12 = p10;n12 <= m10; n12++)
o10(this.cellIdFor(t11.id, e58, n12));
}
}
ripTrace(e50) {
for (;this.ripCount.length <= e50; )
this.ripCount.push(0);
if (this.ripCount[e50]++, this.totalRipEvents++, this.totalRipEvents >= this.MAX_RIPS)
return this.error = `Convergence failure: exceeded MAX_RIPS ${this.MAX_RIPS}`, void (this.failed = true);
const t10 = this.getSolvedRoutesForConn(e50);
if (t10.length > 0)
for (const e54 of t10) {
for (let t11 = 0;t11 < e54.states.length; t11++) {
const n11 = e54.states[t11] % this.planeSize;
this.penalty2d[n11] = this.penalty2d[n11] + this.hyperParameters.ripTracePenalty;
}
for (let t11 = 0;t11 < e54.viaCellIds.length; t11++) {
const n11 = e54.viaCellIds[t11];
this.penalty2d[n11] = this.penalty2d[n11] + this.hyperParameters.ripViaPenalty;
}
}
const n10 = this.usedIndicesByConn[e50];
if (n10) {
for (let t11 = 0;t11 < n10.length; t11++)
this.removeOccupant(n10[t11], e50);
this.usedIndicesByConn[e50] = undefined;
}
if (t10.length > 0) {
this.solvedRoutes[e50] = undefined;
for (const n11 of t10) {
const t11 = n11.states[0], o10 = n11.states[n11.states.length - 1], i10 = Math.floor(t11 / this.planeSize), r10 = Math.floor(o10 / this.planeSize);
this.unsolvedSegs.push({ connId: e50, startZ: i10, startCellId: t11 - i10 * this.planeSize, startPoint: n11.startPoint, endZ: r10, endCellId: o10 - r10 * this.planeSize, endPoint: n11.endPoint, connectionAliases: n11.connectionAliases });
}
}
}
flattenNeighborLists(e50) {
const t10 = new Int32Array(e50.length + 1);
let n10 = 0;
for (let o11 = 0;o11 < e50.length; o11++)
t10[o11] = n10, n10 += e50[o11].length;
t10[e50.length] = n10;
const o10 = new Int32Array(n10), i10 = new Float32Array(n10);
let r10 = 0;
for (let t11 = 0;t11 < e50.length; t11++) {
const n11 = e50[t11];
for (let e54 = 0;e54 < n11.length; e54++) {
const t12 = n11[e54];
o10[r10] = t12.cellId, i10[r10] = t12.cost, r10++;
}
}
return { offset: t10, ids: o10, costs: i10 };
}
visualize() {
const e50 = ["red", "blue", "orange", "green"], t10 = this.gridToBoundsTransform, n10 = [], o10 = [], i10 = [], r10 = [];
r10.push({ center: { x: this.nodeWithPortPoints.center.x, y: this.nodeWithPortPoints.center.y }, width: this.nodeWithPortPoints.width, height: this.nodeWithPortPoints.height, stroke: "gray" });
const s10 = ({ route: t11, connectionName: n11, strokeWidth: i11, strokeDash: r11, labelPrefix: s11 }) => {
if (t11.length < 2)
return;
let a11 = 0;
for (let c11 = 1;c11 < t11.length; c11 += 1) {
const l10 = t11[c11 - 1];
t11[c11].z !== l10.z && (c11 - a11 >= 2 && o10.push({ points: t11.slice(a11, c11).map((e54) => ({ x: e54.x, y: e54.y })), strokeColor: e50[l10.z] ?? "rgba(128,128,128,0.75)", strokeWidth: i11, strokeDash: r11, label: `${s11} ${n11} z=${l10.z}` }), a11 = c11);
}
if (t11.length - a11 < 2)
return;
const c10 = t11[a11].z;
o10.push({ points: t11.slice(a11).map((e54) => ({ x: e54.x, y: e54.y })), strokeColor: e50[c10] ?? "rgba(128,128,128,0.75)", strokeWidth: i11, strokeDash: r11, label: `${s11} ${n11} z=${c10}` });
};
for (const e54 of this.obstacles)
if (e54.type !== "rect") {
s10({ route: e54.route, connectionName: e54.connectionName, strokeWidth: e54.traceThickness, strokeDash: [0.12, 0.08], labelPrefix: "fixed obstacle" });
for (const t11 of e54.vias)
i10.push({ center: { x: t11.x, y: t11.y }, radius: e54.viaDiameter / 2, fill: "rgba(128,0,128,0.25)", stroke: "purple", label: `fixed obstacle ${e54.connectionName} via` });
} else
r10.push({ center: e54.center, width: e54.width, height: e54.height, fill: "rgba(128,0,128,0.12)", stroke: "purple", label: `fixed obstacle ${e54.connectionName}` });
if (this.showPenaltyMap && this.penalty2d) {
let e54 = 0;
for (let t11 = 0;t11 < this.penalty2d.length; t11++)
this.penalty2d[t11] > e54 && (e54 = this.penalty2d[t11]);
if (e54 > 0)
for (let n11 = 0;n11 < this.planeSize; n11++) {
const o11 = this.penalty2d[n11];
if (o11 <= 0)
continue;
const i11 = Eee(t10, { x: this.cellCenterX[n11], y: this.cellCenterY[n11] }), s11 = Math.min(0.6, o11 / e54 * 0.6);
r10.push({ center: i11, width: this.cellWidth[n11] * t10.a, height: this.cellHeight[n11] * t10.e, fill: `rgba(255,165,0,${s11.toFixed(3)})` });
}
}
if (this.showUsedCellMap && this.usedCellsFlat)
for (let e54 = 0;e54 < this.layers; e54++) {
const n11 = e54 * this.planeSize;
for (let e58 = 0;e58 < this.planeSize; e58++) {
if (this.usedCellsFlat[n11 + e58] === -1)
continue;
const o11 = Eee(t10, { x: this.cellCenterX[e58], y: this.cellCenterY[e58] });
r10.push({ center: o11, width: this.cellWidth[e58] * t10.a, height: this.cellHeight[e58] * t10.e, fill: "rgba(0,0,255,0.5)" });
}
}
for (const t11 of this.nodeWithPortPoints.portPoints)
n10.push({ x: t11.x, y: t11.y, color: e50[t11.z] ?? "gray", label: t11.connectionName });
const a10 = this.getOutput();
for (const e54 of a10)
s10({ route: e54.route, connectionName: e54.connectionName, strokeWidth: this.traceThickness, labelPrefix: "B01 route" });
for (const e54 of a10)
for (const t11 of e54.vias)
i10.push({ center: { x: t11.x, y: t11.y }, radius: this.viaDiameter / 2, fill: "rgba(0,0,0,0.3)", stroke: "black", label: `B01 route ${e54.connectionName} via` });
if (this.activeConnSeg && this.visitedFlatStamp) {
const e54 = this.stamp;
for (let o11 = 0;o11 < this.layers; o11++) {
const i11 = o11 * this.planeSize;
for (let o12 = 0;o12 < this.planeSize; o12++) {
if (this.visitedFlatStamp[i11 + o12] !== e54)
continue;
const r11 = Eee(t10, { x: this.cellCenterX[o12], y: this.cellCenterY[o12] });
n10.push({ x: r11.x, y: r11.y, color: "rgba(0,0,255,0.2)" });
}
}
}
return { points: n10, lines: o10, circles: i10, rects: r10, coordinateSystem: "cartesian", title: `HighDensityB01 [${this.getSolvedRouteCount()} solved, ${this.unsolvedSegs?.length ?? 0} remaining]` };
}
getOutput() {
const e50 = this.gridToBoundsTransform, t10 = [];
for (let n10 = 0;n10 < this.solvedRoutes.length; n10++) {
const o10 = this.getSolvedRoutesForConn(n10);
if (o10.length !== 0)
for (const n11 of o10) {
const o11 = Array.from(n11.states, (t11) => {
const n12 = Math.floor(t11 / this.planeSize), o12 = t11 - n12 * this.planeSize, i11 = Eee(e50, { x: this.cellCenterX[o12], y: this.cellCenterY[o12] });
return { x: i11.x, y: i11.y, z: this.layerToZ.get(n12) ?? n12 };
}), i10 = Array.from(n11.viaCellIds, (t11) => Eee(e50, { x: this.cellCenterX[t11], y: this.cellCenterY[t11] }));
for (const e54 of n11.connectionAliases) {
const n12 = (e54.reversedFromCanonical ? [...o11].reverse() : o11).map((e58) => ({ ...e58 }));
n12.length > 0 && (n12[0] = { ...e54.startPoint }, n12.length > 1 && (n12[n12.length - 1] = { ...e54.endPoint })), t10.push({ connectionName: e54.connectionName, rootConnectionName: e54.rootConnectionName, regionId: this.nodeWithPortPoints.capacityMeshNodeId, traceThickness: this.traceThickness, viaDiameter: this.viaDiameter, route: n12, vias: i10.map((e58) => ({ ...e58 })) });
}
}
}
return t10;
}
getSolvedRoutesForConn(e50) {
const t10 = this.solvedRoutes[e50];
return t10 ? Array.isArray(t10) ? t10 : [t10] : [];
}
getSolvedRouteCount() {
let e50 = 0;
for (let t10 = 0;t10 < this.solvedRoutes.length; t10++)
e50 += this.getSolvedRoutesForConn(t10).length;
return e50;
}
computeGridToBoundsTransform() {
let e50 = 1 / 0, t10 = -1 / 0, n10 = 1 / 0, o10 = -1 / 0;
for (let i11 = 0;i11 < this.planeSize; i11++) {
const r11 = this.cellCenterX[i11], s11 = this.cellCenterY[i11];
r11 < e50 && (e50 = r11), r11 > t10 && (t10 = r11), s11 < n10 && (n10 = s11), s11 > o10 && (o10 = s11);
}
const i10 = t10 - e50, r10 = o10 - n10, s10 = this.boundsMaxX - this.boundsMinX, a10 = this.boundsMaxY - this.boundsMinY, c10 = i10 > 0 ? s10 / i10 : 1, l10 = r10 > 0 ? a10 / r10 : 1;
return { a: c10, b: 0, c: i10 > 0 ? this.boundsMinX - c10 * e50 : (this.boundsMinX + this.boundsMaxX) / 2 - e50, d: 0, e: l10, f: r10 > 0 ? this.boundsMinY - l10 * n10 : (this.boundsMinY + this.boundsMaxY) / 2 - n10 };
}
};
var ote = new WeakMap;
var ite = (e50, { layerCount: t10, allowBlindAndBuriedVias: n10 }) => {
const o10 = `${t10}:${n10 === true}`, i10 = ote.get(e50)?.get(o10);
if (i10)
return i10;
const r10 = [], s10 = [];
for (let o11 = 1;o11 < e50.route.length; o11++) {
const i11 = e50.route[o11 - 1], a11 = e50.route[o11], c11 = Math.hypot(a11.x - i11.x, a11.y - i11.y), l10 = Math.max(i11.traceThickness ?? e50.traceThickness, a11.traceThickness ?? e50.traceThickness);
if (i11.z !== a11.z && i11.toNextSegmentType === "through_obstacle") {
const t11 = Math.min(i11.z, a11.z), n11 = Math.max(i11.z, a11.z);
if (c11 <= 0.000000001) {
const o12 = e50.vias.some((e54) => Math.hypot(e54.x - a11.x, e54.y - a11.y) <= 0.000000001);
s10.push({ center: { x: a11.x, y: a11.y }, minZ: t11, maxZ: n11, diameter: o12 ? e50.viaDiameter : l10 });
continue;
}
for (let e54 = t11;e54 <= n11; e54++)
r10.push({ start: { ...i11, z: e54 }, end: { ...a11, z: e54 }, z: e54, width: l10 });
continue;
}
const h10 = i11.z === a11.z ? undefined : nee({ hdRoute: e50, start: i11, end: a11 }), d10 = h10 === "start" ? a11.z : i11.z;
if (c11 > 0.000000001 && r10.push({ start: i11.z === d10 ? i11 : { ...i11, z: d10 }, end: a11.z === d10 ? a11 : { ...a11, z: d10 }, z: d10, width: l10 }), i11.z === a11.z)
continue;
const u10 = h10 === "start" ? i11 : a11;
Po(i11.z, t10), Po(a11.z, t10), s10.push({ center: { x: u10.x, y: u10.y }, minZ: n10 ? Math.min(i11.z, a11.z) : 0, maxZ: n10 ? Math.max(i11.z, a11.z) : t10 - 1, diameter: e50.viaDiameter });
}
const a10 = { wireSegments: r10, viaSpans: s10 }, c10 = ote.get(e50) ?? new Map;
return c10.set(o10, a10), ote.set(e50, c10), a10;
};
var rte = (e50, t10, n10) => {
const o10 = e50.end.x - e50.start.x, i10 = e50.end.y - e50.start.y, r10 = Math.hypot(o10, i10), s10 = { x: (e50.start.x + e50.end.x) / 2, y: (e50.start.y + e50.end.y) / 2 };
return Math.abs(o10) <= 0.000000001 || Math.abs(i10) <= 0.000000001 ? [{ center: s10, width: Math.abs(o10) > Math.abs(i10) ? r10 : e50.width, height: Math.abs(o10) > Math.abs(i10) ? e50.width : r10 }] : I0({ center: s10, width: r10, height: e50.width, rotation: 180 * Math.atan2(i10, o10) / Math.PI }, Math.max(n10, Math.ceil(r10 / t10)));
};
var ste = ({ fixedObstacleRoutes: e50, layerCount: t10, allowBlindAndBuriedVias: n10 }) => e50.flatMap((e54, o10) => {
const i10 = [e54.connectionName, e54.rootConnectionName].filter((e58) => typeof e58 == "string"), r10 = ite(e54, { layerCount: t10, allowBlindAndBuriedVias: n10 });
return [...r10.wireSegments.flatMap((e58, n11) => rte(e58, 0.75, 2).map((r11, s10) => ({ obstacleId: `pipeline9_fixed_obstacle_${o10}_wire_${n11}_${s10}`, type: "rect", layers: [Po(e58.z, t10)], center: r11.center, width: r11.width, height: r11.height, connectedTo: i10 }))), ...r10.viaSpans.map((e58, n11) => ({ obstacleId: `pipeline9_fixed_obstacle_${o10}_via_${n11}`, type: "rect", layers: Array.from({ length: e58.maxZ - e58.minZ + 1 }, (n12, o11) => Po(e58.minZ + o11, t10)), center: e58.center, width: e58.diameter, height: e58.diameter, connectedTo: i10 }))];
});
var ate = (e50, t10, n10) => {
const o10 = [e50.connectionName, e50.rootConnectionName].filter((e54) => typeof e54 == "string"), i10 = [t10.connectionName, t10.rootConnectionName].filter((e54) => typeof e54 == "string");
return o10.some((e54) => i10.some((t11) => e54 === t11 || n10.areIdsConnected(e54, t11)));
};
var cte = (e50, t10) => e50.minX <= t10.maxX && e50.maxX >= t10.minX && e50.minY <= t10.maxY && e50.maxY >= t10.minY;
var lte = ({ left: e50, right: t10, clearance: n10, leftBounds: o10, layerCount: i10, allowBlindAndBuriedVias: r10 }) => {
const s10 = { layerCount: i10, allowBlindAndBuriedVias: r10 }, a10 = ite(e50, s10), c10 = ite(t10, s10), l10 = o10 ? a10.wireSegments.filter((e54) => ((e58, t11) => {
const n11 = { minX: Math.min(e58.start.x, e58.end.x) - e58.width / 2, maxX: Math.max(e58.start.x, e58.end.x) + e58.width / 2, minY: Math.min(e58.start.y, e58.end.y) - e58.width / 2, maxY: Math.max(e58.start.y, e58.end.y) + e58.width / 2 };
return cte(n11, t11);
})(e54, o10)) : a10.wireSegments, h10 = o10 ? a10.viaSpans.filter((e54) => ((e58, t11) => {
const n11 = { minX: e58.center.x - e58.diameter / 2, maxX: e58.center.x + e58.diameter / 2, minY: e58.center.y - e58.diameter / 2, maxY: e58.center.y + e58.diameter / 2 };
return cte(n11, t11);
})(e54, o10)) : a10.viaSpans;
for (const e54 of l10) {
for (const t11 of c10.wireSegments) {
if (e54.z !== t11.z)
continue;
const o11 = e54.width / 2 + t11.width / 2 + n10;
if (BJ(e54.start, e54.end, t11.start, t11.end) < o11)
return true;
}
for (const t11 of c10.viaSpans) {
if (e54.z < t11.minZ || e54.z > t11.maxZ)
continue;
const o11 = e54.width / 2 + t11.diameter / 2 + n10;
if (BJ(e54.start, e54.end, t11.center, t11.center) < o11)
return true;
}
}
for (const e54 of h10) {
for (const t11 of c10.wireSegments) {
if (t11.z < e54.minZ || t11.z > e54.maxZ)
continue;
const o11 = e54.diameter / 2 + t11.width / 2 + n10;
if (BJ(e54.center, e54.center, t11.start, t11.end) < o11)
return true;
}
for (const t11 of c10.viaSpans) {
if (e54.minZ > t11.maxZ || t11.minZ > e54.maxZ)
continue;
const o11 = e54.diameter / 2 + t11.diameter / 2 + n10;
if (Math.hypot(e54.center.x - t11.center.x, e54.center.y - t11.center.y) < o11)
return true;
}
}
return false;
};
var hte = ({ routes: e50, movablePreloadedConnectionNames: t10, boardObstacles: n10, connMap: o10, layerCount: i10, viaToPadClearance: r10, allowBlindAndBuriedVias: s10 }) => e50.some((e54) => {
if (!t10.has(e54.connectionName))
return false;
return ite(e54, { layerCount: i10, allowBlindAndBuriedVias: s10 }).viaSpans.some((t11) => n10.some((n11) => {
if ((({ obstacle: e58, route: t12, connMap: n12 }) => {
if (vo(e58, t12, n12))
return true;
if (!t12.rootConnectionName)
return false;
const o11 = n12.getNetConnectedToId(t12.connectionName) ?? n12.getNetConnectedToId(t12.rootConnectionName) ?? (n12.netMap[t12.rootConnectionName] ? t12.rootConnectionName : undefined);
return !!o11 && e58.connectedTo.some((e59) => (n12.getNetConnectedToId(e59) ?? (n12.netMap[e59] ? e59 : undefined)) === o11);
})({ obstacle: n11, route: e54, connMap: o10 }))
return false;
const s11 = ((e58, t12) => {
const n12 = e58.__zLayers ?? e58.zLayers;
return n12 || e58.layers.map((e59) => go(e59, t12));
})(n11, i10);
return !!s11.some((e58) => e58 >= t11.minZ && e58 <= t11.maxZ) && ((e58, t12) => {
const n12 = -1 * (t12.ccwRotationDegrees ?? 0) * Math.PI / 180, o11 = e58.x - t12.center.x, i11 = e58.y - t12.center.y, r11 = o11 * Math.cos(n12) - i11 * Math.sin(n12), s12 = o11 * Math.sin(n12) + i11 * Math.cos(n12), a10 = Math.max(Math.abs(r11) - t12.width / 2, 0), c10 = Math.max(Math.abs(s12) - t12.height / 2, 0);
return Math.hypot(a10, c10);
})(t11.center, n11) < t11.diameter / 2 + r10;
}));
});
var dte = class extends ai {
params;
highDensitySolver;
forceImproveSolver;
repairSolver;
phase = "route";
constructor(e50) {
super(), this.params = e50, this.stats = { preloadedViaCandidateRejectionCount: 0, forceImproveCandidateRejectionCount: 0, repairCandidateRejectionCount: 0 }, this.highDensitySolver = new JL({ nodePortPoints: [e50.nodeWithPortPoints], colorMap: e50.colorMap, connMap: e50.connMap, viaDiameter: e50.viaDiameter, traceWidth: e50.traceWidth, obstacleMargin: e50.obstacleMargin, effort: e50.effort, nodePfById: e50.nodePfById, obstacles: e50.obstacles, layerCount: e50.layerCount, useGrowShrinkHighDensityIntraNodeSolver: true, preserveTerminalPcbPortIds: false, growShrinkFallbackToInvalidGeometryOnFailure: false, growShrinkSolutionValidator: e50.boardObstacles && e50.movablePreloadedConnectionNames && e50.viaToPadClearance !== undefined ? (e54) => this.validateCandidateRoutes(e54) : undefined }), this.activeSubSolver = this.highDensitySolver, this.MAX_ITERATIONS = 1e8 * e50.effort;
}
getSolverName() {
return "Pipeline9RegionalFallbackSolver";
}
validateCandidateRoutes(e50) {
const { boardObstacles: t10, movablePreloadedConnectionNames: n10, viaToPadClearance: o10 } = this.params;
if (!t10 || !n10 || o10 === undefined)
return true;
const i10 = hte({ routes: e50, movablePreloadedConnectionNames: n10, boardObstacles: t10, connMap: this.params.connMap, layerCount: this.params.layerCount, allowBlindAndBuriedVias: this.params.allowBlindAndBuriedVias, viaToPadClearance: o10 });
return i10 && (this.stats.preloadedViaCandidateRejectionCount = Number(this.stats.preloadedViaCandidateRejectionCount ?? 0) + 1), !i10;
}
_step() {
if (this.phase === "route") {
if (this.highDensitySolver.step(), this.highDensitySolver.failed)
return this.error = this.highDensitySolver.error, void (this.failed = true);
if (!this.highDensitySolver.solved)
return;
const e50 = oee(this.highDensitySolver.routes);
return this.validateCandidateRoutes(e50) ? (this.forceImproveSolver = new vU({ nodeWithPortPoints: [this.params.nodeWithPortPoints], hdRoutes: e50, 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 = true));
}
if (this.phase === "improve") {
if (this.forceImproveSolver.step(), this.forceImproveSolver.failed)
return this.error = this.forceImproveSolver.error, void (this.failed = true);
if (!this.forceImproveSolver.solved)
return;
const e50 = this.forceImproveSolver.getOutput();
return this.validateCandidateRoutes(e50) ? (this.repairSolver = new qK({ nodeWithPortPoints: [this.params.nodeWithPortPoints], hdRoutes: e50, obstacles: this.params.obstacles, colorMap: this.params.colorMap, repairMargin: this.params.obstacleMargin, minimumTraceWidth: this.params.traceWidth, 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 = true));
}
if (this.phase === "repair") {
if (this.repairSolver.step(), this.repairSolver.failed)
return this.error = this.repairSolver.error, void (this.failed = true);
if (!this.repairSolver.solved)
return;
const e50 = this.repairSolver.getOutput();
return this.validateCandidateRoutes(e50) ? (this.activeSubSolver = null, this.phase = "done", void (this.solved = true)) : (this.stats.repairCandidateRejectionCount = Number(this.stats.repairCandidateRejectionCount ?? 0) + 1, this.error = "Pipeline9 regional repair output failed its candidate validator", void (this.failed = true));
}
}
getOutput() {
return this.repairSolver?.getOutput() ?? this.forceImproveSolver?.getOutput() ?? this.highDensitySolver.routes;
}
visualize() {
return this.repairSolver?.visualize() ?? this.forceImproveSolver?.visualize() ?? this.highDensitySolver.visualize();
}
};
var ute = (e50, t10) => ({ minX: e50.center.x - e50.width / 2 - t10, maxX: e50.center.x + e50.width / 2 + t10, minY: e50.center.y - e50.height / 2 - t10, maxY: e50.center.y + e50.height / 2 + t10 });
var pte = (e50, t10, n10, o10, i10) => {
const r10 = new Set(t10.availableZ ?? t10.portPoints.map((e54) => e54.z)), s10 = ite(e50, i10);
return s10.wireSegments.some((e54) => r10.has(e54.z) && ((e58, t11, n11, o11) => Math.min(e58.x, t11.x) - n11 <= o11.maxX && Math.max(e58.x, t11.x) + n11 >= o11.minX && Math.min(e58.y, t11.y) - n11 <= o11.maxY && Math.max(e58.y, t11.y) + n11 >= o11.minY)(e54.start, e54.end, e54.width / 2 + o10, n10)) || s10.viaSpans.some((e54) => [...r10].some((t11) => t11 >= e54.minZ && t11 <= e54.maxZ) && ((e58, t11, n11) => {
const o11 = Math.max(n11.minX - e58.x, 0, e58.x - n11.maxX), i11 = Math.max(n11.minY - e58.y, 0, e58.y - n11.maxY);
return o11 * o11 + i11 * i11 <= t11 * t11;
})(e54.center, e54.diameter / 2 + o10, n10));
};
var mte = (e50, t10) => {
const n10 = (e54) => ({ ...e54, rootConnectionName: t10.getNetConnectedToId(e54.rootConnectionName ?? e54.connectionName) ?? e54.rootConnectionName ?? e54.connectionName });
return { ...e50, portPoints: e50.portPoints.map(n10), portPointsInPairs: e50.portPointsInPairs?.map(([e54, t11]) => [n10(e54), n10(t11)]) };
};
var gte = ({ nodeWithPortPoints: e50, connMap: t10, colorMap: n10, viaDiameter: o10, traceWidth: i10, obstacleMargin: r10, effort: s10, nodePfById: a10, obstacles: c10, boardGeometry: l10, layerCount: h10 }) => new JL({ nodePortPoints: [mte(e50, t10)], colorMap: n10, connMap: t10, viaDiameter: o10, traceWidth: i10, obstacleMargin: r10, effort: s10, nodePfById: a10, obstacles: c10, layerCount: h10, useGrowShrinkHighDensityIntraNodeSolver: true, enableNegotiatedSearch: true, gridSearchSegmentWork: 500, gridSearchWorkScale: h10 > 2 ? 0.25 : 1, rejectOverlappingTerminals: h10 > 2, boardGeometry: l10, preserveTerminalPcbPortIds: false, growShrinkFallbackToInvalidGeometryOnFailure: false, captureSearchDebug: false });
var fte = class extends ai {
fixedHdRoutes;
connMap;
colorMap;
obstacles;
boardGeometry;
layerCount;
allowBlindAndBuriedVias;
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(e50) {
super(), this.fixedHdRoutes = e50.fixedHdRoutes, this.connMap = e50.connMap, this.colorMap = e50.colorMap ?? {}, this.obstacles = e50.obstacles, this.boardGeometry = e50.boardGeometry, this.layerCount = e50.layerCount, this.allowBlindAndBuriedVias = e50.allowBlindAndBuriedVias ?? false, this.viaDiameter = e50.viaDiameter, this.traceWidth = e50.traceWidth, this.obstacleMargin = e50.obstacleMargin, this.viaToPadClearance = e50.viaToPadClearance, this.effort = e50.effort, this.nodePfById = e50.nodePfById instanceof Map ? new Map(e50.nodePfById) : new Map(Object.entries(e50.nodePfById ?? {})), this.preserveTerminalPcbPortIds = e50.preserveTerminalPcbPortIds ?? false, this.includeBoardObstacles = e50.includeBoardObstacles ?? false, this.enableRegionalFallback = e50.enableRegionalFallback ?? true, this.maxB01Rips = e50.maxB01Rips, this.unsolvedNodePortPoints = [...e50.nodePortPoints], this.MAX_ITERATIONS = 1e8 * this.effort, this.stats = { nodeCount: e50.nodePortPoints.length, solvedNodeCount: 0, fixedObstacleCount: e50.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((e50) => this.removedFixedRouteConnectionNames.has(e50.connectionName) ? [] : [this.fixedRouteReplacements.get(e50.connectionName) ?? e50]);
}
finishActiveNode(e50) {
const t10 = this.activeNode ? ((e54, t11) => e54.map((e58) => ({ ...e58, rootConnectionName: t11.portPoints.find((t12) => t12.connectionName === e58.connectionName)?.rootConnectionName ?? e58.rootConnectionName })))(e50, this.activeNode) : e50;
this.routes.push(...this.preserveTerminalPcbPortIds && this.activeNode ? ((e54, t11) => {
const n10 = t11.portPoints.filter((e58) => e58.pcb_port_id !== undefined);
return e54.map((e58) => {
const t12 = e58.route[0], o10 = e58.route.at(-1), i10 = n10.find((n11) => t12 !== undefined && n11.connectionName === e58.connectionName && n11.x === t12.x && n11.y === t12.y && n11.z === t12.z), r10 = n10.find((t13) => o10 !== undefined && t13.connectionName === e58.connectionName && t13.x === o10.x && t13.y === o10.y && t13.z === o10.z);
return { ...e58, startPcbPortId: i10?.pcb_port_id, endPcbPortId: r10?.pcb_port_id };
});
})(t10, this.activeNode) : t10), 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(e50) {
this.activeNode = e50, this.activeRegularSolver = gte({ nodeWithPortPoints: e50, colorMap: this.colorMap, connMap: this.connMap, viaDiameter: this.viaDiameter, traceWidth: this.traceWidth, obstacleMargin: this.obstacleMargin, effort: this.effort, nodePfById: this.nodePfById, obstacles: this.obstacles, boardGeometry: this.boardGeometry, layerCount: this.layerCount }), this.stats.regularNodeCount = Number(this.stats.regularNodeCount ?? 0) + 1;
}
startRegionalFallback(e50 = new Set) {
if (!this.activeNode)
throw new Error("Pipeline9 cannot start a regional fallback without an active node");
const t10 = { ...mte(this.activeNode, this.connMap), availableZ: Array.from({ length: this.layerCount }, (e54, t11) => t11) }, n10 = mee(t10, this.getUpdatedFixedHdRoutes(), e50), o10 = new Set([...n10.fixedRouteSectionsByConnectionName.values()].flatMap((e54) => e54.sourceRoutes.map((e58) => e58.connectionName)));
for (const t11 of e50)
if (!o10.has(t11))
throw new Error(`Pipeline9 could not promote fixed route "${t11}" into the active regional fallback`);
const i10 = [...e50].filter((e54) => !this.activeFallbackPromotedFixedRouteConnectionNames.has(e54)).length;
this.activeFallbackFixedRouteSections = n10.fixedRouteSectionsByConnectionName, this.activeFallbackFixedObstacleRoutes = n10.fixedObstacleRoutes, this.activeFallbackPromotedFixedRouteConnectionNames = new Set(e50);
const r10 = ste({ fixedObstacleRoutes: this.activeFallbackFixedObstacleRoutes, layerCount: this.layerCount, allowBlindAndBuriedVias: this.allowBlindAndBuriedVias });
this.activeFallbackSolver = new dte({ nodeWithPortPoints: n10.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, ...r10], boardObstacles: this.obstacles, movablePreloadedConnectionNames: o10, viaToPadClearance: this.viaToPadClearance, layerCount: this.layerCount, allowBlindAndBuriedVias: this.allowBlindAndBuriedVias }), e50.size === 0 ? 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) + i10);
}
finishRegionalFallback() {
if (!this.activeFallbackSolver)
return;
if (!this.activeNode)
throw new Error("Pipeline9 cannot finish a regional fallback without an active node");
this.recordRegionalCandidateRejections();
const e50 = [], t10 = new Map;
for (const n11 of this.activeFallbackSolver.getOutput()) {
if (!this.activeFallbackFixedRouteSections.has(n11.connectionName)) {
e50.push(n11);
continue;
}
const o11 = t10.get(n11.connectionName) ?? [];
o11.push(n11), t10.set(n11.connectionName, o11);
}
const n10 = [], o10 = [];
for (const [e54, i11] of this.activeFallbackFixedRouteSections) {
const r11 = t10.get(e54) ?? [];
if (r11.length === 0) {
o10.push(i11);
continue;
}
if (r11.length > 1)
return this.error = `Pipeline9 regional fallback expected one replacement for fixed route "${e54}", got ${r11.length}`, void (this.failed = true);
const s11 = _ee({ section: i11, replacement: r11[0], sourceMutationMasks: this.preloadedTraceMutationMasks, replacementIsMutated: true });
n10.push({ connectionName: e54, section: i11, replacement: s11.route, mutatedSegments: s11.mutatedSegments, replacementProducedSegment: s11.replacementProducedSegment });
}
const i10 = [...e50, ...n10.map(({ replacement: e54 }) => e54)], r10 = [...this.activeFallbackFixedObstacleRoutes, ...o10.flatMap((e54) => e54.sourceRoutes)], s10 = ute(this.activeNode, this.obstacleMargin + Math.max(this.traceWidth, this.viaDiameter) / 2), a10 = new Map;
for (const e54 of i10)
for (const t11 of r10)
ate(e54, t11, this.connMap) || lte({ left: e54, right: t11, clearance: this.obstacleMargin, leftBounds: s10, layerCount: this.layerCount, allowBlindAndBuriedVias: this.allowBlindAndBuriedVias }) && a10.set(t11.connectionName, t11);
if (a10.size > 0) {
const e54 = [...a10.keys()], t11 = [...a10].flatMap(([e58, t12]) => t12.isThroughObstacle === true ? [] : [e58]), n11 = new Set(this.activeFallbackPromotedFixedRouteConnectionNames);
for (const e58 of t11)
n11.add(e58);
if (n11.size === this.activeFallbackPromotedFixedRouteConnectionNames.size) {
const t12 = [...a10].flatMap(([e58, t13]) => t13.isThroughObstacle === true ? [e58] : []);
return this.error = t12.length > 0 ? `Pipeline9 regional fallback conflicts with immutable through-obstacle route(s): ${t12.join(", ")}` : `Pipeline9 promoted regional fallback could not resolve immutable fixed route conflict(s): ${e54.join(", ")}`, void (this.failed = true);
}
return void this.startRegionalFallback(n11);
}
const c10 = new Map;
for (const { section: e54, replacementProducedSegment: t11 } of n10)
if (t11)
for (const t12 of e54.sourceRoutes) {
const { preloadedRoutePositionStart: e58, preloadedRoutePositionEnd: n11 } = t12;
if (e58 === undefined != (n11 === undefined))
throw new Error(`Pipeline9 fixed route "${t12.connectionName}" has incomplete route-position metadata`);
const o11 = Math.min(e58 ?? t12.preloadedRouteIndex, n11 ?? t12.preloadedRouteIndex), i11 = Math.max(e58 ?? t12.preloadedRouteIndex, n11 ?? t12.preloadedRouteIndex), r11 = c10.get(t12.preloadedTraceIndex);
c10.set(t12.preloadedTraceIndex, { start: Math.min(r11?.start ?? o11, o11), end: Math.max(r11?.end ?? i11, i11) });
}
for (const { connectionName: e54, section: t11, replacement: o11, mutatedSegments: i11 } of n10) {
this.fixedRouteReplacements.set(e54, o11), this.preloadedTraceMutationMasks.set(e54, i11);
for (const e58 of t11.sourceRoutes.slice(1))
this.removedFixedRouteConnectionNames.add(e58.connectionName), this.preloadedTraceMutationMasks.delete(e58.connectionName);
}
const l10 = mee({ ...mte(this.activeNode, this.connMap), portPoints: [], portPointsInPairs: [], availableZ: Array.from({ length: this.layerCount }, (e54, t11) => t11) }, this.getUpdatedFixedHdRoutes()), h10 = new Set;
for (const e54 of l10.fixedRouteSectionsByConnectionName.values()) {
const t11 = e54.sourceRoutes[0];
if (!t11)
continue;
const n11 = c10.get(t11.preloadedTraceIndex);
if (n11)
for (const [o11, i11] of e54.sourceRoutes.entries()) {
const r11 = i11.preloadedRoutePositionStart ?? i11.preloadedRouteIndex, s11 = i11.preloadedRoutePositionEnd ?? i11.preloadedRouteIndex, a11 = { start: Math.min(r11, s11), end: Math.max(r11, s11) }, c11 = a11.start === a11.end, l11 = n11.start === n11.end;
if (!(c11 || l11 ? a11.start <= n11.end && n11.start <= a11.end : a11.start < n11.end && n11.start < a11.end))
continue;
h10.add(t11.preloadedTraceIndex);
const d11 = [...this.preloadedTraceMutationMasks.get(i11.connectionName) ?? Array(i11.route.length - 1).fill(false)];
if (d11.length !== i11.route.length - 1)
throw new Error(`Pipeline9 fixed route mutation mask for "${i11.connectionName}" has ${d11.length} segments, expected ${i11.route.length - 1}`);
const u10 = o11 === 0 ? e54.start.segmentIndex : 0, p10 = o11 === e54.sourceRoutes.length - 1 ? e54.end.segmentIndex : i11.route.length - 2;
for (let e58 = u10;e58 <= p10; e58++)
d11[e58] = true;
this.preloadedTraceMutationMasks.set(i11.connectionName, d11);
}
}
for (const e54 of c10.keys())
if (!h10.has(e54))
throw new Error(`Pipeline9 could not capture accepted mutation provenance for trace ${e54}`);
const d10 = n10.reduce((e54, { section: t11 }) => e54 + t11.sourceRoutes.length, 0);
this.stats.reroutedFixedRouteCount = Number(this.stats.reroutedFixedRouteCount ?? 0) + d10, this.stats.reroutedFixedRouteSectionCount = Number(this.stats.reroutedFixedRouteSectionCount ?? 0) + n10.length, this.finishActiveNode(e50);
}
recordRegionalCandidateRejections() {
if (!this.activeFallbackSolver)
return;
const e50 = this.activeFallbackSolver.stats;
this.stats.regionalPreloadedViaCandidateRejectionCount = Number(this.stats.regionalPreloadedViaCandidateRejectionCount ?? 0) + Number(e50.preloadedViaCandidateRejectionCount ?? 0), this.stats.regionalForceImproveCandidateRejectionCount = Number(this.stats.regionalForceImproveCandidateRejectionCount ?? 0) + Number(e50.forceImproveCandidateRejectionCount ?? 0), this.stats.regionalRepairCandidateRejectionCount = Number(this.stats.regionalRepairCandidateRejectionCount ?? 0) + Number(e50.repairCandidateRejectionCount ?? 0);
}
finishRegularSolverFailure(e50) {
if (this.activeFallbackReason = `regular high-density routing failed: ${e50}`, this.activeRegularSolver = null, !this.enableRegionalFallback)
return this.error = `Pipeline9 ${this.activeFallbackReason}`, this.failed = true, void (this.activeNode = null);
this.startRegionalFallback();
}
_step() {
this.stepNodeRouting(), this.activeSubSolver = this.activeFallbackSolver ?? this.activeRegularSolver ?? this.activeB01Solver;
}
computeProgress() {
if (this.solved)
return 1;
const e50 = Number(this.stats.nodeCount);
if (e50 === 0)
return 0;
const t10 = Math.max(0, Math.min(1, this.activeSubSolver?.progress ?? 0));
return Math.max(this.progress, (Number(this.stats.solvedNodeCount) + t10) / e50);
}
stepNodeRouting() {
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 = true, 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 = true, void (this.activeNode = null));
if (!this.activeB01Solver.solved)
return;
return void this.finishActiveNode(this.activeB01Solver.getOutput());
}
const e50 = this.unsolvedNodePortPoints.pop();
if (!e50)
return void (this.solved = true);
const t10 = ute(e50, this.obstacleMargin), n10 = Math.max(this.traceWidth, this.viaDiameter) / 2, o10 = this.getUpdatedFixedHdRoutes().filter((o11) => pte(o11, e50, t10, n10, this)).flatMap((t11) => ((e54, t12, n11) => {
const o11 = new Set(t12.availableZ ?? t12.portPoints.map((e58) => e58.z));
if (o11.size === 0)
throw new Error(`Pipeline9 B01 node "${t12.capacityMeshNodeId}" has no available layers`);
const i11 = { type: "route", connectionName: e54.connectionName, rootConnectionName: e54.rootConnectionName, traceThickness: e54.traceThickness, viaDiameter: e54.viaDiameter }, r11 = [], s10 = ite(e54, n11);
for (const e58 of s10.wireSegments)
o11.has(e58.z) && r11.push({ ...i11, traceThickness: e58.width, route: [e58.start, e58.end], vias: [] });
for (const e58 of s10.viaSpans)
[...o11].some((t13) => t13 >= e58.minZ && t13 <= e58.maxZ) && r11.push({ ...i11, viaDiameter: e58.diameter, route: [{ ...e58.center, z: e58.minZ }, { ...e58.center, z: e58.maxZ }], vias: [{ ...e58.center, zStart: e58.minZ, zEnd: e58.maxZ }] });
return r11;
})(t11, e50, this));
if (this.stats.fixedObstacleUses = Number(this.stats.fixedObstacleUses ?? 0) + o10.length, o10.length === 0)
return void this.startRegularSolver(e50);
const i10 = (this.includeBoardObstacles ? this.obstacles : []).filter((e54) => ((e58, t11) => {
const n11 = (e58.ccwRotationDegrees ?? 0) * Math.PI / 180, o11 = Math.abs(Math.cos(n11)), i11 = Math.abs(Math.sin(n11)), r11 = e58.width / 2 * o11 + e58.height / 2 * i11, s10 = e58.width / 2 * i11 + e58.height / 2 * o11;
return e58.center.x - r11 <= t11.maxX && e58.center.x + r11 >= t11.minX && e58.center.y - s10 <= t11.maxY && e58.center.y + s10 >= t11.minY;
})(e54, t10)).map((t11) => (({ obstacle: e54, node: t12, connMap: n11, layerCount: o11 }) => {
const i11 = new Set(t12.availableZ ?? t12.portPoints.map((e58) => e58.z)), r11 = (e54.zLayers ?? e54.layers.map((e58) => go(e58, o11))).filter((e58) => i11.has(e58));
if (r11.length === 0)
return;
const s10 = e54.connectedTo[0] ?? e54.obstacleId ?? `pipeline9_obstacle_${e54.center.x}_${e54.center.y}`;
return { type: "rect", connectionName: s10, rootConnectionName: n11.getNetConnectedToId(s10) ?? s10, center: e54.center, width: e54.width, height: e54.height, ccwRotationDegrees: e54.ccwRotationDegrees, zLayers: r11 };
})({ obstacle: t11, node: e50, connMap: this.connMap, layerCount: this.layerCount })).filter((e54) => e54 !== undefined);
if (this.stats.boardObstacleUses = Number(this.stats.boardObstacleUses ?? 0) + i10.length, this.activeNode = e50, e50.width > 15 || e50.height > 15)
return this.activeFallbackReason = `B01 node "${e50.capacityMeshNodeId}" exceeds the 15x15mm routing limit (${e50.width}x${e50.height}mm)`, void this.startRegionalFallback();
const r10 = mte(e50, this.connMap);
this.stats.b01NodeCount = Number(this.stats.b01NodeCount ?? 0) + 1, this.activeB01Solver = new nte({ ...Oee, nodeWithPortPoints: r10, obstacles: [...o10, ...i10], viaDiameter: this.viaDiameter, viaMinDistFromBorder: this.viaDiameter / 2, traceThickness: this.traceWidth, traceMargin: this.obstacleMargin, obstacleClearanceMargin: 0.15, effort: this.effort }), this.maxB01Rips !== undefined && (this.activeB01Solver.MAX_RIPS = this.maxB01Rips);
}
visualize() {
return this.activeFallbackSolver?.visualize() ?? this.activeRegularSolver?.visualize() ?? this.activeB01Solver?.visualize() ?? { lines: this.routes.flatMap((e50) => e50.route.slice(0, -1).map((t10, n10) => ({ points: [t10, e50.route[n10 + 1]], strokeWidth: e50.traceThickness, layer: `z${t10.z}`, label: e50.connectionName }))), points: [], rects: [], circles: [] };
}
};
var _te = (e50, t10) => {
const n10 = e50({ hdRoutes: t10, traces: [] });
return Array.isArray(n10) ? n10 : n10.errorsWithCenters ?? n10.errors;
};
var yte = (e50) => {
const t10 = typeof e50.pcb_trace_id == "string" ? e50.pcb_trace_id : undefined, n10 = Array.isArray(e50.pcb_trace_ids) ? e50.pcb_trace_ids.filter((e54) => typeof e54 == "string") : [], o10 = [...typeof e50.pcb_via_id == "string" ? [e50.pcb_via_id] : [], ...Array.isArray(e50.pcb_via_ids) ? e50.pcb_via_ids : []].filter((e54) => typeof e54 == "string"), i10 = t10 ? `overlap_${t10}_` : undefined, r10 = i10 && typeof e50.pcb_trace_error_id == "string" && e50.pcb_trace_error_id.startsWith(i10) ? e50.pcb_trace_error_id.slice(i10.length) : undefined;
if (n10.length > 0) {
const e54 = t10 && !n10.includes(t10) ? [t10, ...n10] : [...n10];
return e54.length < 2 && r10 && !o10.includes(r10) && e54.push(r10), e54;
}
return [t10, r10].filter((e54) => typeof e54 == "string" && !o10.includes(e54));
};
var bte = (e50) => yte(e50).filter((e54, t10, n10) => n10.indexOf(e54) === t10);
var xte = (e50) => e50.reduce((e54, t10) => {
if (typeof t10.actual_clearance == "number" && typeof t10.minimum_clearance == "number")
return e54 + Math.max(0, t10.minimum_clearance - t10.actual_clearance);
const n10 = (typeof t10.message == "string" ? t10.message : "").match(/gap: (-?\d+(?:\.\d+)?)mm/);
return n10 ? e54 + Math.max(0, 0.1 - Number.parseFloat(n10[1])) : e54 + 1;
}, 0);
var vte = (e50, t10) => e50.length < t10.length || e50.length === t10.length && xte(e50) < xte(t10) - 0.000000001;
var Ite = ({ routes: e50, newConnections: t10, syntheticConnectionNames: n10 }) => {
const o10 = new Set([...t10.map((e54) => e54.name), ...n10]), i10 = new Map, r10 = new Map;
for (let t11 = 0;t11 < e50.length; t11++) {
const n11 = e50[t11];
if (!o10.has(n11.connectionName))
continue;
const s10 = i10.get(n11.connectionName) ?? 0;
i10.set(n11.connectionName, s10 + 1), r10.set(`${n11.connectionName}_${s10}`, t11);
}
return r10;
};
var Ste = 0.01;
var Cte = [0.03, 0.1, 0.25];
var Pte = (e50) => {
let t10 = 0;
for (const n10 of e50) {
if (typeof n10.actual_clearance != "number" || !Number.isFinite(n10.actual_clearance) || typeof n10.minimum_clearance != "number" || !Number.isFinite(n10.minimum_clearance))
return;
if (t10 += Math.max(0, n10.minimum_clearance - n10.actual_clearance), !Number.isFinite(t10))
return;
}
return t10;
};
var Mte = ({ errors: e50, errorsWithCenters: t10, routeIndexByTraceId: n10, padPositionById: o10 }) => {
const i10 = [];
let r10 = 0;
for (const s10 of e50) {
const e54 = s10.type === "pcb_via_trace_clearance_error", a10 = s10.type === "pcb_pad_trace_clearance_error";
if (!e54 && !a10 || typeof s10.pcb_trace_id != "string" || !n10.has(s10.pcb_trace_id) || typeof s10.actual_clearance != "number" || !Number.isFinite(s10.actual_clearance) || typeof s10.minimum_clearance != "number" || !Number.isFinite(s10.minimum_clearance))
return;
const c10 = bte(s10);
if (e54 && c10.length < 2 || c10.some((e58) => !n10.has(e58)))
return;
const l10 = t10.find((e58) => e58.type === s10.type && e58.pcb_trace_id === s10.pcb_trace_id && e58.pcb_pad_id === s10.pcb_pad_id && e58.pcb_via_id === s10.pcb_via_id), h10 = a10 ? typeof s10.pcb_pad_id == "string" ? o10.get(s10.pcb_pad_id) : undefined : l10?.center ?? s10.center;
if (!h10 || typeof h10 != "object")
return;
if (!(("x" in h10) && ("y" in h10) && typeof h10.x == "number" && Number.isFinite(h10.x) && typeof h10.y == "number" && Number.isFinite(h10.y)))
return;
const d10 = { ...s10, pcb_trace_id: s10.pcb_trace_id, actual_clearance: s10.actual_clearance, minimum_clearance: s10.minimum_clearance, center: { x: h10.x, y: h10.y } };
if (e54) {
if (typeof s10.pcb_via_id != "string")
return;
i10.push({ ...d10, type: "pcb_via_trace_clearance_error", pcb_via_id: s10.pcb_via_id, pcb_pad_id: undefined });
} else {
if (typeof s10.pcb_pad_id != "string")
return;
i10.push({ ...d10, type: "pcb_pad_trace_clearance_error", pcb_pad_id: s10.pcb_pad_id, pcb_via_id: undefined });
}
if (r10 += Math.max(0, s10.minimum_clearance - s10.actual_clearance), !Number.isFinite(r10))
return;
}
return { errors: i10, deficit: r10 };
};
var wte = { maxRegions: 4, maxCandidateAttempts: 1024, maxPathSearchNodes: 480000 };
var Nte = (e50, t10) => ({ maxRegions: Math.min(e50.maxRegions, (e50.initialMaxRegions ?? e50.maxRegions) + t10 * (e50.regionsPerAcceptedRepair ?? 0)), maxCandidateAttempts: Math.min(e50.maxCandidateAttempts, (e50.initialMaxCandidateAttempts ?? e50.maxCandidateAttempts) + t10 * (e50.candidateAttemptsPerAcceptedRepair ?? 0)), maxPathSearchNodes: Math.min(e50.maxPathSearchNodes, (e50.initialMaxPathSearchNodes ?? e50.maxPathSearchNodes) + t10 * (e50.pathSearchNodesPerAcceptedRepair ?? 0)) });
var Tte = [3, 4, 5, 6, 8];
var Rte = ({ error: e50, routeIndexByTraceId: t10 }) => {
const n10 = typeof e50.pcb_trace_id == "string" ? e50.pcb_trace_id : undefined, o10 = [...typeof e50.pcb_via_id == "string" ? [e50.pcb_via_id] : [], ...Array.isArray(e50.pcb_via_ids) ? e50.pcb_via_ids.filter((e54) => typeof e54 == "string") : []], i10 = n10 ? `overlap_${n10}_` : undefined, r10 = i10 && typeof e50.pcb_trace_error_id == "string" && e50.pcb_trace_error_id.startsWith(i10) ? e50.pcb_trace_error_id.slice(i10.length) : undefined, s10 = r10 !== undefined && o10.includes(r10);
return [n10, ...Array.isArray(e50.pcb_trace_ids) ? e50.pcb_trace_ids : [], s10 ? undefined : r10].filter((e54) => typeof e54 == "string" && t10.has(e54)).filter((e54, t11, n11) => n11.indexOf(e54) === t11);
};
var Ete = (e50) => e50.filter((e54) => e54.type === "pcb_via_clearance_error" || Array.isArray(e54.pcb_via_ids)).length;
var Ate = (e50, t10) => {
const n10 = new Map;
for (const t11 of e50)
n10.set(t11.connectionName, (n10.get(t11.connectionName) ?? 0) + 1);
return e50.map((e54, o10) => {
const i10 = n10.get(e54.connectionName) > 1 ? `${e54.connectionName}_regional_${o10}` : e54.connectionName;
return i10 !== e54.connectionName && t10.addConnections([[i10, e54.connectionName, e54.rootConnectionName ?? e54.connectionName]]), { ...e54, connectionName: i10, preloadedTraceId: `pipeline9_joint_candidate_${o10}`, preloadedTraceIndex: o10, preloadedRouteIndex: 0, isThroughObstacle: false };
});
};
var Ote = (e50, t10) => e50.minX <= t10.maxX && e50.maxX >= t10.minX && e50.minY <= t10.maxY && e50.maxY >= t10.minY;
var kte = (e50) => ({ minX: e50.center.x - e50.diameter / 2, maxX: e50.center.x + e50.diameter / 2, minY: e50.center.y - e50.diameter / 2, maxY: e50.center.y + e50.diameter / 2 });
var Dte = (e50) => ({ minX: e50.center.x - e50.width / 2, maxX: e50.center.x + e50.width / 2, minY: e50.center.y - e50.height / 2, maxY: e50.center.y + e50.height / 2 });
var Lte = (e50, t10, n10) => {
const o10 = ite(e50, n10);
return o10.wireSegments.some((e54) => Ote(((e58) => ({ minX: Math.min(e58.start.x, e58.end.x) - e58.width / 2, maxX: Math.max(e58.start.x, e58.end.x) + e58.width / 2, minY: Math.min(e58.start.y, e58.end.y) - e58.width / 2, maxY: Math.max(e58.start.y, e58.end.y) + e58.width / 2 }))(e54), t10)) || o10.viaSpans.some((e54) => Ote(kte(e54), t10));
};
var zte = ({ routes: e50, fixedRouteCopperSpatialIndex: t10, center: n10, regionSize: o10, srj: i10, connMap: r10, colorMap: s10, viaDiameter: a10, traceWidth: c10, obstacleMargin: l10, effort: h10 }) => {
const d10 = Ate(e50, r10), u10 = { capacityMeshNodeId: "pipeline9_joint_drc_regular_fallback", center: n10, width: o10, height: o10, availableZ: Array.from({ length: i10.layerCount }, (e54, t11) => t11), portPoints: [], portPointsInPairs: [] }, p10 = mee(u10, d10);
if (p10.fixedRouteSectionsByConnectionName.size === 0)
return;
if (!((e54) => {
const t11 = aee(e54);
return e54.portPoints.every((e58) => Ds({ point: e58, bounds: t11 }) === "on-boundary");
})(p10.nodeWithPortPoints))
return;
const m10 = [...p10.fixedRouteSectionsByConnectionName.values()].flatMap((e54) => e54.sourceRoutes).reduce((e54, t11) => {
const n11 = ite(t11, i10);
return Math.max(e54, t11.viaDiameter / 2, ...n11.wireSegments.map((e58) => e58.width / 2), ...n11.viaSpans.map((e58) => e58.diameter / 2));
}, Math.max(c10 / 2, a10 / 2)), g10 = { minX: n10.x - o10 / 2 - l10 - m10, maxX: n10.x + o10 / 2 + l10 + m10, minY: n10.y - o10 / 2 - l10 - m10, maxY: n10.y + o10 / 2 + l10 + m10 }, f10 = t10.getRoutesOverlappingBounds(g10), _10 = ste({ fixedObstacleRoutes: f10, layerCount: i10.layerCount, allowBlindAndBuriedVias: i10.allowBlindAndBuriedVias });
return { solver: new dte({ nodeWithPortPoints: p10.nodeWithPortPoints, colorMap: s10, connMap: r10, viaDiameter: a10, traceWidth: c10, obstacleMargin: l10, effort: h10, obstacles: [...i10.obstacles, ..._10], layerCount: i10.layerCount, allowBlindAndBuriedVias: i10.allowBlindAndBuriedVias }), routes: e50, regionalRoutes: d10, problem: p10, candidateBounds: g10, localFixedObstacleRoutes: f10, obstacleMargin: l10, connMap: r10, srj: i10 };
};
var Bte = ({ solver: e50, routes: t10, regionalRoutes: n10, problem: o10, candidateBounds: i10, localFixedObstacleRoutes: r10, obstacleMargin: s10, connMap: a10, srj: c10 }) => {
if (!e50.solved || e50.failed)
return;
const l10 = e50.getOutput(), h10 = new Map(l10.map((e54) => [e54.connectionName, e54])), d10 = new Map, u10 = new Set;
for (const [e54, t11] of o10.fixedRouteSectionsByConnectionName) {
const n11 = h10.get(e54);
if (!n11)
return;
d10.set(t11.sourceRoutes[0].preloadedTraceIndex, fee(t11, n11));
for (const e58 of t11.sourceRoutes.slice(1))
u10.add(e58.preloadedTraceIndex);
}
const p10 = n10.flatMap((e54, n11) => u10.has(n11) ? [] : [{ ...d10.get(n11) ?? e54, connectionName: t10[n11].connectionName }]);
return (({ candidateRoutes: e54, fixedObstacleRoutes: t11, obstacleMargin: n11, connMap: o11, candidateBounds: i11, srj: r11 }) => {
for (const s11 of e54)
for (const e58 of t11)
if (!ate(s11, e58, o11) && lte({ left: s11, right: e58, clearance: n11, leftBounds: i11, layerCount: r11.layerCount, allowBlindAndBuriedVias: r11.allowBlindAndBuriedVias }))
return true;
return false;
})({ candidateRoutes: p10, fixedObstacleRoutes: r10, obstacleMargin: s10, connMap: a10, candidateBounds: i10, srj: c10 }) ? undefined : p10;
};
var Fte = class extends ai {
params;
candidateSearchBudget;
phase = "initialize";
result;
currentRoutes;
currentErrors = [];
bestRoutes;
bestErrors = [];
fixedRouteCopperSpatialIndex;
routeIndexByTraceId = new Map;
repairableErrors = [];
passIndex = 0;
errorIndex = 0;
traceIndex = 0;
regionIndex = 0;
traceIds = [];
repairCenter;
stopB01SearchForError = false;
acceptedOnPass = false;
attemptedCandidateCount = 0;
acceptedCandidateCount = 0;
fallbackCandidateCount = 0;
candidateSearchCount = 0;
candidateSearchBudgetExhausted = false;
safeTraceLayerRepairSkippedForBudget = false;
preloadEligibleDrcIssueCount = 0;
b01Candidate;
regularCandidate;
safeTraceLayerSolver;
constructor(e50) {
super(), this.params = e50, this.currentRoutes = e50.routes, this.bestRoutes = e50.routes, this.candidateSearchBudget = ((e54) => {
if (!Number.isInteger(e54) || e54 < 0)
throw new Error("Pipeline9 regional repair route count must be nonnegative");
const t10 = Math.floor(7000 / Math.max(1, e54));
return Math.max(16, Math.min(192, t10));
})(e50.routes.length), this.MAX_ITERATIONS = 64 + 8 * this.candidateSearchBudget;
}
initializeRepair() {
const { initialErrors: e50, drcEvaluator: t10, newConnections: n10, syntheticConnectionNames: o10 } = this.params;
this.currentErrors = e50 ?? _te(t10, this.currentRoutes), this.MAX_ITERATIONS += 16 * this.currentErrors.length, this.preloadEligibleDrcIssueCount = this.currentErrors.filter((e54) => (({ error: e58, preloadRepairTraceIds: t11 }) => !!yte(e58).some((e59) => t11.has(e59)) || (e58.__collapsed_trace_participants ?? []).flatMap((e59) => new Set(e59.evaluationTraceIds).size > 1 ? [e59.solverTraceId] : []).some((e59) => t11.collidingFixedTraceIds?.has(e59)))({ error: e54, preloadRepairTraceIds: this.params.preloadRepairTraceIds })).length;
const i10 = Ite({ routes: this.currentRoutes, newConnections: n10, syntheticConnectionNames: o10 }), r10 = this.params.allowTracePairRepair === true && this.currentErrors.some((e54) => ((e58, t11) => !(e58.type !== "pcb_trace_error" || typeof e58.pcb_via_id == "string" || Array.isArray(e58.pcb_via_ids) && e58.pcb_via_ids.length > 0) && Rte({ error: e58, routeIndexByTraceId: t11 }).length === 2)(e54, i10));
this.preloadEligibleDrcIssueCount !== 0 || r10 ? (this.fixedRouteCopperSpatialIndex = ((e54, t11) => {
const n11 = new Map, o11 = (e58, t12) => {
const o12 = Math.floor(t12.minX / 4), i11 = Math.floor(t12.maxX / 4), r11 = Math.floor(t12.minY / 4), s10 = Math.floor(t12.maxY / 4);
for (let t13 = o12;t13 <= i11; t13++)
for (let o13 = r11;o13 <= s10; o13++) {
const i12 = `${t13}:${o13}`, r12 = n11.get(i12) ?? new Set;
r12.add(e58), n11.set(i12, r12);
}
};
for (let n12 = 0;n12 < e54.length; n12++) {
const i11 = ite(e54[n12], t11);
for (const e58 of i11.wireSegments)
for (const t12 of rte(e58, 4, 1))
o11(n12, Dte(t12));
for (const e58 of i11.viaSpans)
o11(n12, kte(e58));
}
return { getRoutesOverlappingBounds: (o12) => {
const i11 = new Set, r11 = Math.floor(o12.minX / 4), s10 = Math.floor(o12.maxX / 4), a10 = Math.floor(o12.minY / 4), c10 = Math.floor(o12.maxY / 4);
for (let e58 = r11;e58 <= s10; e58++)
for (let t12 = a10;t12 <= c10; t12++)
for (const o13 of n11.get(`${e58}:${t12}`) ?? [])
i11.add(o13);
return [...i11].sort((e58, t12) => e58 - t12).map((t12) => e54[t12]).filter((e58) => Lte(e58, o12, t11));
} };
})(this.params.fixedObstacleRoutes, this.params.srj), this.phase = "begin-pass") : this.finishRepair();
}
beginPass() {
this.candidateSearchBudgetExhausted || this.passIndex >= 2 ? this.phase = "refine" : (this.acceptedOnPass = false, this.routeIndexByTraceId = Ite({ routes: this.currentRoutes, newConnections: this.params.newConnections, syntheticConnectionNames: this.params.syntheticConnectionNames }), this.repairableErrors = this.currentErrors.filter((e50) => (e50.type === "pcb_trace_error" || e50.type === "pcb_pad_trace_clearance_error" || e50.type === "pcb_via_trace_clearance_error" || e50.type === "pcb_via_clearance_error") && typeof e50.pcb_trace_id == "string"), this.errorIndex = 0, this.phase = "begin-error");
}
beginError() {
if (this.candidateSearchBudgetExhausted || this.errorIndex >= this.repairableErrors.length)
return void (this.phase = "finish-pass");
const e50 = this.repairableErrors[this.errorIndex];
this.repairCenter = ((e54, t10) => {
const n10 = typeof e54.pcb_pad_id == "string" ? e54.pcb_pad_id : typeof e54.pcb_trace_error_id == "string" ? e54.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\d+)$/)?.[1] : undefined;
if (n10) {
const e58 = t10.obstacles.find((e59) => e59.obstacleId === n10 || e59.connectedTo[0] === n10);
if (e58)
return e58.center;
}
return ((e58) => {
const t11 = e58.center;
return t11 && typeof t11 == "object" && "x" in t11 && "y" in t11 && typeof t11.x == "number" && typeof t11.y == "number" ? { x: t11.x, y: t11.y } : undefined;
})(e54);
})(e50, this.params.srj), this.traceIds = Rte({ error: e50, routeIndexByTraceId: this.routeIndexByTraceId }).slice(0, 2), this.repairCenter ? (this.bestRoutes = this.currentRoutes, this.bestErrors = this.currentErrors, this.traceIndex = 0, this.regionIndex = 0, this.stopB01SearchForError = false, this.phase = "prepare-b01") : this.errorIndex++;
}
startChildSolver(e50) {
const t10 = Math.floor(e50.MAX_ITERATIONS) + 1;
if (!Number.isSafeInteger(t10) || t10 < 1)
throw new Error("Regional B01 child has an invalid iteration limit");
this.MAX_ITERATIONS += t10, this.activeSubSolver = e50;
}
prepareB01Candidate() {
if (this.stopB01SearchForError || this.candidateSearchBudgetExhausted || this.traceIndex >= this.traceIds.length)
return void (this.phase = "prepare-regional");
const e50 = this.routeIndexByTraceId.get(this.traceIds[this.traceIndex]);
if (e50 === undefined)
return this.traceIndex++, void (this.regionIndex = 0);
if (this.regionIndex >= Tte.length)
return void (this.bestErrors.length === 0 ? this.stopB01SearchForError = true : (this.traceIndex++, this.regionIndex = 0));
if (this.candidateSearchCount >= this.candidateSearchBudget)
return this.candidateSearchBudgetExhausted = true, void (this.phase = "prepare-regional");
const t10 = this.repairCenter;
if (!t10)
throw new Error("Regional B01 candidate has no repair center");
const n10 = Tte[this.regionIndex];
this.regionIndex++, this.candidateSearchCount++, this.b01Candidate = (({ routes: e54, fixedObstacleRoutes: t11, routeIndex: n11, center: o10, regionSize: i10, srj: r10, connMap: s10, colorMap: a10, viaDiameter: c10, traceWidth: l10, obstacleMargin: h10, effort: d10 }) => {
const u10 = Ate(e54, s10), p10 = u10[n11];
if (!p10)
return;
const m10 = { capacityMeshNodeId: `pipeline9_joint_drc_${n11}_${i10}`, center: o10, width: i10, height: i10, availableZ: Array.from({ length: r10.layerCount }, (e58, t12) => t12), portPoints: [], portPointsInPairs: [] }, g10 = mee(m10, [p10]), f10 = g10.fixedRouteSectionsByConnectionName.get(p10.connectionName);
if (!f10)
return;
const _10 = u10.filter((e58, t12) => t12 !== n11);
return { solver: new fte({ nodePortPoints: [g10.nodeWithPortPoints], fixedHdRoutes: [..._10, ...t11].map((e58) => ({ ...e58, rootConnectionName: s10.getNetConnectedToId(e58.rootConnectionName ?? e58.connectionName) ?? e58.rootConnectionName ?? e58.connectionName })), connMap: s10, colorMap: a10, obstacles: r10.obstacles, layerCount: r10.layerCount, allowBlindAndBuriedVias: r10.allowBlindAndBuriedVias, viaDiameter: c10, traceWidth: l10, obstacleMargin: h10, effort: d10, preserveTerminalPcbPortIds: true, includeBoardObstacles: true, enableRegionalFallback: false, maxB01Rips: 120 }), routes: e54, movableRoute: p10, movableSection: f10, routeIndex: n11 };
})({ ...this.params, routes: this.currentRoutes, routeIndex: e50, center: t10, regionSize: n10 }), this.b01Candidate && (this.startChildSolver(this.b01Candidate.solver), this.phase = "route-b01");
}
stepB01Candidate() {
const e50 = this.b01Candidate;
if (!e50)
throw new Error("Regional B01 has no active candidate");
e50.solver.step(), (e50.solver.solved || e50.solver.failed) && (this.activeSubSolver = null, this.phase = "validate-b01");
}
validateB01Candidate() {
const e50 = this.b01Candidate;
if (!e50)
throw new Error("Regional B01 has no completed candidate");
const t10 = (({ solver: e54, routes: t11, movableRoute: n10, movableSection: o10, routeIndex: i10 }) => {
if (!e54.solved || e54.failed)
return;
const r10 = e54.routes.find((e58) => e58.connectionName === n10.connectionName);
return r10 ? { routes: t11.map((e58, t12) => t12 === i10 ? { ...fee(o10, r10), connectionName: e58.connectionName } : e58), usedFallback: Number(e54.stats.fallbackNodeCount ?? 0) > 0 } : undefined;
})(e50);
if (this.b01Candidate = undefined, t10) {
this.attemptedCandidateCount++, t10.usedFallback && this.fallbackCandidateCount++;
const e54 = _te(this.params.drcEvaluator, t10.routes);
vte(e54, this.bestErrors) && (this.bestRoutes = t10.routes, this.bestErrors = e54), this.bestErrors.length === 0 && (this.stopB01SearchForError = true);
}
this.phase = "prepare-b01";
}
prepareRegularCandidate() {
if (this.bestRoutes !== this.currentRoutes || this.candidateSearchBudgetExhausted)
return void (this.phase = "commit-error");
if (this.candidateSearchCount >= this.candidateSearchBudget)
return this.candidateSearchBudgetExhausted = true, void (this.phase = "commit-error");
this.candidateSearchCount++;
const e50 = this.repairCenter, t10 = this.fixedRouteCopperSpatialIndex;
if (!e50 || !t10)
throw new Error("Regional fallback candidate is missing its fixed context");
this.regularCandidate = zte({ ...this.params, routes: this.currentRoutes, fixedRouteCopperSpatialIndex: t10, center: e50, regionSize: 3 }), this.regularCandidate ? (this.startChildSolver(this.regularCandidate.solver), this.phase = "route-regional") : this.phase = "commit-error";
}
stepRegularCandidate() {
const e50 = this.regularCandidate;
if (!e50)
throw new Error("Regional fallback has no active candidate");
e50.solver.step(), (e50.solver.solved || e50.solver.failed) && (this.activeSubSolver = null, this.phase = "validate-regional");
}
validateRegularCandidate() {
const e50 = this.regularCandidate;
if (!e50)
throw new Error("Regional fallback has no completed candidate");
const t10 = Bte(e50);
if (this.regularCandidate = undefined, t10) {
this.attemptedCandidateCount++, this.fallbackCandidateCount++;
const e54 = _te(this.params.drcEvaluator, t10);
vte(e54, this.bestErrors) && (this.bestRoutes = t10, this.bestErrors = e54);
}
this.phase = "commit-error";
}
commitErrorRepair() {
this.bestRoutes !== this.currentRoutes && (this.currentRoutes = this.bestRoutes, this.currentErrors = this.bestErrors, this.acceptedCandidateCount++, this.acceptedOnPass = true), this.errorIndex++, this.phase = this.candidateSearchBudgetExhausted ? "finish-pass" : "begin-error";
}
finishPass() {
this.passIndex++, this.phase = !this.acceptedOnPass || this.currentErrors.length === 0 || this.candidateSearchBudgetExhausted ? "refine" : "begin-pass";
}
refineAcceptedRoutes() {
if (this.acceptedCandidateCount > 0 && this.currentErrors.length > 0) {
const e50 = Wk({ ...this.params.srj}, this.currentRoutes, this.params.effort, 1, this.params.connMap);
if (e50 !== this.currentRoutes) {
const t10 = _te(this.params.drcEvaluator, e50);
Ete(t10) <= Ete(this.currentErrors) && vte(t10, this.currentErrors) && (this.currentRoutes = e50, this.currentErrors = t10);
}
}
this.phase = "prepare-safe-layer";
}
prepareSafeLayerRepair() {
const e50 = this.currentErrors.some((e54) => e54.type === "pcb_trace_error" || e54.type === "pcb_pad_trace_clearance_error");
this.safeTraceLayerRepairSkippedForBudget = e50 && this.candidateSearchBudgetExhausted, e50 && !this.candidateSearchBudgetExhausted ? (this.safeTraceLayerSolver = new uL({ srj: { ...this.params.srj, traces: undefined }, hdRoutes: this.currentRoutes, connMap: this.params.connMap, effort: this.params.effort, drcEvaluator: this.params.drcEvaluator, maxIterations: 8, enableLargeBoardBroadFallback: false, enableTargetedErrorSweep: false, enablePostSolveClearanceRelaxation: false, enableSafeTraceLayerMoves: true, enableViaInPadLayerMoves: false }), this.startChildSolver(this.safeTraceLayerSolver), this.phase = "route-safe-layer") : this.finishRepair();
}
stepSafeLayerRepair() {
const e50 = this.safeTraceLayerSolver;
if (!e50)
throw new Error("Regional B01 has no safe trace-layer solver");
if (e50.step(), e50.failed)
throw new Error(`Pipeline9 post-regional safe trace-layer repair failed: ${e50.error ?? "unknown error"}`);
e50.solved && (this.activeSubSolver = null, this.phase = "validate-safe-layer");
}
validateSafeLayerRepair() {
const e50 = this.safeTraceLayerSolver;
if (!e50)
throw new Error("Regional B01 has no completed safe trace-layer solver");
const t10 = e50.getOutput(), n10 = _te(this.params.drcEvaluator, t10);
vte(n10, this.currentErrors) && (this.currentRoutes = t10, this.currentErrors = n10), this.safeTraceLayerSolver = undefined, this.finishRepair();
}
finishRepair() {
this.result = { routes: this.currentRoutes, attemptedCandidateCount: this.attemptedCandidateCount, acceptedCandidateCount: this.acceptedCandidateCount, fallbackCandidateCount: this.fallbackCandidateCount, candidateSearchCount: this.candidateSearchCount, candidateSearchBudget: this.candidateSearchBudget, candidateSearchBudgetExhausted: this.candidateSearchBudgetExhausted, safeTraceLayerRepairSkippedForBudget: this.safeTraceLayerRepairSkippedForBudget, remainingDrcIssueCount: this.currentErrors.length, preloadEligibleDrcIssueCount: this.preloadEligibleDrcIssueCount, preloadRepairAttempted: this.preloadEligibleDrcIssueCount > 0 }, this.activeSubSolver = null, this.stats = { ...this.result, routes: undefined }, this.phase = "done", this.solved = true;
}
_step() {
switch (this.phase) {
case "initialize":
return this.initializeRepair();
case "begin-pass":
return this.beginPass();
case "begin-error":
return this.beginError();
case "prepare-b01":
return this.prepareB01Candidate();
case "route-b01":
return this.stepB01Candidate();
case "validate-b01":
return this.validateB01Candidate();
case "prepare-regional":
return this.prepareRegularCandidate();
case "route-regional":
return this.stepRegularCandidate();
case "validate-regional":
return this.validateRegularCandidate();
case "commit-error":
return this.commitErrorRepair();
case "finish-pass":
return this.finishPass();
case "refine":
return this.refineAcceptedRoutes();
case "prepare-safe-layer":
return this.prepareSafeLayerRepair();
case "route-safe-layer":
return this.stepSafeLayerRepair();
case "validate-safe-layer":
return this.validateSafeLayerRepair();
case "done":
throw new Error("Regional B01 repair was stepped after completion");
}
}
computeProgress() {
if (this.solved)
return 1;
const e50 = this.activeSubSolver ? Math.max(0, Math.min(1, this.activeSubSolver.progress)) : 1;
return Math.max(this.progress, Math.min(1, (Math.max(0, this.candidateSearchCount - 1) + e50) / (this.candidateSearchBudget + 1)));
}
getResult() {
if (!this.solved || this.failed || !this.result)
throw new Error("Pipeline9 regional B01 repair is not complete");
return this.result;
}
};
var jte = (e50) => ((e54) => {
const t10 = typeof e54.pcb_trace_id == "string" ? e54.pcb_trace_id : undefined, n10 = Array.isArray(e54.pcb_trace_ids) ? e54.pcb_trace_ids.filter((e58) => typeof e58 == "string") : [], o10 = [...typeof e54.pcb_via_id == "string" ? [e54.pcb_via_id] : [], ...Array.isArray(e54.pcb_via_ids) ? e54.pcb_via_ids : []].filter((e58) => typeof e58 == "string"), i10 = t10 ? `overlap_${t10}_` : undefined, r10 = i10 && typeof e54.pcb_trace_error_id == "string" && e54.pcb_trace_error_id.startsWith(i10) ? e54.pcb_trace_error_id.slice(i10.length) : undefined;
if (n10.length > 0) {
const e58 = t10 && !n10.includes(t10) ? [t10, ...n10] : [...n10];
return e58.length < 2 && r10 && !o10.includes(r10) && e58.push(r10), e58;
}
return [t10, r10].filter((e58) => typeof e58 == "string" && !o10.includes(e58));
})(e50).filter((e54, t10, n10) => n10.indexOf(e54) === t10);
var $te = (e50, t10) => {
const n10 = [...new Set(t10.flatMap(jte))];
return e50.map((e54) => {
if (e54.jumpers?.length || !n10.some((t12) => t12 === e54.connectionName || t12.startsWith(`${e54.connectionName}_`)))
return e54;
const t11 = e54.route.flatMap((t12, n11) => {
const o10 = e54.route[n11 + 1];
if (!o10 || t12.z !== o10.z || t12.toNextSegmentType || t12.insideJumperPad || o10.insideJumperPad || (t12.traceThickness ?? e54.traceThickness) !== (o10.traceThickness ?? e54.traceThickness))
return [t12];
const i10 = Math.min(32, Math.ceil(((e58, t13) => {
const n12 = Math.max(Math.abs(e58), Math.abs(t13));
if (n12 === 0 || n12 === Number.POSITIVE_INFINITY)
return n12;
const o11 = e58 / n12, i11 = t13 / n12;
return n12 * Math.sqrt(o11 * o11 + i11 * i11);
})(o10.x - t12.x, o10.y - t12.y) / 0.25));
return [t12, ...Array.from({ length: Math.max(0, i10 - 1) }, (e58, n12) => ({ x: t12.x + (o10.x - t12.x) * (n12 + 1) / i10, y: t12.y + (o10.y - t12.y) * (n12 + 1) / i10, z: t12.z, traceThickness: t12.traceThickness }))];
});
return t11.length === e54.route.length ? e54 : { ...e54, route: t11 };
});
};
var Yte = class extends ai {
params;
state = { phase: "initialize" };
constructor(e50) {
super(), this.params = e50;
}
_step() {
const e50 = this.state, t10 = this.params;
if (e50.phase === "initialize") {
const e54 = t10.drcEvaluator({ traces: [], routes: t10.routes, hdRoutes: t10.routes }), n11 = Array.isArray(e54) ? e54 : e54.errors;
if (n11.length === 0)
return this.state = { phase: "finished", output: t10.routes }, void (this.solved = true);
const o11 = { ...O0(t10.originalSrj), traces: undefined }, i11 = iee(t10.routes), r11 = t10.subdivideSegments ? $te(i11, n11) : i11, s11 = new Z_({ srj: o11, routes: r11, bounds: o11.bounds, boundaryMargin: 0, boardEdgeClearance: t10.originalSrj.minBoardEdgeClearance ?? 0, lockedPointIndices: r11.map((e58) => e58.route.map(() => false)), allowViaMovement: !t10.allowPartialRepair, traceClearance: (t10.originalSrj.minTraceToPadEdgeClearance ?? E7.traceClearance) + (t10.allowPartialRepair || t10.usePrecisionMargin ? Ste : 0), viaClearance: (t10.originalSrj.minPadEdgeToPadEdgeClearance ?? E7.viaClearance) + (t10.usePrecisionMargin ? Ste : 0) });
return this.MAX_ITERATIONS = s11.MAX_ITERATIONS + 4, this.activeSubSolver = s11, void (this.state = { phase: "relax", context: { srj: o11, errors: n11, originalCanonicalRoutes: i11, canonicalRoutes: r11 }, solver: s11 });
}
if (e50.phase === "relax") {
if (e50.solver.step(), this.MAX_ITERATIONS = e50.solver.MAX_ITERATIONS + 4, e50.solver.failed)
throw new Error(`Clearance relaxation failed: ${e50.solver.error}`);
return void (e50.solver.solved && (this.activeSubSolver = null, this.state = { phase: "select", context: e50.context, candidate: e50.solver.getOutput() }));
}
if (e50.phase === "finished")
throw new Error("Clearance projection stepped after completion");
const { srj: n10, errors: o10, originalCanonicalRoutes: i10, canonicalRoutes: r10 } = e50.context;
if (e50.phase === "select") {
let o11 = e50.candidate;
return t10.allowPartialRepair && (o11 = (({ srj: e54, routes: t11, proposedRoutes: n11 }) => {
if (t11.length !== n11.length)
throw new Error("Clearance projection changed the route count");
if (e54.allowBlindAndBuriedVias || t11.some((e58) => e58.jumpers?.length || e58.route.some((e59) => e59.toNextSegmentType || e59.insideJumperPad)))
return t11;
const { holeDiameter: o12 } = Xo(e54), i11 = (t12, n12) => ({ type: "pcb_trace", pcb_trace_id: `projection_${n12}`, connection_name: t12.rootConnectionName ?? t12.connectionName, route: Ro(t12, e54.layerCount, { defaultViaHoleDiameter: o12 }) }), r11 = t11.map(i11), s11 = { ...e54, minBoardEdgeClearance: e54.minBoardEdgeClearance ?? 0, traces: r11 }, a11 = new V6(s11), c11 = new Set(a11.canonicalize([...(e54.differentialPairs ?? []).flatMap((e58) => e58.connectionNames), ...(e54.buses ?? []).flatMap((e58) => e58.connectionNames)])), l10 = [...t11], h10 = [];
for (const [e58, o13] of n11.entries()) {
const n12 = t11[e58];
if (o13.route.length !== n12.route.length)
throw new Error("Partial clearance projection changed routing topology");
const i12 = [r11[e58].pcb_trace_id];
if (!a11.canonicalize(i12).some((e59) => c11.has(e59))) {
l10[e58] = { ...n12, route: [...o13.route] };
for (let t12 = 0;t12 < o13.route.length; t12++)
o13.route[t12].x === n12.route[t12].x && o13.route[t12].y === n12.route[t12].y || h10.push({ routeIndex: e58, pointIndex: t12 });
}
}
let d10 = new x8(s11, l10.map(i11), undefined, [], a11);
const u10 = ({ routeIndex: t12, pointIndex: n12 }) => {
const o13 = l10[t12];
for (let i12 = Math.max(1, n12);i12 <= Math.min(n12 + 1, o13.route.length - 1); i12++) {
const n13 = o13.route[i12 - 1], s12 = o13.route[i12];
if (n13.z !== s12.z)
throw new Error("Partial clearance projection moved a layer transition");
if (d10.collides({ start: n13, end: s12, layer: Po(n13.z, e54.layerCount), width: Math.max(n13.traceThickness ?? o13.traceThickness, s12.traceThickness ?? o13.traceThickness), connectionNames: [r11[t12].pcb_trace_id] }))
return false;
}
return true;
};
let p10 = h10;
for (;p10.length > 0; ) {
const e58 = p10.filter((e59) => !u10(e59));
if (e58.length === 0)
break;
for (const { routeIndex: n13, pointIndex: o13 } of e58)
l10[n13].route[o13] = t11[n13].route[o13];
const n12 = new Set(e58);
p10 = p10.filter((e59) => !n12.has(e59)), d10 = new x8(s11, l10.map(i11), undefined, [], a11);
}
const m10 = new Set(p10);
for (let e58 = 0;e58 < h10.length; e58++) {
const o13 = h10[e58];
if (m10.has(o13))
continue;
let r12 = [o13];
for (;e58 + 1 < h10.length; ) {
const t12 = h10[e58 + 1];
if (m10.has(t12) || t12.routeIndex !== o13.routeIndex || t12.pointIndex !== h10[e58].pointIndex + 1)
break;
r12.push(t12), e58++;
}
for (const { routeIndex: e59, pointIndex: t12 } of r12)
l10[e59].route[t12] = n11[e59].route[t12];
for (;r12.length > 0; ) {
const e59 = r12.filter((e60) => !u10(e60));
if (e59.length === 0)
break;
for (const { routeIndex: n13, pointIndex: o14 } of e59)
l10[n13].route[o14] = t11[n13].route[o14];
const n12 = new Set(e59);
r12 = r12.filter((e60) => !n12.has(e60));
}
if (r12.length !== 0) {
for (const e59 of r12)
m10.add(e59);
d10 = new x8(s11, l10.map(i11), undefined, [], a11);
}
}
const g10 = new Set([...m10].map(({ routeIndex: e58 }) => e58));
return l10.map((e58, n12) => g10.has(n12) ? e58 : t11[n12]);
})({ srj: n10, routes: r10, proposedRoutes: o11 }), o11 = o11.map((e54, t11) => e54 === r10[t11] ? i10[t11] : e54)), void (this.state = { phase: "physical-validation", context: e50.context, candidate: o11 });
}
if (e50.phase === "physical-validation") {
const o11 = new Map(S_({ srj: n10, routes: r10 }).map((e54) => [e54.key, e54.severity]));
return S_({ srj: n10, routes: e50.candidate }).some(({ key: e54, severity: t11 }) => !o11.has(e54) || t11 > o11.get(e54) + 0.00000001) || P_({ srj: n10, previousRoutes: t10.previousRoutes ?? r10, routes: e50.candidate }).length > 0 ? (this.state = { phase: "finished", output: t10.routes }, void (this.solved = true)) : void (this.state = { ...e50, phase: "reference-validation" });
}
const s10 = t10.drcEvaluator({ traces: [], routes: e50.candidate, hdRoutes: e50.candidate }), a10 = Array.isArray(s10) ? s10 : s10.errors, c10 = t10.allowPartialRepair ? ((e54, t11) => {
if (t11.length >= e54.length)
return false;
const n11 = (e58) => e58.type === "pcb_via_trace_clearance_error" ? JSON.stringify([e58.type, e58.pcb_trace_id, e58.pcb_via_id]) : e58.type === "pcb_pad_trace_clearance_error" ? JSON.stringify([e58.type, e58.pcb_trace_id, e58.pcb_pad_id]) : e58.type === "pcb_via_clearance_error" && Array.isArray(e58.pcb_via_ids) ? JSON.stringify([e58.type, [...e58.pcb_via_ids].sort()]) : e58.type === "pcb_trace_error" && typeof e58.pcb_trace_error_id == "string" && e58.pcb_trace_error_id.startsWith(`overlap_${e58.pcb_trace_id}_`) ? JSON.stringify([e58.type, e58.pcb_trace_error_id]) : undefined, o11 = [...e54];
for (const e58 of t11) {
const t12 = n11(e58);
if (t12 === undefined)
return false;
const i11 = o11.findIndex((e59) => n11(e59) === t12);
if (i11 < 0)
return false;
const r11 = o11.splice(i11, 1)[0];
if (e58.type !== "pcb_trace_error" && (typeof e58.actual_clearance != "number" || !Number.isFinite(e58.actual_clearance) || typeof r11.actual_clearance != "number" || !Number.isFinite(r11.actual_clearance) || e58.minimum_clearance !== r11.minimum_clearance || e58.actual_clearance < r11.actual_clearance - 0.000000001))
return false;
}
return true;
})(o10, a10) : a10.length < o10.length;
this.state = { phase: "finished", output: c10 ? e50.candidate : t10.routes }, this.solved = true;
}
getOutput() {
if (!this.solved || this.state.phase !== "finished")
throw new Error("Clearance projection is not complete");
return this.state.output;
}
computeProgress() {
switch (this.state.phase) {
case "initialize":
return 0;
case "relax":
return 0.9 * this.state.solver.progress;
case "select":
return 0.9;
case "physical-validation":
return 0.93;
case "reference-validation":
return 0.96;
case "finished":
return 1;
}
}
};
var Xte = class extends ai {
params;
merger;
result;
phase = "initialize";
physicalSrj;
movableRoutes = [];
candidateRoutes;
beforeErrorCount = 0;
constructor(e50) {
super(), this.params = e50, this.MAX_ITERATIONS = 1000004;
}
initializeMerge() {
const { srj: e50, routes: t10, connMap: n10, drcEvaluator: o10, referenceResult: i10 } = this.params, r10 = i10 ?? o10({ traces: [], routes: t10, hdRoutes: t10 });
this.result = { routes: t10, referenceResult: r10, referenceValidationCount: i10 === undefined ? 1 : 0, accepted: false };
const s10 = Array.isArray(r10) ? r10 : r10.errors;
this.beforeErrorCount = s10.length;
const a10 = s10.filter((e54) => e54.type === "pcb_via_clearance_error").flatMap(jte);
if (this.movableRoutes = t10.filter((e54) => a10.some((t11) => t11 === e54.connectionName || t11.startsWith(`${e54.connectionName}_`))), this.movableRoutes.length === 0)
return this.phase = "done", void (this.solved = true);
this.physicalSrj = { ...O0(e50), traces: undefined };
const c10 = new Set(this.movableRoutes);
this.merger = new NB({ inputHdRoutes: this.movableRoutes, otherHdRoutes: t10.filter((e54) => !c10.has(e54)), netByConnectionName: G7(t10, n10), obstacles: this.physicalSrj.obstacles, layerCount: this.physicalSrj.layerCount, connMap: n10, colorMap: {}, preserveRouteEndpoints: true }), this.MAX_ITERATIONS = this.merger.MAX_ITERATIONS + 4, this.activeSubSolver = this.merger, this.phase = "merge";
}
stepMerge() {
const e50 = this.merger;
if (!e50)
throw new Error("Reported via merge has no active merger");
if (e50.step(), e50.failed)
throw new Error(`Reported via merge failed: ${e50.error}`);
if (!e50.solved)
return;
if (e50.mergedViaHdRoutes.length !== this.movableRoutes.length)
throw new Error("Reported via merge changed the number of route pieces");
const t10 = new Map(this.movableRoutes.map((t11, n10) => [t11, e50.mergedViaHdRoutes[n10]]));
this.candidateRoutes = this.params.routes.map((e54) => t10.get(e54) ?? e54), this.activeSubSolver = null, this.phase = "physical-check";
}
validatePhysicalProposal() {
const e50 = this.physicalSrj, t10 = this.candidateRoutes;
if (!e50 || !t10)
throw new Error("Reported via merge has no physical proposal");
const n10 = this.params.routes, o10 = new Map(S_({ srj: e50, routes: n10 }).map(({ key: e54, severity: t11 }) => [e54, t11]));
if (!S_({ srj: e50, routes: t10 }).every(({ key: e54, severity: t11 }) => o10.has(e54) && t11 <= o10.get(e54) + 0.00000001) || P_({ srj: e50, previousRoutes: n10, routes: t10 }).length > 0)
return this.phase = "done", void (this.solved = true);
this.phase = "reference-check";
}
validateReferenceProposal() {
const e50 = this.result, t10 = this.candidateRoutes;
if (!e50 || !t10)
throw new Error("Reported via merge has no reference proposal");
const n10 = this.params.drcEvaluator({ traces: [], routes: t10, hdRoutes: t10 });
e50.referenceValidationCount++;
(Array.isArray(n10) ? n10 : n10.errors).length < this.beforeErrorCount && (this.result = { ...e50, routes: t10, referenceResult: n10, accepted: true }), this.phase = "done", this.solved = true;
}
_step() {
switch (this.phase) {
case "initialize":
return this.initializeMerge();
case "merge":
return this.stepMerge();
case "physical-check":
return this.validatePhysicalProposal();
case "reference-check":
return this.validateReferenceProposal();
case "done":
throw new Error("Reported via merge was stepped after completion");
}
}
getResult() {
if (!this.solved || this.failed || !this.result)
throw new Error("Reported via merge is not complete");
return this.result;
}
};
var Wte = [10, 16];
var Vte = class extends ai {
params;
budget;
state = { phase: "initialize" };
result;
reservedChildMaximum = 0;
constructor(e50) {
super(), this.params = e50, this.budget = e50.budget ?? wte, this.result = { routes: e50.routes, attemptedRegionCount: 0, acceptedRegionCount: 0, candidateAttemptCount: 0, pathSearchNodeCount: 0, referenceValidationCount: 0, initialDrcIssueCount: undefined, finalDrcIssueCount: undefined, publishedDrcIssueCount: undefined, repaired: false }, this.MAX_ITERATIONS = 16 * this.budget.maxRegions + 32;
}
updateProgress() {
const e50 = Nte(this.budget, this.result.acceptedRegionCount), t10 = this.state.phase === "negotiate" ? this.state.solver : undefined, n10 = typeof t10?.stats.pathSearchCalls == "number" ? t10.stats.pathSearchCalls : 0, o10 = typeof t10?.stats.pathSearchNodes == "number" ? t10.stats.pathSearchNodes : 0;
this.stats = { ...this.result, routes: undefined, phase: this.state.phase, candidateAttemptCount: this.result.candidateAttemptCount + n10, pathSearchNodeCount: this.result.pathSearchNodeCount + o10, allowedRegionCount: e50.maxRegions, allowedCandidateAttemptCount: e50.maxCandidateAttempts, allowedPathSearchNodeCount: e50.maxPathSearchNodes };
const i10 = Math.max(this.result.attemptedRegionCount / Math.max(1, this.budget.maxRegions), this.stats.candidateAttemptCount / Math.max(1, this.budget.maxCandidateAttempts), this.stats.pathSearchNodeCount / Math.max(1, this.budget.maxPathSearchNodes));
this.progress = this.solved ? 1 : Math.max(this.progress, Math.min(0.99, i10));
}
startChild(e50) {
if (this.activeSubSolver)
throw new Error("Regional repair started a child before the previous stage completed");
this.activeSubSolver = e50, this.reservedChildMaximum = e50.MAX_ITERATIONS, this.MAX_ITERATIONS += this.reservedChildMaximum + 1;
}
finish() {
if (this.activeSubSolver)
throw new Error("Regional repair finished with an active child solver");
this.solved = true, this.state = { phase: "done" };
}
publish(e50, t10) {
this.result.routes = e50.currentRoutes, this.result.publishedDrcIssueCount = e50.currentErrors.length, this.result.finalDrcIssueCount = e50.currentErrors.length, this.result.repaired = t10, this.finish();
}
initialize() {
const { originalSrj: e50, routes: t10, syntheticConnectionNames: n10 } = this.params;
if (e50.traces?.length || n10.size > 0)
return void this.finish();
const o10 = Math.max(e50.defaultObstacleMargin ?? 0.2, e50.minTraceToPadEdgeClearance ?? 0, e50.minTraceToHoleEdgeClearance ?? 0, e50.minViaEdgeToPadEdgeClearance ?? 0);
let i10 = Math.max(e50.minTraceWidth, e50.minViaDiameter ?? 0);
for (const e54 of t10) {
i10 = Math.max(i10, e54.traceThickness, e54.viaDiameter);
for (const t11 of e54.route)
i10 = Math.max(i10, t11.traceThickness ?? 0);
}
const r10 = Math.max(0.5, i10 + o10), s10 = (this.budget.regionSizes ?? Wte).filter((e54) => !Number.isFinite(r10) || 2 * r10 < e54);
s10.length !== 0 ? this.state = { phase: "initial-reference", context: { boundaryMargin: r10, regionSizes: s10 } } : this.finish();
}
initialReference(e50) {
const t10 = this.params.drcEvaluator({ traces: [], routes: this.params.routes, hdRoutes: this.params.routes });
this.result.referenceValidationCount++;
const n10 = Array.isArray(t10) ? t10 : t10.errors, o10 = { ...e50, currentRoutes: this.params.routes, reference: t10, currentErrors: n10, initialErrors: n10 };
if (this.result.initialDrcIssueCount = n10.length, this.result.finalDrcIssueCount = n10.length, this.result.publishedDrcIssueCount = n10.length, n10.length === 0)
return void this.finish();
const i10 = new Yte({ originalSrj: this.params.originalSrj, routes: o10.currentRoutes, drcEvaluator: (e54) => (this.result.referenceValidationCount++, this.params.drcEvaluator(e54)) });
this.state = { phase: "initial-projection", context: o10, solver: i10 }, this.startChild(i10);
}
initialProjectionReference(e50) {
const t10 = this.params.drcEvaluator({ traces: [], routes: e50.currentRoutes, hdRoutes: e50.currentRoutes });
this.result.referenceValidationCount++, e50.reference = t10, e50.currentErrors = Array.isArray(t10) ? t10 : t10.errors, this.result.finalDrcIssueCount = e50.currentErrors.length, e50.currentErrors.length !== 0 ? this.state = { phase: "prepare-regions", context: e50 } : this.publish(e50, true);
}
prepareRegions(e50) {
const t10 = { ...O0(this.params.originalSrj), traces: undefined }, n10 = new Map;
for (const e54 of this.params.originalSrj.obstacles)
for (const t11 of [e54.obstacleId, e54.circuitJsonMetadata?.pcb_smtpad_id, e54.circuitJsonMetadata?.pcb_plated_hole_id, e54.connectedTo[0]])
typeof t11 == "string" && n10.set(t11, e54.center);
const o10 = iee(e50.currentRoutes), i10 = { ...e50, srj: t10, obstacleCenterById: n10, currentRoutes: o10, attemptedRegions: [], fixedViolations: new Map(S_({ srj: t10, routes: o10 }).map(({ key: e54, severity: t11 }) => [e54, t11])) };
this.state = { phase: "select-region", context: i10 };
}
selectRegion(e50) {
const t10 = Nte(this.budget, this.result.acceptedRegionCount);
if (this.result.attemptedRegionCount >= t10.maxRegions || this.result.candidateAttemptCount >= t10.maxCandidateAttempts || this.result.pathSearchNodeCount >= t10.maxPathSearchNodes)
return void (this.state = { phase: "publish-partial", context: e50 });
const n10 = (Array.isArray(e50.reference) ? e50.reference : e50.reference.errorsWithCenters ?? e50.reference.errors).map((t11) => {
const n11 = `overlap_${t11.pcb_trace_id}_`, o11 = typeof t11.pcb_pad_id == "string" ? t11.pcb_pad_id : typeof t11.pcb_trace_error_id == "string" && t11.pcb_trace_error_id.startsWith(n11) ? t11.pcb_trace_error_id.slice(n11.length) : undefined;
return (o11 ? e50.obstacleCenterById.get(o11) : undefined) ?? t11.center ?? t11.pcb_center;
}).filter((e54) => e54 !== null && typeof e54 == "object" && ("x" in e54) && ("y" in e54) && typeof e54.x == "number" && typeof e54.y == "number" && Number.isFinite(e54.x) && Number.isFinite(e54.y));
let o10;
for (const t11 of e50.regionSizes) {
const i11 = n10.filter(({ x: n11, y: o11 }) => !e50.attemptedRegions.some(({ bounds: e54, size: i12 }) => t11 === i12 && n11 >= e54.minX && n11 <= e54.maxX && o11 >= e54.minY && o11 <= e54.maxY)), r11 = i11[0];
if (!r11)
continue;
let { x: s11, x: a11, y: c11, y: l11 } = r11;
const h11 = t11 - 2 * e50.boundaryMargin;
for (const e54 of i11.slice(1)) {
const t12 = Math.min(s11, e54.x), n11 = Math.max(a11, e54.x), o11 = Math.min(c11, e54.y), i12 = Math.max(l11, e54.y);
n11 - t12 >= h11 || i12 - o11 >= h11 || (s11 = t12, a11 = n11, c11 = o11, l11 = i12);
}
o10 = { center: { x: (s11 + a11) / 2, y: (c11 + l11) / 2 }, size: t11 };
break;
}
if (!o10)
return void (this.state = { phase: "publish-partial", context: e50 });
const { center: i10, size: r10 } = o10, s10 = O_({ srj: e50.srj, routes: e50.currentRoutes, bounds: { minX: i10.x - r10 / 2, maxX: i10.x + r10 / 2, minY: i10.y - r10 / 2, maxY: i10.y + r10 / 2 } });
if (e50.attemptedRegions.push({ bounds: s10.mutableBounds, size: r10 }), this.result.attemptedRegionCount++, s10.routes.length === 0)
return;
const a10 = new Set(e50.currentErrors.flatMap(jte)), c10 = s10.routes.flatMap((e54, t11) => [...a10].some((t12) => t12 === e54.connectionName || t12.startsWith(`${e54.connectionName}_`)) ? [t11] : []), l10 = Math.min(this.budget.maxCandidateAttemptsPerRegion ?? (this.budget.revisitChangedRegions ? Math.ceil(t10.maxCandidateAttempts / 2) : t10.maxCandidateAttempts), t10.maxCandidateAttempts - this.result.candidateAttemptCount), h10 = new W_({ srj: s10.srj, routes: s10.routes, bounds: s10.mutableBounds, dirtyRouteIndices: c10, isLocked: (e54, t11) => s10.lockedPointIndices[e54][t11], maxPathSearchCalls: l10, maxPathSearchNodes: t10.maxPathSearchNodes - this.result.pathSearchNodeCount, maxPathSearchNodesPerCall: this.budget.maxPathSearchNodesPerCall, pathHeuristicWeight: this.budget.pathHeuristicWeight, pathGridSizeScale: e50.currentErrors.length > 10 ? this.budget.pathGridSizeScale : undefined, allowLayerChanges: true, traceClearance: E7.traceClearance, viaClearance: E7.viaClearance, viaHoleDiameter: this.params.viaHoleDiameter });
this.state = { phase: "negotiate", negotiation: { context: e50, allowance: t10, maxPathSearchCalls: l10, region: s10 }, solver: h10 }, this.startChild(h10);
}
completeNegotiation(e50) {
const t10 = e50.solver.getOutput(), { context: n10, allowance: o10, maxPathSearchCalls: i10 } = e50.negotiation, { pathSearchCalls: r10, pathSearchNodes: s10 } = t10;
if (this.budget.revisitChangedRegions && t10.unresolvedSpanCount > 0 && r10 < i10 && s10 < o10.maxPathSearchNodes - this.result.pathSearchNodeCount && n10.regionSizes.sort((e54, t11) => t11 - e54), !Number.isSafeInteger(r10) || r10 < 0 || r10 + this.result.candidateAttemptCount > this.budget.maxCandidateAttempts || !Number.isSafeInteger(s10) || s10 < 0 || s10 + this.result.pathSearchNodeCount > this.budget.maxPathSearchNodes)
throw new Error("Pipeline9 bounded regional repair exceeded its work budget");
this.result.candidateAttemptCount += r10, this.result.pathSearchNodeCount += s10, this.state = { phase: "splice-region", negotiation: e50.negotiation, repair: t10 };
}
spliceRegion(e50) {
const { context: t10, region: n10 } = e50.negotiation, o10 = (({ routes: e54, region: t11, repairedRoutes: n11 }) => {
if (n11.length !== t11.routeMappings.length || t11.lockedPointIndices.length !== n11.length)
throw new Error("repair04 merge requires exactly one replacement for every extracted fragment");
const o11 = new Map;
for (let i11 = 0;i11 < n11.length; i11 += 1) {
const r10 = t11.routeMappings[i11], s10 = n11[i11];
if (!e54[r10.sourceRouteIndex])
throw new Error("repair04 merge source route no longer exists");
if (L_(r10.originalFragment, s10, t11.lockedPointIndices[i11], t11.mutableBounds, t11.contextBounds, t11.srj.layerCount), oa(r10.originalFragment) === oa(s10))
continue;
const a10 = o11.get(r10.sourceRouteIndex) ?? [];
a10.push({ mapping: r10, repaired: s10 }), o11.set(r10.sourceRouteIndex, a10);
}
return e54.map((e58, t12) => {
const n12 = o11.get(t12);
if (!n12)
return e58;
n12.sort((e59, t13) => F_(e59.mapping.start) - F_(t13.mapping.start));
const i11 = [];
let r10 = 0;
for (const { mapping: t13, repaired: o12 } of n12) {
const n13 = F_(t13.start), s11 = F_(t13.end);
if (n13 < r10 - Qs || s11 < n13 || s11 > e58.route.length - 1 + Qs)
throw new Error("repair04 merge received overlapping or stale fragment provenance");
if (ra(e58, n13, s11) !== t13.sourceGeometryKey)
throw new Error("repair04 merge rejected stale source geometry");
z_(i11, ia(e58, r10, n13)), z_(i11, o12.route), r10 = s11;
}
z_(i11, ia(e58, r10, e58.route.length - 1));
const s10 = new Set(n12.flatMap(({ mapping: e59 }) => e59.originalFragment.vias.map((e60) => `${e60.x},${e60.y}`))), a10 = e58.vias.filter((e59) => !s10.has(`${e59.x},${e59.y}`)).map((e59) => structuredClone(e59));
for (const { repaired: e59 } of n12)
for (const t13 of e59.vias)
a10.some((e60) => Math.abs(e60.x - t13.x) <= Qs && Math.abs(e60.y - t13.y) <= Qs) || a10.push(structuredClone(t13));
return { ...e58, route: B_(i11, e58, n12.map(({ mapping: e59 }) => e59)), vias: a10 };
});
})({ routes: t10.currentRoutes, region: n10, repairedRoutes: e50.repair.routes });
if (o10.every((e54, n11) => e54 === t10.currentRoutes[n11]))
return void (this.state = { phase: "select-region", context: t10 });
const i10 = new Yte({ originalSrj: this.params.originalSrj, routes: o10, previousRoutes: t10.currentRoutes, subdivideSegments: true, drcEvaluator: (e54) => (this.result.referenceValidationCount++, this.params.drcEvaluator(e54)) });
this.state = { phase: "candidate-projection", context: t10, solver: i10 }, this.startChild(i10);
}
prepareViaMerge(e50) {
if (!this.params.connMap)
return void (this.state = { ...e50, phase: "candidate-physical" });
const t10 = new Xte({ srj: e50.context.srj, routes: e50.candidateRoutes, connMap: this.params.connMap, drcEvaluator: this.params.drcEvaluator });
this.state = { ...e50, phase: "via-merge", solver: t10 }, this.startChild(t10);
}
validateCandidate(e50) {
const { context: t10, candidateRoutes: n10 } = e50, o10 = S_({ srj: t10.srj, routes: n10 });
!o10.every(({ key: e54, severity: n11 }) => t10.fixedViolations.has(e54) && n11 <= t10.fixedViolations.get(e54) + 0.00000001) || P_({ srj: t10.srj, previousRoutes: t10.currentRoutes, routes: n10 }).length > 0 ? this.state = { phase: "select-region", context: t10 } : this.state = e50.candidateReference === undefined ? { phase: "candidate-reference", context: t10, candidateRoutes: n10, candidateFixedViolations: o10 } : { phase: "accept-candidate", context: t10, candidateRoutes: n10, candidateFixedViolations: o10, candidateReference: e50.candidateReference };
}
referenceCandidate(e50) {
const t10 = this.params.drcEvaluator({ traces: [], routes: e50.candidateRoutes, hdRoutes: e50.candidateRoutes });
this.result.referenceValidationCount++, this.state = { ...e50, phase: "accept-candidate", candidateReference: t10 };
}
acceptCandidate(e50) {
const { context: t10, candidateReference: n10 } = e50, o10 = Array.isArray(n10) ? n10 : n10.errors;
o10.length >= t10.currentErrors.length ? this.state = { phase: "select-region", context: t10 } : (t10.currentRoutes = e50.candidateRoutes, t10.currentErrors = o10, t10.reference = n10, t10.fixedViolations = new Map(e50.candidateFixedViolations.map(({ key: e54, severity: t11 }) => [e54, t11])), this.result.acceptedRegionCount++, this.budget.revisitChangedRegions && (t10.attemptedRegions.length = 0), this.result.finalDrcIssueCount = o10.length, o10.length !== 0 ? this.state = { phase: "select-region", context: t10 } : this.publish(t10, true));
}
publishPartial(e50) {
(({ originalSrj: e54, initialErrors: t10, remainingErrors: n10 }) => {
if (n10.length >= t10.length)
return false;
const o10 = new Set(e54.obstacles.flatMap((e58) => {
const t11 = e58.circuitJsonMetadata;
return [t11?.pcb_smtpad_id, t11?.pcb_plated_hole_id].filter((e59) => typeof e59 == "string");
})), i10 = [...t10];
for (const e58 of n10) {
if (typeof e58.pcb_trace_id != "string")
return false;
const t11 = `overlap_${e58.pcb_trace_id}_`, n11 = e58.type === "pcb_trace_error" && typeof e58.pcb_trace_error_id == "string" && e58.pcb_trace_error_id.startsWith(t11) ? e58.pcb_trace_error_id.slice(t11.length) : undefined, r10 = e58.type === "pcb_pad_trace_clearance_error", s10 = r10 ? e58.pcb_pad_id : n11;
if (typeof s10 != "string" || !o10.has(s10))
return false;
const a10 = i10.findIndex((t12) => t12.type === e58.type && t12.pcb_trace_id === e58.pcb_trace_id && (r10 ? t12.pcb_pad_id === s10 : t12.pcb_trace_error_id === e58.pcb_trace_error_id));
if (a10 === -1)
return false;
const c10 = i10.splice(a10, 1)[0];
if (r10 && (typeof e58.actual_clearance != "number" || !Number.isFinite(e58.actual_clearance) || typeof c10.actual_clearance != "number" || !Number.isFinite(c10.actual_clearance) || typeof e58.minimum_clearance != "number" || !Number.isFinite(e58.minimum_clearance) || e58.minimum_clearance !== c10.minimum_clearance || e58.actual_clearance < c10.actual_clearance))
return false;
}
return true;
})({ originalSrj: this.params.originalSrj, initialErrors: e50.initialErrors, remainingErrors: e50.currentErrors }) ? this.publish(e50, false) : this.state = { phase: "prepare-independent-projection", context: e50 };
}
prepareIndependentProjection(e50) {
const t10 = new Yte({ originalSrj: this.params.originalSrj, routes: this.params.routes, allowPartialRepair: true, drcEvaluator: (e54) => (this.result.referenceValidationCount++, this.params.drcEvaluator(e54)) });
this.state = { phase: "independent-projection", context: e50, solver: t10 }, this.startChild(t10);
}
prepareIndependentSubdivision(e50) {
const t10 = new Yte({ originalSrj: this.params.originalSrj, routes: e50.independentRoutes, allowPartialRepair: true, subdivideSegments: true, drcEvaluator: (e54) => (this.result.referenceValidationCount++, this.params.drcEvaluator(e54)) });
this.state = { phase: "independent-subdivision", context: e50.context, solver: t10 }, this.startChild(t10);
}
prepareIndependentCoupled(e50) {
const t10 = new Yte({ originalSrj: this.params.originalSrj, routes: e50.independentRoutes, usePrecisionMargin: true, drcEvaluator: (e54) => (this.result.referenceValidationCount++, this.params.drcEvaluator(e54)) });
this.state = { phase: "independent-coupled", context: e50.context, solver: t10 }, this.startChild(t10);
}
referenceIndependent(e50) {
const t10 = this.params.drcEvaluator({ traces: [], routes: e50.independentRoutes, hdRoutes: e50.independentRoutes });
this.result.referenceValidationCount++;
const n10 = Array.isArray(t10) ? t10 : t10.errors;
this.result.routes = e50.independentRoutes, this.result.publishedDrcIssueCount = n10.length, this.result.finalDrcIssueCount = n10.length, this.result.repaired = n10.length === 0, this.finish();
}
completeChild() {
const e50 = this.state;
switch (e50.phase) {
case "initial-projection": {
const t10 = e50.solver.getOutput();
t10 !== e50.context.currentRoutes ? (e50.context.currentRoutes = t10, this.state = { phase: "initial-projection-reference", context: e50.context }) : this.state = { phase: "prepare-regions", context: e50.context };
break;
}
case "negotiate":
this.completeNegotiation(e50);
break;
case "candidate-projection": {
const t10 = new Yte({ originalSrj: this.params.originalSrj, routes: e50.solver.getOutput(), previousRoutes: e50.context.currentRoutes, usePrecisionMargin: true, drcEvaluator: (e54) => (this.result.referenceValidationCount++, this.params.drcEvaluator(e54)) });
this.state = { phase: "candidate-margin-projection", context: e50.context, solver: t10 }, this.startChild(t10);
break;
}
case "candidate-margin-projection":
this.state = { phase: "prepare-via-merge", context: e50.context, candidateRoutes: e50.solver.getOutput() };
break;
case "via-merge": {
const t10 = e50.solver.getResult();
this.result.referenceValidationCount += t10.referenceValidationCount, this.state = { phase: "candidate-physical", context: e50.context, candidateRoutes: t10.routes, candidateReference: t10.referenceResult };
break;
}
case "independent-projection":
this.state = { phase: "prepare-independent-subdivision", context: e50.context, independentRoutes: e50.solver.getOutput() };
break;
case "independent-subdivision": {
const t10 = e50.solver.getOutput();
t10 === this.params.routes ? this.finish() : this.state = { phase: "prepare-independent-coupled", context: e50.context, independentRoutes: t10 };
break;
}
case "independent-coupled":
this.state = { phase: "independent-reference", context: e50.context, independentRoutes: e50.solver.getOutput() };
break;
default:
throw new Error(`Regional repair child completed during phase ${e50.phase}`);
}
}
_step() {
const e50 = this.activeSubSolver;
if (e50)
return e50.step(), e50.MAX_ITERATIONS > this.reservedChildMaximum && (this.MAX_ITERATIONS += e50.MAX_ITERATIONS - this.reservedChildMaximum, this.reservedChildMaximum = e50.MAX_ITERATIONS), e50.failed ? (this.failed = true, this.error = e50.error) : e50.solved && (this.activeSubSolver = null, this.reservedChildMaximum = 0, this.completeChild()), void this.updateProgress();
const t10 = this.state;
switch (t10.phase) {
case "initialize":
this.initialize();
break;
case "initial-reference":
this.initialReference(t10.context);
break;
case "initial-projection-reference":
this.initialProjectionReference(t10.context);
break;
case "prepare-regions":
this.prepareRegions(t10.context);
break;
case "select-region":
this.selectRegion(t10.context);
break;
case "splice-region":
this.spliceRegion(t10);
break;
case "prepare-via-merge":
this.prepareViaMerge(t10);
break;
case "candidate-physical":
this.validateCandidate(t10);
break;
case "candidate-reference":
this.referenceCandidate(t10);
break;
case "accept-candidate":
this.acceptCandidate(t10);
break;
case "publish-partial":
this.publishPartial(t10.context);
break;
case "prepare-independent-projection":
this.prepareIndependentProjection(t10.context);
break;
case "prepare-independent-subdivision":
this.prepareIndependentSubdivision(t10);
break;
case "prepare-independent-coupled":
this.prepareIndependentCoupled(t10);
break;
case "independent-reference":
this.referenceIndependent(t10);
break;
default:
throw new Error(`Regional repair has no active child during phase ${t10.phase}`);
}
this.updateProgress();
}
getResult() {
if (!this.solved || this.failed)
throw new Error("Pipeline9 bounded regional repair result requested before completion");
return this.result;
}
};
var Hte = [0.9, 0.72];
var Gte = Array.from({ length: 16 }, (e50, t10) => t10 * Math.PI / 8);
var Ute = (e50) => e50.type === "pcb_pad_trace_clearance_error" || e50.type === "pcb_trace_error" && !(Array.isArray(e50.pcb_trace_ids) && e50.pcb_trace_ids.length >= 2);
var Zte = (e50) => {
if (typeof e50.pcb_pad_id == "string")
return e50.pcb_pad_id;
if (typeof e50.pcb_trace_error_id == "string") {
const t11 = e50.pcb_trace_error_id.match(/(pcb_(?:smtpad|plated_hole|hole|keepout)_\d+)$/)?.[1];
if (t11)
return t11;
}
const t10 = typeof e50.message == "string" ? e50.message : "";
return t10.match(/(?:pcb_smtpad|pcb_plated_hole|pcb_hole|pcb_keepout)\[#?([^\]"]+)\]/)?.[1];
};
var qte = (e50, t10) => {
if (!t10)
return;
const n10 = t10.startsWith("pcb_") ? t10 : `pcb_${t10}`;
return e50.obstacles.find((e54) => e54.obstacleId === n10 || e54.connectedTo[0] === n10);
};
var Jte = ({ srj: e50, pcbPortId: t10, z: n10, portPositionMap: o10 }) => {
const i10 = Po(n10, e50.layerCount), r10 = o10.get(t10), s10 = e50.obstacles.filter((e54) => e54.layers.includes(i10) && e54.connectedTo.includes(t10));
return r10 ? s10.reduce((e54, t11) => e54 ? Math.hypot(t11.center.x - r10.x, t11.center.y - r10.y) < Math.hypot(e54.center.x - r10.x, e54.center.y - r10.y) ? t11 : e54 : t11, undefined) : s10[0];
};
var Qte = ({ terminalObstacle: e50, conflictingObstacle: t10, traceRadius: n10 }) => {
const o10 = Math.max(0, e50.width / 2 - n10), i10 = Math.max(0, e50.height / 2 - n10), r10 = (e50.ccwRotationDegrees ?? 0) * Math.PI / 180;
return Hte.flatMap((t11) => Gte.map((n11) => {
const s10 = { x: Math.cos(n11) * o10 * t11, y: Math.sin(n11) * i10 * t11 }, a10 = (l10 = r10, { x: (c10 = s10).x * Math.cos(l10) - c10.y * Math.sin(l10), y: c10.x * Math.sin(l10) + c10.y * Math.cos(l10) });
var c10, l10;
return { x: e50.center.x + a10.x, y: e50.center.y + a10.y };
})).sort((e54, n11) => Math.hypot(n11.x - t10.center.x, n11.y - t10.center.y) - Math.hypot(e54.x - t10.center.x, e54.y - t10.center.y)).slice(0, 16);
};
var Kte = ({ routes: e50, routeIndex: t10, endpointIndex: n10, point: o10, bounds: i10, collapseAdjacent: r10 }) => {
const s10 = ((e54) => e54.map((e58) => ({ ...e58, route: e58.route.map((e59) => ({ ...e59 })), vias: e58.vias.map((e59) => ({ ...e59 })) })))(e50), a10 = s10[t10];
if (!a10 || a10.route.length < 2)
return;
const c10 = n10 === 0 ? 0 : a10.route.length - 1, l10 = n10 === 0 ? 1 : c10 - 1, h10 = a10.route[c10], d10 = a10.route[l10];
if (!h10 || !d10 || h10.z !== d10.z)
return;
const u10 = a10.traceThickness / 2;
if (!(o10.x - u10 < i10.minX || o10.x + u10 > i10.maxX || o10.y - u10 < i10.minY || o10.y + u10 > i10.maxY)) {
if (a10.route[c10] = { ...h10, ...o10 }, r10) {
const e54 = n10 === 0 ? l10 + 1 : l10 - 1, t11 = a10.route[e54], i11 = a10.vias.some((e58) => e58.x === d10.x && e58.y === d10.y);
if (!t11 || t11.z !== h10.z || d10.pcb_port_id !== undefined || i11)
return;
a10.route[l10] = { ...d10, ...o10 };
}
return s10;
}
};
var ene = ({ srj: e50, originalSrj: t10, routes: n10, newConnections: o10, syntheticConnectionNames: i10, drcEvaluator: r10, effort: s10 = 1 }) => {
let a10 = n10, c10 = _te(r10, a10), l10 = 0, h10 = 0;
const d10 = c10.length < 20 || n10.length <= 120 ? 256 : Math.max(32, Math.min(256, Math.floor(16384 * Math.max(1, s10) / n10.length))), u10 = ((e54) => {
const t11 = new Map;
for (const n11 of e54.connections)
for (const e58 of n11.pointsToConnect)
e58.pcb_port_id && t11.set(e58.pcb_port_id, e58);
return t11;
})(t10);
for (let n11 = 0;n11 < 2; n11++) {
let n12 = false;
const s11 = Ite({ routes: a10, newConnections: o10, syntheticConnectionNames: i10 });
for (const o11 of c10.filter(Ute)) {
if (l10 >= d10)
break;
if (typeof o11.pcb_trace_id != "string")
continue;
const i11 = s11.get(o11.pcb_trace_id), p10 = qte(e50, Zte(o11));
if (i11 === undefined || !p10)
continue;
const m10 = a10[i11];
let g10 = a10, f10 = c10;
e:
for (const n13 of [0, -1]) {
const o12 = n13 === 0 ? m10.route[0] : m10.route.at(-1);
if (!o12 || typeof o12.pcb_port_id != "string")
continue;
const s12 = Jte({ srj: t10, pcbPortId: o12.pcb_port_id, z: o12.z, portPositionMap: u10 });
if (!s12 || s12 === p10)
continue;
const c11 = Math.hypot(p10.width, p10.height) / 2 + Math.hypot(s12.width, s12.height) / 2 + 0.5;
if (!(Math.hypot(o12.x - p10.center.x, o12.y - p10.center.y) > c11))
for (const t11 of Qte({ terminalObstacle: s12, conflictingObstacle: p10, traceRadius: m10.traceThickness / 2 }))
for (const o13 of [false, true]) {
if (l10 >= d10)
break e;
const s13 = Kte({ routes: a10, routeIndex: i11, endpointIndex: n13, point: t11, bounds: e50.bounds, collapseAdjacent: o13 });
if (!s13)
continue;
l10++;
const c12 = _te(r10, s13);
vte(c12, f10) && (g10 = s13, f10 = c12);
}
}
g10 !== a10 && (a10 = g10, c10 = f10, h10++, n12 = true);
}
if (!n12 || c10.length === 0)
break;
}
return { routes: a10, attemptedCandidateCount: l10, acceptedCandidateCount: h10, remainingErrors: c10 };
};
var tne = ["pcb_trace_error_id", "pcb_error_id", "pcb_via_trace_clearance_error_id", "pcb_pad_trace_clearance_error_id"];
var nne = (e50, t10) => {
let n10 = e50;
const o10 = [...t10].sort(([e54], [t11]) => t11.length - e54.length);
for (const [e54, t11] of o10)
n10 = n10.replaceAll(e54, t11);
return n10;
};
var one = (e50, t10) => {
const n10 = String(e50.type ?? e50.error_type ?? "unknown");
if (n10 === "pcb_via_clearance_error")
return ((e54, t11) => {
const n11 = [...typeof e54.pcb_trace_id == "string" ? [e54.pcb_trace_id] : [], ...Array.isArray(e54.pcb_trace_ids) ? e54.pcb_trace_ids.filter((e58) => typeof e58 == "string") : []].map((e58) => nne(e58, t11)).filter((e58, t12, n12) => n12.indexOf(e58) === t12).sort(), o11 = e54.center && typeof e54.center == "object" ? e54.center : e54.pcb_center && typeof e54.pcb_center == "object" ? e54.pcb_center : undefined, i10 = typeof o11?.x == "number" && typeof o11.y == "number" ? { x: o11.x, y: o11.y } : undefined, r10 = typeof e54.pcb_via_pair_net_relation == "string" ? e54.pcb_via_pair_net_relation : undefined;
if (n11.length !== 0 && i10 && r10)
return `pcb_via_clearance_error:${JSON.stringify({ traceIds: n11, center: i10, netRelation: r10 })}`;
})(e50, t10);
for (const o11 of tne) {
const i10 = e50[o11];
if (typeof i10 == "string")
return `${n10}:${nne(i10, t10)}`;
}
const o10 = Object.fromEntries(Object.entries(e50).filter(([e54, t11]) => (e54.endsWith("_id") || e54.endsWith("_ids")) && (typeof t11 == "string" || Array.isArray(t11))).sort(([e54], [t11]) => e54.localeCompare(t11)).map(([e54, n11]) => [e54, typeof n11 == "string" ? nne(n11, t10) : n11]));
return `${n10}:${JSON.stringify(o10)}`;
};
var ine = ({ errors: e50, baselineErrors: t10, originalTraceIdByPreparedTraceId: n10 = new Map }) => {
const o10 = new Set(t10.filter((e54) => !((e58) => typeof e58.pcb_trace_error_id == "string" && e58.pcb_trace_error_id.startsWith("missing_connection_"))(e54)).map((e54) => one(e54, new Map)));
return o10.delete(undefined), e50.filter((e54) => {
const t11 = one(e54, n10);
return t11 === undefined || !o10.has(t11);
});
};
var rne = 1.5;
var sne = ({ errorsWithCenters: e50, traces: t10, layerCount: n10, defaultViaDiameter: o10, connMap: i10 }) => {
const r10 = ((e54) => e54.flatMap((e58) => {
if (e58.type !== "pcb_trace_error" || !Array.isArray(e58.pcb_port_ids) || e58.pcb_port_ids.length < 4)
return [];
const t11 = e58.center;
return t11 && typeof t11 == "object" && "x" in t11 && "y" in t11 && typeof t11.x == "number" && typeof t11.y == "number" ? [{ x: t11.x, y: t11.y }] : [];
}))(e50), s10 = new Set;
for (let e54 = 0;e54 < t10.length; e54++) {
const a10 = t10[e54], c10 = Ree(a10, e54, n10, o10, i10);
r10.some((e58) => c10.some((t11) => {
const n11 = t11.route.map((e59) => e59.x), o11 = t11.route.map((e59) => e59.y);
return Math.min(...n11) <= e58.x + rne && Math.max(...n11) >= e58.x - rne && Math.min(...o11) <= e58.y + rne && Math.max(...o11) >= e58.y - rne;
})) && s10.add(a10.pcb_trace_id);
}
return s10;
};
var ane = ({ routes: e50, otherHdRoutes: t10, obstacles: n10, colorMap: o10, layerCount: i10, connMap: r10 }) => {
const s10 = G7([...e50, ...t10], r10), a10 = new NB({ inputHdRoutes: e50, otherHdRoutes: t10, netByConnectionName: s10, obstacles: n10, colorMap: o10, layerCount: i10, connMap: r10 });
if (a10.solve(), a10.failed)
throw new Error(`Pipeline9 could not merge movable preloaded vias: ${a10.error ?? "unknown error"}`);
return a10.getMergedViaHdRoutes() ?? e50;
};
var cne = ({ errors: e50, circuitJson: t10, newTraceIds: n10 }) => {
const o10 = new Map(t10.flatMap((e54) => e54.type === "pcb_via" && typeof e54.pcb_via_id == "string" && typeof e54.pcb_trace_id == "string" ? [[e54.pcb_via_id, e54.pcb_trace_id]] : []));
return e50.map((e54) => {
const t11 = typeof e54.pcb_trace_id == "string" ? e54.pcb_trace_id : undefined, i10 = Array.isArray(e54.pcb_trace_ids) ? e54.pcb_trace_ids.filter((e58) => typeof e58 == "string") : [], r10 = [...typeof e54.pcb_via_id == "string" ? [e54.pcb_via_id] : [], ...Array.isArray(e54.pcb_via_ids) ? e54.pcb_via_ids.filter((e58) => typeof e58 == "string") : []].filter((e58, t12, n11) => n11.indexOf(e58) === t12);
if (t11 && typeof e54.pcb_trace_error_id == "string") {
const s11 = `overlap_${t11}_`, a11 = e54.pcb_trace_error_id.startsWith(s11) ? e54.pcb_trace_error_id.slice(s11.length) : undefined, c11 = a11 !== undefined && (r10.includes(a11) || o10.has(a11) && !i10.includes(a11)), l10 = i10.find((e58) => e58 !== t11 && n10.has(e58)) ?? (a11 && !c11 ? a11 : undefined);
if (!n10.has(t11) && r10.length === 0 && l10 && n10.has(l10)) {
const n11 = [l10, t11, ...i10].filter((e58, t12, n12) => n12.indexOf(e58) === t12);
return { ...e54, pcb_trace_id: l10, pcb_trace_ids: n11, pcb_trace_error_id: `overlap_${l10}_${t11}` };
}
}
const s10 = r10.flatMap((e58) => {
const t12 = o10.get(e58);
return t12 ? [t12] : [];
}).filter((e58, t12, n11) => n11.indexOf(e58) === t12), a10 = s10.length > 0 ? s10 : i10.filter((e58) => e58 !== t11), c10 = a10.find((e58) => n10.has(e58));
if (c10 && (!t11 || !n10.has(t11))) {
const n11 = [c10, ...t11 ? [t11] : [], ...i10, ...a10].filter((e58, t12, n12) => n12.indexOf(e58) === t12);
return { ...e54, pcb_trace_id: c10, pcb_trace_ids: n11, pcb_via_id: r10[0], pcb_via_ids: r10 };
}
if (r10.length > 0) {
const n11 = [...t11 ? [t11] : [], ...i10, ...a10].filter((e58, t12, n12) => n12.indexOf(e58) === t12);
return { ...e54, pcb_trace_ids: n11, pcb_via_id: r10[0], pcb_via_ids: r10 };
}
return e54;
});
};
var lne = 0.000000001;
var hne = (e50) => {
const t10 = new Set, n10 = [];
for (const o10 of e50)
for (const e54 of o10.route) {
if (e54.route_type !== "via")
continue;
const i10 = `${e54.x},${e54.y},${e54.from_layer},${e54.to_layer}`;
t10.has(i10) || (t10.add(i10), n10.push({ type: "pcb_via", pcb_via_id: `via_${n10.length}`, pcb_trace_id: o10.pcb_trace_id }));
}
return n10;
};
var dne = ({ errors: e50, circuitJson: t10, evaluatedTraceIds: n10 }) => {
const o10 = new Map(t10.flatMap((e54) => e54.type === "pcb_via" && typeof e54.pcb_via_id == "string" && typeof e54.pcb_trace_id == "string" ? [[e54.pcb_via_id, e54.pcb_trace_id]] : []));
return e50.map((e54) => {
const t11 = [...typeof e54.pcb_via_id == "string" ? [e54.pcb_via_id] : [], ...Array.isArray(e54.pcb_via_ids) ? e54.pcb_via_ids.filter((e58) => typeof e58 == "string") : []], i10 = typeof e54.pcb_trace_id == "string" ? e54.pcb_trace_id : undefined, r10 = i10 ? `overlap_${i10}_` : undefined, s10 = r10 && typeof e54.pcb_trace_error_id == "string" && e54.pcb_trace_error_id.startsWith(r10) ? e54.pcb_trace_error_id.slice(r10.length) : undefined, a10 = typeof e54.pcb_trace_error_id == "string" ? e54.pcb_trace_error_id.match(/_(via_\d+)$/)?.[1] : undefined, c10 = t11.length !== 0 || !a10 || !o10.has(a10) || s10 && n10.has(s10) ? undefined : a10, l10 = [...t11, ...c10 ? [c10] : []].filter((e58, t12, n11) => n11.indexOf(e58) === t12), h10 = [...typeof e54.pcb_trace_id == "string" ? [e54.pcb_trace_id] : [], ...Array.isArray(e54.pcb_trace_ids) ? e54.pcb_trace_ids.filter((e58) => typeof e58 == "string") : [], ...l10.flatMap((e58) => {
const t12 = o10.get(e58);
return t12 ? [t12] : [];
})].filter((e58, t12, n11) => n11.indexOf(e58) === t12);
return { ...e54, ...l10.length > 0 ? { pcb_via_id: l10[0], pcb_via_ids: l10 } : {}, ...l10.length > 0 && h10.length > 0 ? { pcb_trace_ids: h10 } : {} };
});
};
var une = (e50, t10) => Math.abs(e50.x - t10.x) <= lne && Math.abs(e50.y - t10.y) <= lne && e50.z === t10.z;
var pne = ({ trace: e50, sectionGroup: t10, syntheticConnectionName: n10, connMap: o10 }) => {
const i10 = t10.routes;
if (i10.length === 0)
throw new Error(`Pipeline9 cannot exactly repair empty preloaded section for trace "${e50.pcb_trace_id}"`);
const r10 = [];
for (const t11 of i10) {
if (r10.length === 0) {
r10.push(...t11.route);
continue;
}
const n11 = r10.at(-1);
if (t11.route[0] && une(n11, t11.route[0]))
r10.push(...t11.route.slice(1));
else {
if (!t11.route.at(-1) || !une(n11, t11.route.at(-1)))
throw new Error(`Pipeline9 cannot reconnect preloaded trace "${e50.pcb_trace_id}" for exact repair`);
r10.push(...t11.route.slice(0, -1).reverse());
}
}
const s10 = t10.routePositionStart === 0, a10 = t10.routePositionEnd === e50.route.length - 1, c10 = s10 ? e50.connectsTo?.[0] : null, l10 = a10 ? e50.connectsTo?.at(-1) : null;
return c10 && r10[0] && (r10[0] = { ...r10[0], pcb_port_id: c10 }), l10 && r10.at(-1) && (r10[r10.length - 1] = { ...r10.at(-1), pcb_port_id: l10 }), { connectionName: n10, rootConnectionName: o10.getNetConnectedToId(e50.connection_name) ?? e50.connection_name, traceThickness: Math.max(...i10.map((e54) => e54.traceThickness)), viaDiameter: Math.max(...i10.map((e54) => e54.viaDiameter)), route: r10, vias: r10.slice(0, -1).flatMap((e54, t11) => {
const n11 = r10[t11 + 1];
return e54.z !== n11.z && (o11 = e54, i11 = n11, Math.abs(o11.x - i11.x) <= lne && Math.abs(o11.y - i11.y) <= lne) ? [{ x: n11.x, y: n11.y }] : [];
var o11, i11;
}) };
};
var mne = ({ trace: e50, traceIndex: t10, layerCount: n10, defaultViaDiameter: o10, connMap: i10 }) => {
const r10 = e50.route.flatMap((e54, t11) => e54.route_type === "through_obstacle" ? [t11] : []), s10 = new Map, a10 = Ree(e50, t10, n10, o10, i10);
for (const t11 of a10) {
const { preloadedRoutePositionStart: n11, preloadedRoutePositionEnd: o11 } = t11;
if (n11 === undefined || o11 === undefined)
throw new Error(`Pipeline9 preloaded trace section is missing route positions for "${e50.pcb_trace_id}"`);
if (e50.route[n11]?.route_type === "through_obstacle")
continue;
const i11 = r10.filter((e54) => e54 < n11).length, a11 = s10.get(i11) ?? { routePositionStart: n11, routePositionEnd: o11, routes: [] };
a11.routePositionStart = Math.min(a11.routePositionStart, n11), a11.routePositionEnd = Math.max(a11.routePositionEnd, o11), a11.routes.push(t11), s10.set(i11, a11);
}
return [...s10.values()];
};
var gne = (e50, t10) => e50.map((e54) => {
const n10 = Array.isArray(e54.pcb_trace_ids) ? e54.pcb_trace_ids.filter((e58) => typeof e58 == "string") : [], o10 = typeof e54.pcb_trace_id == "string" ? e54.pcb_trace_id : undefined, i10 = o10 ? `overlap_${o10}_` : undefined, r10 = i10 && typeof e54.pcb_trace_error_id == "string" && e54.pcb_trace_error_id.startsWith(i10) ? e54.pcb_trace_error_id.slice(i10.length) : undefined, s10 = [...typeof e54.pcb_via_id == "string" ? [e54.pcb_via_id] : [], ...Array.isArray(e54.pcb_via_ids) ? e54.pcb_via_ids.filter((e58) => typeof e58 == "string") : []], a10 = r10 !== undefined && s10.includes(r10), c10 = [o10, ...n10, a10 ? undefined : r10].filter((e58) => typeof e58 == "string"), l10 = new Map;
for (const e58 of c10) {
const n11 = t10.get(e58) ?? e58, o11 = l10.get(n11) ?? new Set;
o11.add(e58), l10.set(n11, o11);
}
const h10 = [...l10].flatMap(([e58, t11]) => t11.size > 1 ? [{ solverTraceId: e58, evaluationTraceIds: [...t11] }] : []), d10 = o10 ? t10.get(o10) ?? o10 : undefined, u10 = n10.map((e58) => t10.get(e58) ?? e58), p10 = r10 ? a10 ? r10 : t10.get(r10) ?? r10 : undefined;
return d10 !== o10 || u10.some((e58, t11) => e58 !== n10[t11]) || p10 !== r10 ? { ...e54, ...o10 ? { pcb_trace_id: d10 } : {}, ...Array.isArray(e54.pcb_trace_ids) ? { pcb_trace_ids: u10 } : {}, ...d10 && p10 ? { pcb_trace_error_id: `overlap_${d10}_${p10}` } : {}, ...h10.length > 0 ? { __collapsed_trace_participants: h10 } : {} } : e54;
});
var fne = (e50, t10) => {
const n10 = e50.hdRoute.route[0], o10 = e50.hdRoute.route.at(-1);
return { name: e50.syntheticConnectionName, rootConnectionName: e50.hdRoute.rootConnectionName, __netConnectionName: e50.originalTrace.connection_name, nominalTraceWidth: e50.hdRoute.traceThickness, pointsToConnect: [{ x: n10.x, y: n10.y, layer: Po(n10.z, t10), pointId: `${e50.syntheticConnectionName}:start` }, { x: o10.x, y: o10.y, layer: Po(o10.z, t10), pointId: `${e50.syntheticConnectionName}:end` }] };
};
var _ne = ({ originalTrace: e50, repairedSections: t10 }) => {
const n10 = [];
let o10 = 0;
for (const i10 of [...t10].sort((e54, t11) => e54.routePositionStart - t11.routePositionStart)) {
if (i10.routePositionStart < o10)
throw new Error(`Pipeline9 found overlapping repaired sections for preloaded trace "${e50.pcb_trace_id}"`);
n10.push(...e50.route.slice(o10, i10.routePositionStart), ...i10.route), o10 = i10.routePositionEnd + 1;
}
return n10.push(...e50.route.slice(o10)), { ...e50, __replaces_pcb_trace_id: e50.pcb_trace_id, route: n10 };
};
var yne = class extends ai {
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;
currentPipelineStepIndex = 0;
regionalB01Params;
boundedRegionalParams;
boundedRegionalRepairStartedAt;
pipelineDef = [{ solverName: "exactRepairSolver", createSolver: () => {
if (!this.exactRepairSolver)
throw new Error("Pipeline9 exact repair stage is missing its solver");
return this.exactRepairSolver;
}, onSolved: () => this.finishExactRepair() }, { solverName: "regionalB01RepairSolver", createSolver: () => {
if (!this.regionalB01Params)
throw new Error("Pipeline9 regional B01 stage is missing its input");
return this.regionalB01RepairSolver = new Fte(this.regionalB01Params), this.regionalB01RepairSolver;
}, onSolved: () => this.finishRegionalB01Repair() }, { solverName: "boundedRegionalRepairSolver", createSolver: () => {
if (!this.boundedRegionalParams)
throw new Error("Pipeline9 bounded regional stage is missing its input");
return this.boundedRegionalRepairStartedAt = performance.now(), this.boundedRegionalRepairSolver = new Vte(this.boundedRegionalParams), this.boundedRegionalRepairSolver;
}, onSolved: () => this.finishBoundedRegionalRepair() }];
boundedRegionalRepairSolver;
regionalB01RepairSolver;
cacheIndexedDrcResult(e50, t10) {
if (this.indexedDrcCandidateCache.size >= 64) {
const e54 = this.indexedDrcCandidateCache.keys().next().value;
e54 !== undefined && this.indexedDrcCandidateCache.delete(e54);
}
this.indexedDrcCandidateCache.set(e50, t10);
}
constructor(e50) {
super(), this.params = e50, this.inputNewHdRoutes = e50.newHdRoutes, this.inputUpdatedPreloadedTraces = e50.updatedPreloadedTraces;
const t10 = e50.updatedPreloadedTraces.filter((t11) => e50.mutatedPreloadedTraceIds.has(t11.pcb_trace_id)), n10 = g7({ connections: e50.newConnections, originalConnections: e50.originalSrj.connections, layerCount: e50.layerCount, obstacles: e50.obstacles, defaultViaHoleDiameter: e50.defaultViaHoleDiameter, connMap: e50.connMap }), o10 = n10(e50.newHdRoutes), i10 = new Set(o10.map((e54) => e54.pcb_trace_id)), r10 = (({ originalPreloadedTraces: e54, mutatedPreloadedTraces: t11, newTraces: n11 }) => {
const o11 = new Set(n11.map((e58) => e58.pcb_trace_id)), i11 = new Map(t11.map((e58) => [e58.pcb_trace_id, e58])), r11 = new Set([...e54.map((e58) => e58.pcb_trace_id), ...o11]), s11 = new Map;
return { routedTraces: [...e54.filter((e58) => o11.has(e58.pcb_trace_id)).map((e58) => {
const t12 = i11.get(e58.pcb_trace_id) ?? e58, n12 = `${e58.pcb_trace_id}_preloaded`;
let o12 = n12, a11 = 2;
for (;r11.has(o12); )
o12 = `${n12}_${a11}`, a11 += 1;
return r11.add(o12), s11.set(o12, e58.pcb_trace_id), { ...t12, pcb_trace_id: o12, __replaces_pcb_trace_id: e58.pcb_trace_id };
}), ...t11.filter((e58) => !o11.has(e58.pcb_trace_id)), ...n11], originalPreloadedTraceIdByPreparedTraceId: s11 };
})({ originalPreloadedTraces: e50.originalSrj.traces ?? [], mutatedPreloadedTraces: t10, newTraces: o10 }), s10 = e50.originalSrj.minTraceToPadEdgeClearance ?? E7.traceClearance ?? 0.1, a10 = E7.viaClearance, c10 = e50.originalSrj.minViaHoleEdgeToViaHoleEdgeClearance ?? E7.viaClearance ?? 0.1, l10 = O7({ includeBoardClearance: true, inputSrj: e50.originalSrj, srjWithPointPairs: e50.srjWithPointPairs, routedTraces: [], drcOptions: { traceClearance: s10, viaClearance: c10 } }), h10 = new Set((e50.originalSrj.traces ?? []).map((e54) => e54.pcb_trace_id)), d10 = dne({ errors: l10.errors, circuitJson: l10.circuitJson, evaluatedTraceIds: h10 }), u10 = dne({ errors: l10.errorsWithCenters, circuitJson: l10.circuitJson, evaluatedTraceIds: h10 }), p10 = O7({ includeBoardClearance: true, inputSrj: e50.originalSrj, srjWithPointPairs: e50.srjWithPointPairs, routedTraces: r10.routedTraces, drcOptions: { traceClearance: s10, viaClearance: c10 } }), m10 = new Set(A7(e50.originalSrj.traces ?? [], r10.routedTraces).map((e54) => e54.pcb_trace_id)), g10 = dne({ errors: p10.errors, circuitJson: p10.circuitJson, evaluatedTraceIds: m10 }), f10 = dne({ errors: p10.errorsWithCenters, circuitJson: p10.circuitJson, evaluatedTraceIds: m10 }), _10 = { ...p10, errors: ine({ errors: g10, baselineErrors: d10, originalTraceIdByPreparedTraceId: r10.originalPreloadedTraceIdByPreparedTraceId }), errorsWithCenters: ine({ errors: f10, baselineErrors: u10, originalTraceIdByPreparedTraceId: r10.originalPreloadedTraceIdByPreparedTraceId }) }, y10 = (({ errors: e54, circuitJson: t11 }) => {
const n11 = new Map(t11.flatMap((e58) => e58.type === "pcb_via" && typeof e58.pcb_via_id == "string" && typeof e58.pcb_trace_id == "string" ? [[e58.pcb_via_id, e58.pcb_trace_id]] : [])), o11 = new Set;
for (const t12 of e54) {
const e58 = typeof t12.pcb_trace_id == "string" ? t12.pcb_trace_id : undefined, i11 = [...typeof t12.pcb_via_id == "string" ? [t12.pcb_via_id] : [], ...Array.isArray(t12.pcb_via_ids) ? t12.pcb_via_ids.filter((e59) => typeof e59 == "string") : []];
if (typeof t12.pcb_trace_id == "string" && o11.add(t12.pcb_trace_id), Array.isArray(t12.pcb_trace_ids))
for (const e59 of t12.pcb_trace_ids)
typeof e59 == "string" && o11.add(e59);
if (typeof t12.pcb_via_id == "string") {
const e59 = n11.get(t12.pcb_via_id);
e59 && o11.add(e59);
}
if (Array.isArray(t12.pcb_via_ids))
for (const e59 of t12.pcb_via_ids) {
if (typeof e59 != "string")
continue;
const t13 = n11.get(e59);
t13 && o11.add(t13);
}
const r11 = e58 ? `overlap_${e58}_` : undefined;
if (r11 && typeof t12.pcb_trace_error_id == "string" && t12.pcb_trace_error_id.startsWith(r11)) {
const e59 = t12.pcb_trace_error_id.slice(r11.length);
i11.includes(e59) || o11.add(e59);
}
}
return o11;
})({ errors: _10.errors, circuitJson: _10.circuitJson }), b10 = new Map(e50.updatedPreloadedTraces.map((e54) => [e54.pcb_trace_id, e54])), x10 = new Set;
for (const e54 of y10) {
const t11 = r10.originalPreloadedTraceIdByPreparedTraceId.get(e54);
t11 && b10.has(t11) ? x10.add(t11) : !i10.has(e54) && b10.has(e54) && x10.add(e54);
}
for (const t11 of sne({ errorsWithCenters: _10.errorsWithCenters, traces: e50.updatedPreloadedTraces, layerCount: e50.layerCount, defaultViaDiameter: e50.defaultViaDiameter, connMap: e50.connMap }))
x10.add(t11);
this.movablePreloadedSections = [];
for (const t11 of x10) {
const n11 = b10.get(t11);
if (!n11)
throw new Error(`Pipeline9 cannot find preloaded trace "${t11}" selected for exact repair`);
const o11 = e50.updatedPreloadedTraces.findIndex((e54) => e54.pcb_trace_id === t11), i11 = mne({ trace: n11, traceIndex: o11, layerCount: e50.layerCount, defaultViaDiameter: e50.defaultViaDiameter, connMap: e50.connMap });
for (const [t12, o12] of i11.entries()) {
const i12 = `pipeline9_preloaded_drc_${this.movablePreloadedSections.length}`;
this.movablePreloadedSections.push({ originalTrace: n11, originalRoutePositionStart: o12.routePositionStart, originalRoutePositionEnd: o12.routePositionEnd, syntheticConnectionName: i12, evaluationTraceId: `${n11.pcb_trace_id}__pipeline9_section_${t12}`, hdRoute: pne({ trace: n11, sectionGroup: o12, syntheticConnectionName: i12, connMap: e50.connMap }) });
}
}
this.syntheticConnectionNames = new Set(this.movablePreloadedSections.map((e54) => e54.syntheticConnectionName));
const v10 = new Set(this.movablePreloadedSections.map((e54) => e54.originalTrace.pcb_trace_id));
this.fixedPreloadedObstacleRoutes = e50.updatedPreloadedTraces.flatMap((t11, n11) => {
const o11 = Ree(t11, n11, e50.layerCount, e50.defaultViaDiameter, e50.connMap);
return v10.has(t11.pcb_trace_id) ? o11.filter((e54) => {
const n12 = e54.preloadedRoutePositionStart;
return n12 !== undefined && t11.route[n12]?.route_type === "through_obstacle";
}) : o11;
});
const I10 = new Map;
for (const [e54, t11] of this.movablePreloadedSections.entries()) {
const n11 = t11.originalTrace.pcb_trace_id, o11 = I10.get(n11) ?? [];
o11.push(e54), I10.set(n11, o11);
}
for (const t11 of (({ errors: e54, circuitJson: t12, originalTraceIdByPreparedTraceId: n11 }) => {
const o11 = new Map(t12.flatMap((e58) => e58.type === "pcb_via" && typeof e58.pcb_via_id == "string" && typeof e58.pcb_trace_id == "string" ? [[e58.pcb_via_id, e58.pcb_trace_id]] : []));
return e54.flatMap((e58) => {
if (e58.type !== "pcb_via_clearance_error" || !Array.isArray(e58.pcb_via_ids) || typeof e58.actual_clearance != "number" || e58.actual_clearance >= 0)
return [];
const t13 = e58.pcb_via_ids.flatMap((e59) => {
if (typeof e59 != "string")
return [];
const t14 = o11.get(e59);
return t14 ? [n11.get(t14) ?? t14] : [];
}).filter((e59, t14, n12) => n12.indexOf(e59) === t14);
return t13.length > 0 ? [t13] : [];
});
})({ errors: _10.errors, circuitJson: _10.circuitJson, originalTraceIdByPreparedTraceId: r10.originalPreloadedTraceIdByPreparedTraceId })) {
const n11 = t11.flatMap((e54) => I10.get(e54) ?? []).filter((e54, t12, n12) => n12.indexOf(e54) === t12);
if (n11.length === 0)
continue;
const o11 = new Set(n11), i11 = ane({ routes: n11.map((e54) => this.movablePreloadedSections[e54].hdRoute), otherHdRoutes: [...e50.newHdRoutes, ...this.fixedPreloadedObstacleRoutes, ...this.movablePreloadedSections.flatMap((e54, t12) => o11.has(t12) ? [] : [e54.hdRoute])], obstacles: e50.obstacles, colorMap: e50.colorMap, layerCount: e50.layerCount, connMap: e50.connMap });
for (let e54 = 0;e54 < n11.length; e54++)
this.movablePreloadedSections[n11[e54]].hdRoute = i11[e54];
}
const S10 = e50.newHdRoutes.length + this.movablePreloadedSections.length, C10 = _10.errors.length >= 20 && S10 > 120 ? Math.min(1, 120 * Math.max(1, e50.effort) / S10) : 1, P10 = _10.errors.length >= 200 ? C10 ** 2 : C10, M10 = Math.max(_10.errors.length >= 200 ? 2 : 8, Math.floor(32 * P10)), w10 = Math.max(_10.errors.length >= 200 ? 1 : 4, Math.floor(12 * P10));
if (this.stats = { initialJointDrcIssueCount: _10.errors.length, baselineJointDrcIssueCount: l10.errors.length, initialJointDrcIssueCountByType: _10.errors.reduce((e54, t11) => {
const n11 = String(t11.type ?? t11.error_type ?? "unknown");
return e54[n11] = (e54[n11] ?? 0) + 1, e54;
}, {}), movablePreloadedTraceCount: v10.size, movablePreloadedSectionCount: this.movablePreloadedSections.length, exactRepairConfiguredMaxIterations: M10, exactRepairConfiguredViaInPadMaxIterations: M10, exactRepairConfiguredBroadMaxIterations: w10 }, _10.errors.length === 0)
return void (this.solved = true);
const N10 = new Set(this.movablePreloadedSections.map((e54) => e54.originalTrace.pcb_trace_id)), T10 = t10.filter((e54) => !N10.has(e54.pcb_trace_id)), R10 = new Map(this.movablePreloadedSections.map((t11) => [t11.syntheticConnectionName, fne(t11, e50.layerCount)])), { traces: E10, ...A10 } = e50.srjWithPointPairs, O10 = { ...A10, connections: [...e50.srjWithPointPairs.connections, ...R10.values()] }, k10 = new UM({ ...O10, obstacles: e50.originalSrj.obstacles, minTraceWidth: e50.originalSrj.minTraceWidth, minViaDiameter: e50.originalSrj.minViaDiameter ?? e50.defaultViaDiameter }, { connMap: e50.connMap, traceClearance: s10, viaClearance: a10, includeTraceViaOwnerMetadata: true, spatialCellSize: Math.max(e50.defaultViaDiameter, e50.originalSrj.minTraceWidth) + Math.max(s10, a10) }), D10 = k10.evaluate(e50.originalSrj.traces ?? []), L10 = hne(e50.originalSrj.traces ?? []), z10 = { ...D10, errors: dne({ errors: D10.errors, circuitJson: L10, evaluatedTraceIds: h10 }), errorsWithCenters: dne({ errors: D10.errorsWithCenters, circuitJson: L10, evaluatedTraceIds: h10 }) };
let B10;
const F10 = (t11) => {
const o11 = t11.filter((e54) => !this.syntheticConnectionNames.has(e54.connectionName)), i11 = n10(o11), r11 = V7(i11, e50.originalSrj.traces ?? []), s11 = new Set, a11 = new Map, c11 = this.movablePreloadedSections.map((n11) => {
const o12 = t11.find((e54) => e54.connectionName === n11.syntheticConnectionName);
if (!o12)
throw new Error(`Pipeline9 joint DRC repair lost preloaded section "${n11.syntheticConnectionName}"`);
const i12 = n11.originalTrace.pcb_trace_id;
a11.set(n11.evaluationTraceId, i12);
const r12 = !s11.has(i12);
return s11.add(i12), { ...n11.originalTrace, pcb_trace_id: n11.evaluationTraceId, ...r12 ? { __replaces_pcb_trace_id: i12 } : { __replaces_pcb_trace_id: undefined }, route: Ro(o12, e50.layerCount, { defaultViaHoleDiameter: e50.defaultViaHoleDiameter, obstacles: e50.obstacles, connMap: e50.connMap }) };
}), l11 = new Map;
for (let e54 = 0;e54 < i11.length; e54++)
l11.set(r11[e54].pcb_trace_id, i11[e54].pcb_trace_id);
for (const e54 of this.movablePreloadedSections)
l11.set(e54.evaluationTraceId, `${e54.syntheticConnectionName}_0`);
const h11 = new Set(l11.values()), d11 = [...T10, ...c11, ...r11];
return { evaluatedTraces: A7(e50.originalSrj.traces ?? [], d11), movableTraceIds: h11, originalTraceIdByEvaluationTraceId: a11, routedTraces: d11, solverTraceIdByEvaluationTraceId: l11 };
}, j10 = ({ errors: e54, errorsWithCenters: t11, circuitJson: n11, movableTraceIds: o11, solverTraceIdByEvaluationTraceId: i11 }) => {
const r11 = n11.map((e58) => {
if (!("pcb_trace_id" in e58) || typeof e58.pcb_trace_id != "string")
return e58;
const t12 = i11.get(e58.pcb_trace_id);
return t12 ? { ...e58, pcb_trace_id: t12 } : e58;
});
return { errors: cne({ errors: gne(e54, i11), circuitJson: r11, newTraceIds: o11 }), errorsWithCenters: cne({ errors: gne(t11, i11), circuitJson: r11, newTraceIds: o11 }) };
}, $10 = { source: ri(e50.originalSrj === e50.srjWithPointPairs ? e50.originalSrj : { ...e50.originalSrj, connections: [...e50.srjWithPointPairs.connections, ...e50.originalSrj.connections] }), route: ri(e50.srjWithPointPairs) }, Y = ({ routes: t11, hdRoutes: n11 }, o11 = true) => {
const i11 = t11 ?? n11;
if (!i11)
throw new Error("Pipeline9 reference DRC repair requires HD routes");
const r11 = F10(i11), a11 = O7({ includeBoardClearance: true, connectivityMaps: $10, inputSrj: e50.originalSrj, srjWithPointPairs: e50.srjWithPointPairs, routedTraces: r11.routedTraces, drcOptions: { traceClearance: s10, viaClearance: c10, includeTraceContinuity: o11 } }), l11 = new Set(r11.evaluatedTraces.map((e54) => e54.pcb_trace_id)), h11 = dne({ errors: a11.errors, circuitJson: a11.circuitJson, evaluatedTraceIds: l11 }), p11 = dne({ errors: a11.errorsWithCenters, circuitJson: a11.circuitJson, evaluatedTraceIds: l11 }), m11 = ine({ errors: h11, baselineErrors: d10, originalTraceIdByPreparedTraceId: r11.originalTraceIdByEvaluationTraceId }), g11 = ine({ errors: p11, baselineErrors: u10, originalTraceIdByPreparedTraceId: r11.originalTraceIdByEvaluationTraceId });
return j10({ errors: m11, errorsWithCenters: g11, circuitJson: a11.circuitJson, movableTraceIds: r11.movableTraceIds, solverTraceIdByEvaluationTraceId: r11.solverTraceIdByEvaluationTraceId });
}, X10 = ({ routes: e54, hdRoutes: t11 }) => {
const n11 = e54 ?? t11;
if (!n11)
throw new Error("Pipeline9 cached reference DRC requires HD routes");
const o11 = JSON.stringify(n11);
if (B10?.candidateKey === o11)
return B10.result;
this.referenceDrcValidationCount += 1;
const i11 = Y({ routes: n11, hdRoutes: n11 });
return B10 = { candidateKey: o11, result: i11 }, i11;
};
this.cachedReferenceDrcEvaluator = X10, this.clearancePrecisionDrcEvaluator = ({ routes: e54, hdRoutes: t11 }) => Y({ routes: e54, hdRoutes: t11 }, false);
const W10 = (t11) => {
const n11 = F10(t11);
return NL(e50.srjWithPointPairs, n11.routedTraces, { minTraceWidth: e50.originalSrj.minTraceWidth, minViaDiameter: e50.originalSrj.minViaDiameter, originalSrj: e50.originalSrj, includeOriginalConnections: true, connectivityMaps: $10 });
};
let V10;
this.clearanceMarginDrcEvaluator = (e54, t11, n11) => (V10?.routes !== n11 && (V10 = { routes: n11, circuitJson: W10(n11) }), (({ circuitJson: e58, originalCircuitJson: t12, targets: n12 }) => {
const o11 = new Map(e58.filter((e59) => e59.type === "pcb_trace").map((e59) => [e59.pcb_trace_id, e59])), i11 = new Map(t12.filter((e59) => e59.type === "pcb_trace").map((e59) => [e59.pcb_trace_id, e59])), r11 = e58.filter((e59) => e59.type === "pcb_via"), s11 = new Map;
for (const t13 of e58)
t13.type === "pcb_via" ? s11.set(t13.pcb_via_id, t13) : t13.type === "pcb_smtpad" ? s11.set(t13.pcb_smtpad_id, t13) : t13.type === "pcb_plated_hole" && s11.set(t13.pcb_plated_hole_id, t13);
const a11 = [];
for (const e59 of n12) {
const n13 = e59.type === "pcb_via_trace_clearance_error", c11 = n13 ? e59.pcb_via_id : e59.pcb_pad_id;
if (!n13 && e59.type !== "pcb_pad_trace_clearance_error" || typeof e59.pcb_trace_id != "string" || typeof c11 != "string" || typeof e59.minimum_clearance != "number" || !Number.isFinite(e59.minimum_clearance) || e59.minimum_clearance <= 0)
throw new Error("Pipeline9 clearance margin requires a valid target pair");
const l11 = i11.get(e59.pcb_trace_id), h11 = t12.find((e60) => n13 ? e60.type === "pcb_via" && e60.pcb_via_id === c11 : e60.type === "pcb_smtpad" && e60.pcb_smtpad_id === c11 || e60.type === "pcb_plated_hole" && e60.pcb_plated_hole_id === c11);
if (!l11 || !h11)
throw new Error(`Pipeline9 clearance margin has no original target ${c11}/${e59.pcb_trace_id}`);
const d11 = o11.get(e59.pcb_trace_id);
let u11 = s11.get(c11);
if (n13) {
if (h11.type !== "pcb_via" || typeof h11.pcb_trace_id != "string")
throw new Error("Pipeline9 clearance margin requires the original via owner");
const e60 = i11.get(h11.pcb_trace_id);
if (!e60)
throw new Error("Pipeline9 clearance margin lost the original via owner");
const t13 = e60.route.filter((e61) => e61.route_type === "via"), n14 = t13.map((e61, t14) => ({ segment: e61, index: t14 })).filter(({ segment: e61 }) => e61.x === h11.x && e61.y === h11.y && h11.layers.includes(e61.from_layer) && h11.layers.includes(e61.to_layer)).filter(({ segment: e61 }, t14, n15) => n15.findIndex((t15) => t15.segment.from_layer === e61.from_layer && t15.segment.to_layer === e61.to_layer) === t14);
if (n14.length === 0)
throw new Error("Pipeline9 clearance margin lost the original via transition");
if (n14.length !== 1)
return { status: "unsupported-identity" };
const s12 = n14[0].index, a12 = o11.get(h11.pcb_trace_id), c12 = a12?.route.filter((e61) => e61.route_type === "via");
if (!c12 || c12.length !== t13.length || c12.some((e61, n15) => e61.from_layer !== t13[n15].from_layer || e61.to_layer !== t13[n15].to_layer))
return { status: "unsupported-identity" };
const l12 = c12[s12];
u11 = r11.filter((e61) => e61.x === l12.x && e61.y === l12.y && e61.layers.join() === h11.layers.join()).reduce((e61, t14) => !e61 || t14.outer_diameter > e61.outer_diameter ? t14 : e61, undefined);
}
if (!(d11 && u11 && ("x" in u11) && ("y" in u11)))
return { status: "unsupported-identity" };
const p11 = { minClearance: e59.minimum_clearance + 1 }, m11 = n13 ? TM([d11, u11], p11) : NM([d11, u11], p11), g11 = e59.minimum_clearance + Ste;
for (const t13 of m11) {
const n14 = t13.actual_clearance;
if (typeof n14 != "number" || !Number.isFinite(n14))
throw new Error("Pipeline9 clearance margin requires a finite measurement");
n14 >= g11 || a11.push({ ...e59, ...u11.type === "pcb_via" ? { pcb_via_id: u11.pcb_via_id, pcb_via_ids: [u11.pcb_via_id] } : {}, actual_clearance: n14, minimum_clearance: g11, center: { x: u11.x, y: u11.y } });
}
}
return { status: "measured", errors: a11 };
})({ circuitJson: W10(e54), originalCircuitJson: V10.circuitJson, targets: t11 })), this.clearancePrecisionIndexedDrcEvaluator = ({ routes: e54, hdRoutes: t11 }) => {
const n11 = e54 ?? t11;
if (!n11)
throw new Error("Pipeline9 clearance ranking requires HD routes");
const o11 = F10(n11);
return k10.evaluate(o11.evaluatedTraces);
};
const H10 = ({ routes: e54, hdRoutes: t11 }) => {
const n11 = e54 ?? t11;
if (!n11)
throw new Error("Pipeline9 joint DRC repair requires HD routes");
const o11 = JSON.stringify(n11), i11 = this.indexedDrcCandidateCache.get(o11);
if (i11 !== undefined)
return this.indexedDrcCacheHitCount += 1, i11;
const r11 = performance.now();
this.indexedDrcEvaluationCount += 1;
const s11 = F10(n11), a11 = k10.evaluate(s11.evaluatedTraces), c11 = hne(s11.evaluatedTraces), l11 = new Set(s11.evaluatedTraces.map((e58) => e58.pcb_trace_id)), h11 = dne({ errors: a11.errors, circuitJson: c11, evaluatedTraceIds: l11 }), d11 = dne({ errors: a11.errorsWithCenters, circuitJson: c11, evaluatedTraceIds: l11 }), u11 = ine({ errors: h11, baselineErrors: z10.errors, originalTraceIdByPreparedTraceId: s11.originalTraceIdByEvaluationTraceId }), p11 = ine({ errors: d11, baselineErrors: z10.errorsWithCenters, originalTraceIdByPreparedTraceId: s11.originalTraceIdByEvaluationTraceId });
if (u11.length === 0) {
const e58 = this.referenceDrcValidationCount, t12 = X10({ routes: n11, hdRoutes: n11 }), i12 = Array.isArray(t12) ? t12 : t12.errors;
return this.referenceDrcValidationCount > e58 && i12.length > 0 && (this.referenceDrcFalseNegativeCount += 1), this.indexedDrcEvaluationTimeMs += performance.now() - r11, this.cacheIndexedDrcResult(o11, t12), t12;
}
const m11 = j10({ errors: u11, errorsWithCenters: p11, circuitJson: c11, movableTraceIds: s11.movableTraceIds, solverTraceIdByEvaluationTraceId: s11.solverTraceIdByEvaluationTraceId });
return this.indexedDrcEvaluationTimeMs += performance.now() - r11, this.cacheIndexedDrcResult(o11, m11), m11;
};
this.drcEvaluator = H10, this.exactRepairSolver = new pL({ srj: O10, hdRoutes: [...e50.newHdRoutes, ...this.movablePreloadedSections.map((e54) => e54.hdRoute)], connMap: e50.connMap, effort: e50.effort, viaHoleDiameter: e50.defaultViaHoleDiameter, drcEvaluator: H10, viaInPadDrcEvaluator: H10, maxIterations: M10, enableBroadFallback: false, enableLargeBoardBroadFallback: false, enableTargetedErrorSweep: true, enableTraceViaOwnerTargeting: true, enablePostSolveClearanceRelaxation: false, enableSafeTraceLayerMoves: true, enableViaInPadLayerMoves: e50.originalSrj.allowViaInPad ?? false, viaInPadMaxIterations: M10, broadMaxIterations: w10, broadPassMultiplier: 3 * P10 }), this.activeSubSolver = this.exactRepairSolver, this.MAX_ITERATIONS = this.exactRepairSolver.MAX_ITERATIONS + 1;
}
getSolverName() {
return "Pipeline9JointDrcRepairSolver";
}
_step() {
const e50 = this.pipelineDef[this.currentPipelineStepIndex];
if (e50) {
if (this.activeSubSolver) {
const t10 = this.activeSubSolver;
return t10.step(), this.MAX_ITERATIONS = Math.max(this.MAX_ITERATIONS, this.iterations + t10.MAX_ITERATIONS - t10.iterations + 2), void (t10.failed ? (this.failed = true, this.error = t10.error, this.activeSubSolver = null) : t10.solved && (e50.onSolved(), this.activeSubSolver = null, this.currentPipelineStepIndex++));
}
this.activeSubSolver = e50.createSolver(), this.MAX_ITERATIONS = Math.max(this.MAX_ITERATIONS, this.iterations + this.activeSubSolver.MAX_ITERATIONS + 2);
} else
this.solved = true;
}
computeProgress() {
return this.solved ? 1 : Math.max(this.progress, (this.currentPipelineStepIndex + (this.activeSubSolver?.progress ?? 0)) / this.pipelineDef.length);
}
getCurrentPhase() {
return this.pipelineDef[this.currentPipelineStepIndex]?.solverName ?? "none";
}
finishExactRepair() {
if (!this.exactRepairSolver)
throw new Error("Pipeline9 post-exact repair requires the exact solver");
let e50 = this.exactRepairSolver.getOutput();
const t10 = this.exactRepairSolver.stats.finalDrcIssueCount, n10 = typeof t10 == "number" && Number.isFinite(t10) && t10 >= 0 ? t10 : undefined;
let o10, i10 = 0, r10 = 0, s10 = 0, a10 = false;
const c10 = this.cachedReferenceDrcEvaluator({ traces: [], routes: e50, hdRoutes: e50 }), l10 = Array.isArray(c10) ? c10 : c10.errors;
if (o10 = l10.length, l10.length > 0) {
const t11 = (({ srj: e54, routes: t12, newConnections: n11, syntheticConnectionNames: o11, connMap: i11, indexedDrcEvaluator: r11, candidateDrcEvaluator: s11, marginDrcEvaluator: a11, drcEvaluator: c11, initialErrors: l11, initialErrorsWithCenters: h11 = l11 }) => {
const d11 = { routes: t12, attemptedCandidateCount: 0, candidateValidationCount: 0, referenceValidationCount: 0, repaired: false };
if ((e54.traces?.length ?? 0) > 0 || o11.size > 0)
return d11;
if (l11.length === 0)
return d11;
const u10 = Ite({ routes: t12, newConnections: n11, syntheticConnectionNames: o11 }), p10 = new Map;
for (const t13 of e54.obstacles)
for (const e58 of [t13.obstacleId, t13.circuitJsonMetadata?.pcb_smtpad_id, t13.circuitJsonMetadata?.pcb_plated_hole_id, t13.connectedTo[0]])
typeof e58 == "string" && p10.set(e58, t13.center);
const m10 = Mte({ errors: l11, errorsWithCenters: h11, routeIndexByTraceId: u10, padPositionById: p10 });
if (!m10)
return d11;
let g10 = m10;
const f10 = m10.errors, _10 = m10.errors.map((e58) => ({ ...e58, minimum_clearance: e58.minimum_clearance + Ste })), y10 = Pte(_10);
if (y10 === undefined)
return d11;
let b10 = { errors: _10, deficit: y10 }, x10 = t12, v10 = 0, I10 = 0, S10 = 0;
for (let n12 = 0;n12 < 8; n12++) {
const n13 = new Map;
for (const e58 of [...b10.errors, ...g10.errors]) {
const t13 = JSON.stringify([e58.type, e58.pcb_trace_id, e58.pcb_pad_id, e58.pcb_via_id]);
n13.set(t13, e58);
}
const o12 = [...n13.values()];
let l12;
for (const t13 of Cte) {
const n14 = xO(x10);
if (!wD(e54, n14, o12, u10, t13, i11, true, true, true, false))
continue;
const s12 = Gk(n14);
v10++;
const a12 = r11({ traces: [], routes: s12, hdRoutes: s12 }), c12 = Pte(Array.isArray(a12) ? a12 : a12.errors);
c12 !== undefined && (!l12 || c12 < l12.deficit) && (l12 = { routes: s12, deficit: c12 });
}
if (!l12)
break;
I10++;
const h12 = s11({ traces: [], routes: l12.routes, hdRoutes: l12.routes }), d12 = Array.isArray(h12) ? h12 : h12.errors, m11 = Mte({ errors: d12, errorsWithCenters: Array.isArray(h12) ? h12 : h12.errorsWithCenters ?? h12.errors, routeIndexByTraceId: u10, padPositionById: p10 });
if (!m11)
break;
const _11 = a11(l12.routes, f10, t12);
if (_11.status === "unsupported-identity")
break;
const y11 = _11.errors, C10 = Mte({ errors: y11, errorsWithCenters: y11, routeIndexByTraceId: u10, padPositionById: p10 });
if (!C10)
break;
if (d12.length === 0 && y11.length === 0) {
S10++;
const e58 = c11({ traces: [], routes: l12.routes, hdRoutes: l12.routes });
if ((Array.isArray(e58) ? e58 : e58.errors).length === 0)
return { routes: l12.routes, attemptedCandidateCount: v10, candidateValidationCount: I10, referenceValidationCount: S10, repaired: true };
break;
}
if (m11.deficit + C10.deficit >= g10.deficit + b10.deficit - 0.000000001)
break;
x10 = l12.routes, g10 = m11, b10 = C10;
}
return { routes: t12, attemptedCandidateCount: v10, candidateValidationCount: I10, referenceValidationCount: S10, repaired: false };
})({ srj: this.params.srj, routes: e50, newConnections: this.params.newConnections, syntheticConnectionNames: this.syntheticConnectionNames, connMap: this.params.connMap, indexedDrcEvaluator: this.clearancePrecisionIndexedDrcEvaluator, candidateDrcEvaluator: this.clearancePrecisionDrcEvaluator, marginDrcEvaluator: this.clearanceMarginDrcEvaluator, drcEvaluator: this.cachedReferenceDrcEvaluator, initialErrors: l10, initialErrorsWithCenters: Array.isArray(c10) ? c10 : c10.errorsWithCenters ?? c10.errors });
i10 = t11.attemptedCandidateCount, r10 = t11.candidateValidationCount, s10 = t11.referenceValidationCount, a10 = t11.repaired, t11.repaired && (e50 = t11.routes, o10 = 0);
}
if (o10 === 0)
return this.combinedOutput = e50, this.stats = { ...this.stats, ...this.exactRepairSolver.stats, postExactIndexedDrcIssueCount: n10, postExactReferenceValidationAttempted: true, postExactReferenceDrcIssueCount: 0, postExactReferenceAccepted: true, clearancePrecisionCandidateCount: i10, clearancePrecisionCandidateValidationCount: r10, clearancePrecisionReferenceValidationCount: s10, clearancePrecisionRepaired: a10, boundedRegionalRepairMaxRegions: 0, boundedRegionalRepairMaxCandidateAttempts: 0, boundedRegionalRepairMaxPathSearchNodes: 0, boundedRegionalRepairAttemptedRegionCount: 0, boundedRegionalRepairAcceptedRegionCount: 0, boundedRegionalRepairCandidateAttemptCount: 0, boundedRegionalRepairPathSearchNodeCount: 0, boundedRegionalRepairReferenceValidationCount: 0, boundedRegionalRepairRepaired: false, boundedRegionalRepairTimeMs: 0, regionalB01RepairCandidateCount: 0, regionalB01RepairAcceptedCount: 0, regionalB01RepairFallbackCandidateCount: 0, regionalB01RepairCandidateSearchCount: 0, regionalB01RepairCandidateSearchBudget: 0, regionalB01RepairCandidateSearchBudgetExhausted: false, regionalB01RepairSafeTraceLayerSkippedForBudget: false, regionalB01RepairRemainingDrcIssueCount: 0, regionalB01RepairPreloadEligibleDrcIssueCount: 0, regionalB01RepairAttempted: false, 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 = true);
const h10 = ene({ srj: this.params.srj, originalSrj: this.params.originalSrj, routes: e50, newConnections: this.params.newConnections, syntheticConnectionNames: this.syntheticConnectionNames, drcEvaluator: this.drcEvaluator, effort: this.params.effort }), d10 = (({ routes: e54, newConnections: t11, syntheticConnectionNames: n11, fixedPreloadedObstacleRoutes: o11, updatedPreloadedTraces: i11 }) => {
const r11 = new Set, s11 = Object.assign(new Set, { collidingFixedTraceIds: r11 }), a11 = Ite({ routes: e54, newConnections: t11, syntheticConnectionNames: n11 }), c11 = new Set;
for (const [t12, o12] of a11)
n11.has(e54[o12].connectionName) ? s11.add(t12) : c11.add(t12);
for (const e58 of o11) {
const t12 = i11[e58.preloadedTraceIndex];
if (!t12)
throw new Error(`Pipeline9 fixed preload route has invalid trace index ${e58.preloadedTraceIndex}`);
c11.has(t12.pcb_trace_id) ? r11.add(t12.pcb_trace_id) : s11.add(t12.pcb_trace_id);
}
return s11;
})({ routes: h10.routes, newConnections: this.params.newConnections, syntheticConnectionNames: this.syntheticConnectionNames, fixedPreloadedObstacleRoutes: this.fixedPreloadedObstacleRoutes, updatedPreloadedTraces: this.params.updatedPreloadedTraces });
this.regionalB01Params = { srj: this.params.srj, routes: h10.routes, fixedObstacleRoutes: this.fixedPreloadedObstacleRoutes, newConnections: this.params.newConnections, syntheticConnectionNames: this.syntheticConnectionNames, drcEvaluator: this.drcEvaluator, initialErrors: h10.remainingErrors, allowTracePairRepair: true, preloadRepairTraceIds: d10, 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 ?? 0.15, effort: this.params.effort }, this.stats = { ...this.stats, ...this.exactRepairSolver.stats, postExactIndexedDrcIssueCount: n10, postExactReferenceValidationAttempted: true, postExactReferenceDrcIssueCount: o10, postExactReferenceAccepted: false, clearancePrecisionCandidateCount: i10, clearancePrecisionCandidateValidationCount: r10, clearancePrecisionReferenceValidationCount: s10, clearancePrecisionRepaired: a10, regionalB01RepairTraceIdCount: d10.size + (d10.collidingFixedTraceIds?.size ?? 0), terminalEscapeCandidateCount: h10.attemptedCandidateCount, terminalEscapeAcceptedCount: h10.acceptedCandidateCount };
}
finishRegionalB01Repair() {
if (!this.regionalB01RepairSolver?.solved)
throw new Error("Pipeline9 regional B01 stage must solve before completion");
const e50 = this.regionalB01RepairSolver.getResult(), t10 = this.cachedReferenceDrcEvaluator({ traces: [], routes: e50.routes, hdRoutes: e50.routes }), n10 = ((e54, t11, n11) => {
if (!Number.isFinite(n11) || n11 <= 0)
throw new Error("Pipeline9 regional repair effort must be positive and finite");
const o10 = Math.max(1, n11);
return { maxRegions: Math.ceil(24 * o10), maxCandidateAttempts: Math.ceil(4096 * o10), maxPathSearchNodes: Math.ceil(40000000 * o10), initialMaxRegions: Math.ceil(4 * o10), initialMaxCandidateAttempts: Math.ceil(1024 * o10), initialMaxPathSearchNodes: Math.ceil(2000000 * o10), regionsPerAcceptedRepair: 2, candidateAttemptsPerAcceptedRepair: 512, pathSearchNodesPerAcceptedRepair: 2000000, maxCandidateAttemptsPerRegion: 512, maxPathSearchNodesPerCall: 1e6, pathGridSizeScale: 2, pathHeuristicWeight: 3, revisitChangedRegions: true, regionSizes: [16, 32] };
})(e50.routes.length, (Array.isArray(t10) ? t10 : t10.errors).length, this.params.effort);
this.boundedRegionalParams = { connMap: this.params.connMap, originalSrj: { ...this.params.originalSrj, connections: [...this.params.originalSrj.connections, ...this.params.newConnections] }, routes: e50.routes, viaHoleDiameter: this.params.defaultViaHoleDiameter, syntheticConnectionNames: this.syntheticConnectionNames, drcEvaluator: this.cachedReferenceDrcEvaluator, budget: n10 };
}
finishBoundedRegionalRepair() {
if (!this.boundedRegionalRepairSolver?.solved || !this.regionalB01RepairSolver?.solved || !this.boundedRegionalParams?.budget || this.boundedRegionalRepairStartedAt === undefined)
throw new Error("Pipeline9 bounded regional stage is missing its completed inputs");
const e50 = this.regionalB01RepairSolver.getResult(), t10 = this.boundedRegionalRepairSolver.getResult(), n10 = this.boundedRegionalParams.budget;
this.combinedOutput = t10.routes, this.stats = { ...this.stats, boundedRegionalRepairMaxRegions: n10.maxRegions, boundedRegionalRepairMaxCandidateAttempts: n10.maxCandidateAttempts, boundedRegionalRepairMaxPathSearchNodes: n10.maxPathSearchNodes, boundedRegionalRepairAttemptedRegionCount: t10.attemptedRegionCount, boundedRegionalRepairAcceptedRegionCount: t10.acceptedRegionCount, boundedRegionalRepairCandidateAttemptCount: t10.candidateAttemptCount, boundedRegionalRepairPathSearchNodeCount: t10.pathSearchNodeCount, boundedRegionalRepairReferenceValidationCount: t10.referenceValidationCount, boundedRegionalRepairRepaired: t10.repaired, boundedRegionalRepairPublishedDrcIssueCount: t10.publishedDrcIssueCount, boundedRegionalRepairTimeMs: performance.now() - this.boundedRegionalRepairStartedAt, regionalB01RepairCandidateCount: e50.attemptedCandidateCount, regionalB01RepairAcceptedCount: e50.acceptedCandidateCount, regionalB01RepairFallbackCandidateCount: e50.fallbackCandidateCount, regionalB01RepairCandidateSearchCount: e50.candidateSearchCount, regionalB01RepairCandidateSearchBudget: e50.candidateSearchBudget, regionalB01RepairCandidateSearchBudgetExhausted: e50.candidateSearchBudgetExhausted, regionalB01RepairSafeTraceLayerSkippedForBudget: e50.safeTraceLayerRepairSkippedForBudget, regionalB01RepairRemainingDrcIssueCount: e50.remainingDrcIssueCount, regionalB01RepairPreloadEligibleDrcIssueCount: e50.preloadEligibleDrcIssueCount, regionalB01RepairAttempted: e50.preloadRepairAttempted, referenceDrcValidationCount: this.referenceDrcValidationCount, referenceDrcFalseNegativeCount: this.referenceDrcFalseNegativeCount, indexedDrcEvaluationCount: this.indexedDrcEvaluationCount, indexedDrcCacheHitCount: this.indexedDrcCacheHitCount, indexedDrcEvaluationTimeMs: this.indexedDrcEvaluationTimeMs, indexedDrcCandidateCacheSize: this.indexedDrcCandidateCache.size, indexedDrcCandidateCacheCapacity: 64 }, this.solved = true;
}
getCombinedOutput() {
return this.combinedOutput ?? this.exactRepairSolver?.getOutput() ?? this.inputNewHdRoutes;
}
getOutput() {
return this.getCombinedOutput().filter((e50) => !this.syntheticConnectionNames.has(e50.connectionName));
}
getUpdatedPreloadedTraces() {
const e50 = new Map(this.getCombinedOutput().map((e54) => [e54.connectionName, e54])), t10 = new Map;
for (const n11 of this.movablePreloadedSections) {
const o10 = e50.get(n11.syntheticConnectionName);
if (!o10)
throw new Error(`Pipeline9 joint DRC repair output is missing "${n11.syntheticConnectionName}"`);
const i10 = n11.originalTrace.pcb_trace_id, r10 = t10.get(i10) ?? [];
r10.push({ routePositionStart: n11.originalRoutePositionStart, routePositionEnd: n11.originalRoutePositionEnd, route: Ro(o10, this.params.layerCount, { defaultViaHoleDiameter: this.params.defaultViaHoleDiameter, obstacles: this.params.obstacles, connMap: this.params.connMap }) }), t10.set(i10, r10);
}
const n10 = new Map([...t10].map(([e54, t11]) => {
const n11 = this.inputUpdatedPreloadedTraces.find((t12) => t12.pcb_trace_id === e54);
if (!n11)
throw new Error(`Pipeline9 cannot find preloaded trace "${e54}" while rebuilding repaired sections`);
return [e54, _ne({ originalTrace: n11, repairedSections: t11 })];
}));
return this.inputUpdatedPreloadedTraces.map((e54) => n10.get(e54.pcb_trace_id) ?? e54);
}
getMutatedPreloadedTraces() {
const e50 = new Set([...this.params.mutatedPreloadedTraceIds, ...this.movablePreloadedSections.map((e54) => e54.originalTrace.pcb_trace_id)]);
return this.getUpdatedPreloadedTraces().filter((t10) => e50.has(t10.pcb_trace_id));
}
visualize() {
return this.exactRepairSolver?.visualize() ?? {};
}
};
var bne = 0.000001;
var xne = (e50, t10, n10) => {
const o10 = go(e50, n10), i10 = go(t10, n10);
return Array.from({ length: Math.abs(i10 - o10) + 1 }, (e54, t11) => Math.min(o10, i10) + t11);
};
var vne = (e50) => e50.route_type === "wire";
var Ine = (e50, t10, n10) => e50.portPoints.filter((e54) => e54.availableZ.includes(n10) && !(e54._preloadedTracePortAssignments ?? []).some((e58) => e58.z === n10 && e58.fixedNetId !== t10.fixedNetId)).map((e54) => ({ portPoint: e54, distance: xt(e54, t10.start, t10.end) })).sort((e54, t11) => e54.distance - t11.distance || e54.portPoint.distToCentermostPortOnZ - t11.portPoint.distToCentermostPortOnZ || e54.portPoint.segmentPortPointId.localeCompare(t11.portPoint.segmentPortPointId))[0]?.portPoint;
var Sne = (e50, t10, n10) => {
e50._preloadedFixedNetIds = [...new Set([...e50._preloadedFixedNetIds ?? [], t10.fixedNetId])].sort();
const o10 = t10.end.x - t10.start.x, i10 = t10.end.y - t10.start.y, r10 = o10 * o10 + i10 * i10, s10 = r10 === 0 ? 0 : Math.max(0, Math.min(1, ((e50.x - t10.start.x) * o10 + (e50.y - t10.start.y) * i10) / r10)), a10 = { traceId: t10.traceId, fixedNetId: t10.fixedNetId, routePosition: t10.routePositionStart + s10 * (t10.routePositionEnd - t10.routePositionStart), tracePoint: { x: t10.start.x + s10 * o10, y: t10.start.y + s10 * i10 }, z: n10 }, c10 = e50._preloadedTracePortAssignments ?? [];
c10.some((e54) => e54.traceId === a10.traceId && e54.fixedNetId === a10.fixedNetId && e54.z === a10.z && Math.abs(e54.routePosition - a10.routePosition) <= bne) || (e50._preloadedTracePortAssignments = [...c10, a10].sort((e54, t11) => e54.traceId.localeCompare(t11.traceId) || e54.routePosition - t11.routePosition || e54.z - t11.z));
};
var Cne = class extends ai {
constructor(e50, t10) {
super(), this.sharedEdgeSegments = e50, this.srj = t10, this.MAX_ITERATIONS = 1, this.primitives = ((e54) => {
const t11 = [], n10 = ri(e54);
for (const o10 of e54.traces ?? []) {
if (!o10.connection_name)
throw new Error(`Preloaded trace "${o10.pcb_trace_id}" is missing a connection name`);
const i10 = n10.getNetConnectedToId(o10.connection_name) ?? o10.connection_name;
for (const [n11, r10] of o10.route.entries())
if (r10.route_type === "via")
t11.push({ traceId: o10.pcb_trace_id, fixedNetId: i10, connectionName: o10.connection_name, routePositionStart: n11, routePositionEnd: n11, zLayers: xne(r10.from_layer, r10.to_layer, e54.layerCount), start: r10, end: r10 });
else if (r10.route_type === "through_obstacle")
t11.push({ traceId: o10.pcb_trace_id, fixedNetId: i10, connectionName: o10.connection_name, routePositionStart: n11, routePositionEnd: n11 + 1, zLayers: xne(r10.from_layer, r10.to_layer, e54.layerCount), start: r10.start, end: r10.end });
else if (r10.route_type === "jumper") {
const s10 = go(r10.layer, e54.layerCount);
for (const [e58, a10] of [r10.start, r10.end].entries())
t11.push({ traceId: o10.pcb_trace_id, fixedNetId: i10, connectionName: o10.connection_name, routePositionStart: n11 + e58, routePositionEnd: n11 + e58, zLayers: [s10], start: a10, end: a10 });
}
for (let n11 = 0;n11 < o10.route.length - 1; n11++) {
const r10 = o10.route[n11], s10 = o10.route[n11 + 1];
vne(r10) && vne(s10) && r10.layer === s10.layer && t11.push({ traceId: o10.pcb_trace_id, fixedNetId: i10, connectionName: o10.connection_name, routePositionStart: n11, routePositionEnd: n11 + 1, zLayers: [go(r10.layer, e54.layerCount)], start: r10, end: s10 });
}
}
return t11;
})(t10);
}
sharedEdgeSegments;
srj;
primitives;
getSolverName() {
return "PreloadedTraceGraphSolver";
}
_step() {
for (const e54 of this.primitives)
for (const t11 of this.sharedEdgeSegments)
if (!(BJ(e54.start, e54.end, t11.start, t11.end) > bne))
for (const n10 of e54.zLayers) {
if (!t11.availableZ.includes(n10))
continue;
const o10 = Ine(t11, e54, n10);
o10 && Sne(o10, e54, n10);
}
const e50 = this.sharedEdgeSegments.flatMap((e54) => e54.portPoints), t10 = e50.filter((e54) => (e54._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: e50.length, outputPortCount: e50.length, preloadedPortCount: t10.length, tracePortAssignmentCount: t10.reduce((e54, t11) => e54 + (t11._preloadedTracePortAssignments?.length ?? 0), 0), topologyChanged: false }, this.solved = true;
}
getOutput() {
if (!this.solved)
throw new Error("PreloadedTraceGraphSolver has not solved yet");
return this.sharedEdgeSegments;
}
};
var Pne = class extends L0 {
_step() {
if (this.error = D0(this.inputSrj), this.error)
return void (this.failed = true);
const { traces: e50, ...t10 } = this.inputSrj, n10 = O0(t10), o10 = O0(C0(k0(n10)));
this.error = D0(o10), this.error ? this.failed = true : (this.outputSrj = e50 === undefined ? o10 : { ...o10, traces: e50 }, this.solved = true);
}
};
function Mne(e50) {
return new Set((e50 ?? []).filter((e54) => e54._isComponentTopologyNode).map((e54) => e54.capacityMeshNodeId));
}
function wne(e50, t10) {
return e50.nodeIds.some((e54) => t10.has(e54));
}
function Nne({ sharedEdgeSegments: e50, componentCapacityMeshNodeIds: t10 }) {
return e50.filter((e54) => !wne(e54, t10));
}
function Tne(e50, t10, n10, o10 = {}) {
return { solverName: e50, solverClass: t10, getConstructorParams: n10, onSolved: o10.onSolved };
}
var Rne = class extends ai {
constructor(e50, t10 = {}) {
super(), this.srj = e50, this.opts = t10;
const n10 = O0(e50);
this.originalSrj = n10, this.opts = { ...t10 };
const o10 = this.opts;
if (this.effort = o10.effort ?? 1, this.MAX_ITERATIONS = 1e8 * this.effort, this.maxNodeDimension = o10.maxNodeDimension ?? 15, this.maxNodeRatio = o10.maxNodeRatio ?? 6, this.minNodeArea = o10.minNodeArea ?? 0.1 ** 2, this.visualizationTraceColorMode = o10.visualizationTraceColorMode ?? "layer", this.setSimpleRouteJson(n10), o10.capacityDepth === undefined) {
const e54 = this.srj.bounds.maxX - this.srj.bounds.minX, t11 = this.srj.bounds.maxY - this.srj.bounds.minY, n11 = Math.max(e54, t11), i10 = o10.targetMinCapacity ?? 0.5;
o10.capacityDepth = tz(n11, i10);
}
this.cacheProvider = o10.cacheProvider === undefined ? io() : o10.cacheProvider === null ? null : o10.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;
effortCleanupSolver;
maxNodeDimension;
maxNodeRatio;
minNodeArea;
visualizationTraceColorMode;
startTimeOfPhase;
endTimeOfPhase;
timeSpentOnPhase;
activeSubSolver = null;
connMap;
srjWithEscapeViaLocations;
srjWithPointPairs;
originalSrj;
capacityNodes = null;
capacityEdges = null;
sharedEdgeSegmentsWithNecessaryCrampedPortPoints;
highDensityNodePortPoints;
cacheProvider = null;
pipelineDef = [Tne("preprocessSimpleRouteJsonSolver", Pne, (e50) => [e50.originalSrj, { traceColorMode: e50.visualizationTraceColorMode }], { onSolved: (e50) => {
e50.setSimpleRouteJson(e50.preprocessSimpleRouteJsonSolver.getOutputSimpleRouteJson());
} }), Tne("componentDetectionSolver", m6, (e50) => [{ inputSrj: e50.srj }]), Tne("escapeViaLocationSolver", JJ, (e50) => [e50.srj, { viaDiameter: e50.viaDiameter, minTraceWidth: e50.minTraceWidth, obstacleMargin: e50.srj.defaultObstacleMargin ?? 0.15 }], { onSolved: (e50) => {
e50.srjWithEscapeViaLocations = e50.escapeViaLocationSolver?.getOutputSimpleRouteJson();
} }), Tne("netToPointPairsSolver", Tz, (e50) => {
const t10 = e50.srjWithEscapeViaLocations ?? e50.srj;
return [t10, e50.colorMap, si(t10)];
}, { onSolved: (e50) => {
e50.srjWithPointPairs = e50.netToPointPairsSolver?.getNewSimpleRouteJson(), e50.colorMap = Ao(e50.srjWithPointPairs, e50.connMap), e50.connMap = ri(e50.srjWithPointPairs);
} }), Tne("topologyPlanningSolver", B6, (e50) => [{ inputSrj: e50.srjWithPointPairs, componentDetectionOutput: e50.componentDetectionSolver.getOutput(), viaDiameter: e50.viaDiameter, obstacleMargin: e50.srj.defaultObstacleMargin ?? 0.15 }], { onSolved: (e50) => {
e50.topologyPlanningSolver.getOutput();
e50.globalTopologyGeneratorSolver = e50.topologyPlanningSolver.globalTopologySolver, e50.componentTopologyGeneratorSolver = new $6(e50.topologyPlanningSolver);
} }), Tne("topologyMergingSolver", L6, (e50) => {
const t10 = e50.topologyPlanningSolver.getOutput();
return [{ layerCount: e50.srj.layerCount, nodeGroups: [{ groupId: "global", nodes: t10.globalMeshNodes, isComponent: false }, ...t10.componentMeshNodes.map((e54, t11) => ({ groupId: `component-${t11}`, nodes: e54, isComponent: true }))] }];
}, { onSolved: (e50) => {
e50.capacityNodes = e50.topologyMergingSolver.getOutput();
} }), Tne("nodeDimensionSubdivisionSolver", SU, (e50) => [e50.capacityNodes, e50.maxNodeDimension, e50.maxNodeRatio, e50.minNodeArea], { onSolved: (e50) => {
e50.capacityNodes = e50.nodeDimensionSubdivisionSolver.outputNodes;
} }), Tne("edgeSolver", pi, (e50) => [e50.capacityNodes], { onSolved: (e50) => {
e50.capacityEdges = e50.edgeSolver?.edges;
} }), Tne("availableSegmentPointSolver", li, (e50) => [{ nodes: e50.capacityNodes, edges: e50.capacityEdges || [], traceWidth: e50.minTraceWidth, colorMap: e50.colorMap, shouldReturnCrampedPortPoints: true }]), Tne("necessaryCrampedPortPointSolver", zH, (e50) => {
const t10 = Mne(e50.capacityNodes);
return [{ capacityMeshNodes: e50.capacityNodes.filter((e54) => !t10.has(e54.capacityMeshNodeId)), sharedEdgeSegments: Nne({ sharedEdgeSegments: e50.availableSegmentPointSolver.getOutput(), componentCapacityMeshNodeIds: t10 }), simpleRouteJson: e50.srjWithPointPairs }];
}, { onSolved: (e50) => {
const t10 = Mne(e50.capacityNodes);
e50.sharedEdgeSegmentsWithNecessaryCrampedPortPoints = function({ originalSharedEdgeSegments: e54, filteredSharedEdgeSegments: t11, componentCapacityMeshNodeIds: n10 }) {
const o10 = new Map(t11.map((e58) => [e58.edgeId, e58]));
return e54.map((e58) => wne(e58, n10) ? e58 : o10.get(e58.edgeId) ?? e58);
}({ originalSharedEdgeSegments: e50.availableSegmentPointSolver.getOutput(), filteredSharedEdgeSegments: e50.necessaryCrampedPortPointSolver.getOutput(), componentCapacityMeshNodeIds: t10 });
} }), Tne("preloadedTraceGraphSolver", Cne, (e50) => [e50.sharedEdgeSegmentsWithNecessaryCrampedPortPoints, e50.srjWithPointPairs]), Tne("portPointPathingSolver", DJ, (e50) => {
const t10 = e50.sharedEdgeSegmentsWithNecessaryCrampedPortPoints ?? e50.necessaryCrampedPortPointSolver?.getOutput() ?? e50.availableSegmentPointSolver.getOutput(), { graph: n10, connections: o10 } = JH({ capacityMeshNodes: e50.capacityNodes, layerCount: e50.srj.layerCount, connectivityMap: e50.connMap, segmentPortPoints: t10.flatMap((e54) => e54.portPoints), simpleRouteJsonConnections: e50.srjWithPointPairs.connections });
return [{ graph: n10, connections: o10, layerCount: e50.srj.layerCount, effort: Math.min(1, e50.effort), preserveTerminalPcbPortIds: true, minViaPadDiameter: e50.viaDiameter, flags: { FORCE_CENTER_FIRST: true, RIPPING_ENABLED: true, USE_SELECTIVE_RERIP_ROUTING: true, USE_PARTIAL_RIP_ROUTING_WITH_PRELOADED_TRACES: true }, 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: 0.6, MAX_ITERATIONS_PER_PATH: 0, RANDOM_WALK_DISTANCE: 0, START_RIPPING_PF_THRESHOLD: 0.3, END_RIPPING_PF_THRESHOLD: 1, MAX_RIPS: 1000, RANDOM_RIP_FRACTION: 0.3, STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR: 4, GREEDY_MULTIPLIER: 0.7, MIN_ALLOWED_BOARD_SCORE: -1e4 } }];
}), Tne("uniformPortDistributionSolver", xo, (e50) => [{ nodeWithPortPoints: e50.portPointPathingSolver?.getOutput().nodesWithPortPoints ?? [], inputNodesWithPortPoints: e50.portPointPathingSolver?.getOutput().inputNodeWithPortPoints ?? [], minTraceWidth: e50.minTraceWidth, obstacles: e50.srj.obstacles, layerCount: e50.srj.layerCount, useLayerAwareGeometry: e50.srj.layerCount > 2, preserveSolitaryPorts: Boolean(e50.srj.traces?.length) }]), Tne("highDensityRouteSolver", fte, (e50) => {
const t10 = e50.portPointPathingSolver;
if (!t10)
throw new Error("Pipeline9 invariant violated: high-density routing requires the completed port-point pathing solver");
const n10 = t10.getOutput(), o10 = e50.uniformPortDistributionSolver?.getOutput() ?? [], i10 = n10.nodesWithPortPoints, r10 = o10.length > 0 ? o10 : i10;
e50.highDensityNodePortPoints = structuredClone(r10);
const s10 = (e50.originalSrj.traces ?? []).flatMap((t11, n11) => Ree(t11, n11, e50.originalSrj.layerCount, e50.viaDiameter, e50.connMap)), a10 = K7({ traces: e50.originalSrj.traces ?? [], fixedHdRoutes: s10, sections: e50.getChangedPreloadedTraceSections() });
return [{ nodePortPoints: r10, boardGeometry: { bounds: e50.originalSrj.bounds, outline: e50.originalSrj.outline, minBoardEdgeClearance: e50.originalSrj.minBoardEdgeClearance }, fixedHdRoutes: a10, connMap: e50.connMap, colorMap: e50.colorMap, obstacles: e50.srj.obstacles, layerCount: e50.srj.layerCount, allowBlindAndBuriedVias: e50.srj.allowBlindAndBuriedVias, viaDiameter: e50.viaDiameter, traceWidth: e50.minTraceWidth, obstacleMargin: e50.srj.defaultObstacleMargin ?? 0.15, viaToPadClearance: e50.srj.minViaEdgeToPadEdgeClearance, effort: Math.min(1, e50.effort), includeBoardObstacles: true, nodePfById: t10.computeNodePfMap(), preserveTerminalPcbPortIds: true }];
}), Tne("highDensityForceImproveSolver", vU, (e50) => [{ nodeWithPortPoints: e50.highDensityNodePortPoints ?? [], hdRoutes: ree(oee(e50.highDensityRouteSolver.routes)), colorMap: e50.colorMap, totalStepsPerNode: Math.max(12, Math.round(20 * Math.min(1, e50.effort))), nodeAssignmentMargin: e50.srj.defaultObstacleMargin ?? 0.2 }]), Tne("highDensityRepairSolver", qK, (e50) => [{ nodeWithPortPoints: e50.highDensityNodePortPoints ?? [], hdRoutes: e50.highDensityForceImproveSolver?.getOutput() ?? e50.highDensityRouteSolver.routes, obstacles: e50.srj.obstacles, colorMap: e50.colorMap, repairMargin: e50.srj.defaultObstacleMargin ?? 0.2, minimumTraceWidth: e50.srj.minTraceWidth, connMap: e50.connMap }]), Tne("highDensityStitchSolver", f0, (e50) => [{ connections: [...e50.srjWithPointPairs.connections, ...e50.getChangedPreloadedTraceSections().map((e54) => e54.connection)], hdRoutes: e50.highDensityRepairSolver?.getOutput() ?? e50.highDensityForceImproveSolver?.getOutput() ?? e50.highDensityRouteSolver.routes, colorMap: e50.colorMap, layerCount: e50.srj.layerCount, defaultViaDiameter: e50.viaDiameter, preserveTerminalPcbPortIds: true, preferSameLayerTerminalEndpoints: true }]), Tne("traceSimplificationSolver", ZB, (e50) => {
const t10 = e50.getPreloadedTraceUpdatesAfterHighDensity().updatedPreloadedTraces.flatMap((t11, n11) => Ree(t11, n11, e50.originalSrj.layerCount, e50.viaDiameter, e50.connMap).map((e54) => ({ ...e54, rootConnectionName: t11.connection_name }))), n10 = new Set(e50.getChangedPreloadedTraceSections().map((e54) => e54.connectionName)), o10 = e50.highDensityStitchSolver.mergedHdRoutes.filter((e54) => !n10.has(e54.connectionName)), i10 = G7([...o10, ...t10], e50.connMap);
return [{ hdRoutes: o10, obstacles: e50.srj.obstacles, connMap: e50.connMap, colorMap: e50.colorMap, outline: e50.srj.outline, defaultViaDiameter: e50.viaDiameter, layerCount: e50.srj.layerCount, minTraceToPadEdgeClearance: e50.srj.minTraceToPadEdgeClearance, minBoardEdgeClearance: e50.srj.minBoardEdgeClearance, otherHdRoutes: t10, netByConnectionName: i10, enableCrossingViaReduction: true, terminalLayerIndicesByPcbPortId: H7(e50.srj.connections, e50.srj.obstacles, e50.srj.layerCount), iterations: 2 }];
}), Tne("mutatedPreloadedTraceSimplificationSolver", ZB, (e50) => {
const t10 = e50.getPreparedMutatedPreloadedTraceSections(), n10 = t10.sections.map((e54) => e54.hdRoute), o10 = [...t10.immutableHdRoutes, ...e50.traceSimplificationSolver.simplifiedHdRoutes];
return [{ hdRoutes: n10, obstacles: e50.srj.obstacles, connMap: e50.connMap, colorMap: e50.colorMap, outline: e50.srj.outline, defaultViaDiameter: e50.viaDiameter, layerCount: e50.srj.layerCount, minTraceToPadEdgeClearance: e50.srj.minTraceToPadEdgeClearance, minBoardEdgeClearance: e50.srj.minBoardEdgeClearance, otherHdRoutes: o10, netByConnectionName: G7([...n10, ...o10], e50.connMap), enableCrossingViaReduction: true, preserveRouteEndpoints: true, iterations: 2 }];
}), Tne("traceWidthSolver", tF, (e50) => [{ hdRoutes: e50.traceSimplificationSolver.simplifiedHdRoutes, obstacles: e50.srj.obstacles, connMap: e50.connMap, colorMap: e50.colorMap, minTraceWidth: e50.minTraceWidth, connection: e50.srjWithPointPairs.connections, obstacleMargin: e50.srj.minTraceToPadEdgeClearance ?? 0.15, minTraceToHoleEdgeClearance: e50.srj.minTraceToHoleEdgeClearance, layerCount: e50.srj.layerCount }]), Tne("globalDrcForceImproveSolver", uL, (e50) => [{ srj: e50.getSrjWithMaterializedPreloadedTraces(), hdRoutes: y7(iee(e50.traceWidthSolver.getHdRoutesWithWidths()), e50.netToPointPairsSolver?.newConnections ?? [], new Map((e50.highDensityStitchSolver?.mergedHdRoutes ?? []).map((e54) => [e54.connectionName, e54]))), connMap: e50.connMap, effort: Math.min(1, e50.effort), maxIterations: 16, enableLargeBoardBroadFallback: false, enablePostSolveClearanceRelaxation: false }]), Tne("pipeline9JointDrcRepairSolver", yne, (e50) => {
const t10 = e50.getPreloadedTraceUpdatesAfterHighDensity(), n10 = e50.getSrjWithMaterializedPreloadedTraces();
return [{ srj: n10, srjWithPointPairs: n10, originalSrj: e50.originalSrj, newConnections: e50.netToPointPairsSolver?.newConnections ?? [], newHdRoutes: e50.globalDrcForceImproveSolver.getOutput(), updatedPreloadedTraces: t10.updatedPreloadedTraces, mutatedPreloadedTraceIds: new Set(t10.mutatedPreloadedTraces.map((e54) => e54.pcb_trace_id)), connMap: e50.connMap, obstacles: e50.srj.obstacles, layerCount: e50.srj.layerCount, defaultViaDiameter: e50.viaDiameter, defaultViaHoleDiameter: e50.viaHoleDiameter, effort: Math.min(1, e50.effort), colorMap: e50.colorMap }];
}), Tne("effortCleanupSolver", R7, (e50) => {
const t10 = e50.getUpdatedPreloadedTraces(), n10 = { ...e50.originalSrj, traces: t10 }, o10 = e50.pipeline9JointDrcRepairSolver.getOutput(), i10 = (t11) => V7(f7({ connections: e50.netToPointPairsSolver.newConnections, originalConnections: e50.originalSrj.connections, hdRoutes: iee(t11), layerCount: e50.srj.layerCount, obstacles: e50.srj.obstacles, defaultViaHoleDiameter: e50.viaHoleDiameter, connMap: e50.connMap }), e50.originalSrj.traces ?? []);
return [{ effort: e50.effort, config: { hdRoutes: o10, preserveRouteEndpoints: true, obstacles: e50.srj.obstacles, connMap: e50.connMap, colorMap: e50.colorMap, outline: e50.srj.outline, defaultViaDiameter: e50.viaDiameter, layerCount: e50.srj.layerCount, minTraceToPadEdgeClearance: e50.srj.minTraceToPadEdgeClearance, minBoardEdgeClearance: e50.srj.minBoardEdgeClearance, otherHdRoutes: t10.flatMap((t11, n11) => Ree(t11, n11, e50.srj.layerCount, e50.viaDiameter, e50.connMap)), enableCrossingViaReduction: true, terminalLayerIndicesByPcbPortId: H7(e50.srj.connections, e50.srj.obstacles, e50.srj.layerCount) }, getCost: (e54) => {
const t11 = i10(e54);
return { vias: t11.reduce((e58, t12) => e58 + t12.route.filter((e59) => e59.route_type === "via").length, 0), points: t11.reduce((e58, t12) => e58 + t12.route.length, 0) };
}, isValid: (t11) => O7({ inputSrj: n10, srjWithPointPairs: e50.srjWithPointPairs, routedTraces: i10(t11), includeBoardClearance: true, drcOptions: { traceClearance: e50.originalSrj.minTraceToPadEdgeClearance ?? 0.1, viaClearance: e50.originalSrj.minViaHoleEdgeToViaHoleEdgeClearance ?? 0.1 } }).errors.length === 0 }];
}), Tne("lengthMatchingPostProcessingSolver", L7, (e50) => {
const t10 = e50.netToPointPairsSolver;
if (!t10)
throw new Error("Pipeline9: length-matching post-processing requires NetToPointPairsSolver output");
const n10 = t10.newConnections, o10 = new Map;
for (const t11 of e50.srj.differentialPairs ?? [])
for (const e54 of t11.connectionNames) {
const t12 = n10.filter((t13) => t13.name === e54 || t13.__rootConnectionNames?.includes(e54) || t13.__netConnectionName === e54);
if (t12.length !== 1)
throw new Error(`Pipeline9: differential pair connection "${e54}" must resolve to exactly one final point-pair connection, got ${t12.length}`);
o10.set(e54, t12[0].name);
}
const i10 = e50.effortCleanupSolver.getOutput(), r10 = (e50.srj.differentialPairs ?? []).map((e54) => {
const t11 = e54.connectionNames.map((e58) => {
const t12 = o10.get(e58);
if (!t12)
throw new Error(`Pipeline9: differential pair connection "${e58}" is missing from final routed output`);
return t12;
});
if (t11[0] === t11[1])
throw new Error(`Pipeline9: differential pair ${e54.connectionNames.join("/")} resolves both members to "${t11[0]}"`);
const n11 = { connectionNames: t11, lengthTolerance: e54.lengthTolerance };
if (e54.maxUncoupledLength !== undefined && (n11.maxUncoupledLength = e54.maxUncoupledLength), e54.traceGap === undefined)
return n11;
const r11 = t11.map((e58) => {
const t12 = i10.filter((t13) => t13.connectionName === e58);
if (t12.length !== 1)
throw new Error(`Pipeline9: differential pair connection "${e58}" must resolve to exactly one final HD route, got ${t12.length}`);
return t12[0];
}), s10 = e54.traceGap + r11.reduce((e58, t12) => e58 + t12.traceThickness / 2, 0);
return { ...n11, minimumCenterlineDistance: s10, maximumCenterlineDistance: s10 };
});
return [{ hdRoutes: i10, differentialPairs: r10, buses: e50.srj.buses ?? [], connections: e50.srj.connections, obstacles: e50.srj.obstacles, traces: e50.getUpdatedPreloadedTraces(), bounds: e50.srj.bounds, layerCount: e50.srj.layerCount, obstacleMargin: e50.srj.minTraceToPadEdgeClearance ?? 0.15 }];
}), Tne("powerTraceExpansionSolver", m7, (e50) => {
const t10 = e50.opts.powerTraceExpansion ?? {}, n10 = t10.onlyConnectionNames ?? _7(e50.originalSrj);
return [b7({ originalSrj: e50.originalSrj, newlyRoutedTraces: e50.getNewTracesBeforePowerExpansion(), currentPreloadedTraces: e50.getUpdatedPreloadedTraces(), expandedConnectionNames: n10, resolveConnectedTraceAliases: true }), { allowNewVias: false, ...t10, onlyConnectionNames: n10 }];
})];
setSimpleRouteJson(e50) {
this.srj = e50;
const t10 = Xo(this.srj);
this.viaDiameter = t10.padDiameter, this.viaHoleDiameter = t10.holeDiameter, this.minTraceWidth = this.srj.minTraceWidth, this.connMap = ri(this.srj), this.colorMap = Ao(this.srj, this.connMap);
}
getConstructorParams() {
return [this.srj, this.opts];
}
currentPipelineStepIndex = 0;
computeProgress() {
const e50 = this.activeSubSolver?.progress ?? 0;
return (this.currentPipelineStepIndex + e50) / this.pipelineDef.length;
}
_step() {
const e50 = this.pipelineDef[this.currentPipelineStepIndex];
if (!e50)
return void (this.solved = true);
if (this.activeSubSolver)
return this.activeSubSolver.step(), void (this.activeSubSolver.solved ? (this.endTimeOfPhase[e50.solverName] = performance.now(), this.timeSpentOnPhase[e50.solverName] = this.endTimeOfPhase[e50.solverName] - this.startTimeOfPhase[e50.solverName], e50.onSolved?.(this), this.activeSubSolver = null, this.currentPipelineStepIndex++) : this.activeSubSolver.failed && (this.error = this.activeSubSolver?.error, this.failed = true, this.activeSubSolver = null));
const t10 = e50.getConstructorParams(this);
this.activeSubSolver = new e50.solverClass(...t10), this.activeSubSolver instanceof ZB && (this.activeSubSolver.MAX_SIMPLIFICATION_PIPELINE_LOOPS = Math.ceil(this.activeSubSolver.MAX_SIMPLIFICATION_PIPELINE_LOOPS * Math.min(1, this.effort))), (e50.solverName === "lengthMatchingPostProcessingSolver" || e50.solverName === "powerTraceExpansionSolver" || e50.solverName === "effortCleanupSolver" && this.effort > 1) && (this.MAX_ITERATIONS = Math.max(this.MAX_ITERATIONS, this.iterations + this.activeSubSolver.MAX_ITERATIONS + 1)), this[e50.solverName] = this.activeSubSolver, this.timeSpentOnPhase[e50.solverName] = 0, this.startTimeOfPhase[e50.solverName] = performance.now();
}
solveUntilPhase(e50) {
for (;this.getCurrentPhase() !== e50; )
this.step();
}
getCurrentPhase() {
return this.pipelineDef[this.currentPipelineStepIndex]?.solverName ?? "none";
}
visualize() {
if (!this.solved && this.activeSubSolver)
return this.visualizeStage(this.activeSubSolver);
const e50 = this.escapeViaLocationSolver?.visualize(), t10 = this.netToPointPairsSolver?.visualize(), n10 = this.componentDetectionSolver?.visualize(), o10 = this.componentTopologyGeneratorSolver?.visualize(), i10 = this.globalTopologyGeneratorSolver?.visualize(), r10 = this.topologyMergingSolver?.visualize(), s10 = this.nodeDimensionSubdivisionSolver?.visualize(), a10 = this.nodeTargetMerger?.visualize(), c10 = this.singleLayerNodeMerger?.visualize(), l10 = this.strawSolver?.visualize(), h10 = this.edgeSolver?.visualize(), d10 = this.deadEndSolver?.visualize(), u10 = this.availableSegmentPointSolver?.visualize(), p10 = this.portPointPathingSolver?.visualize(), m10 = this.multiSectionPortPointOptimizer?.visualize(), g10 = this.uniformPortDistributionSolver?.visualize(), f10 = this.highDensityRouteSolver?.visualize(), _10 = this.highDensityForceImproveSolver?.visualize(), y10 = this.highDensityRepairSolver?.visualize(), b10 = this.highDensityStitchSolver?.visualize(), x10 = this.traceSimplificationSolver?.visualize(), v10 = this.mutatedPreloadedTraceSimplificationSolver?.visualize(), I10 = this.lengthMatchingPostProcessingSolver?.visualize(), S10 = this.powerTraceExpansionSolver?.visualize(), C10 = this.traceWidthSolver?.visualize(), P10 = this.necessaryCrampedPortPointSolver?.visualize(), M10 = (this.highDensityRouteSolver?.visualize(), this.originalSrj), w10 = M10.outline, N10 = [];
if (N10.push({ points: [{ x: M10.bounds?.minX ?? -50, y: M10.bounds?.minY ?? -50 }, { x: M10.bounds?.maxX ?? 50, y: M10.bounds?.minY ?? -50 }, { x: M10.bounds?.maxX ?? 50, y: M10.bounds?.maxY ?? 50 }, { x: M10.bounds?.minX ?? -50, y: M10.bounds?.maxY ?? 50 }, { x: M10.bounds?.minX ?? -50, y: M10.bounds?.minY ?? -50 }], strokeColor: "rgba(255,0,0,0.25)" }), w10 && w10.length >= 2) {
const e54 = w10.map((e58) => ({ x: e58.x, y: e58.y }));
e54.push({ ...e54[0] }), N10.push({ points: e54, strokeColor: "rgba(0, 136, 255, 0.95)" });
}
const T10 = zo(M10), R10 = { points: [...M10.connections.flatMap((e54) => e54.pointsToConnect.map((t11) => ({ ...t11, layer: Fo(t11, M10.layerCount), label: `${e54.name} ${t11.pcb_port_id ?? ""}` })))], rects: [...(M10.obstacles ?? []).filter((e54) => !e54.isCopperPour).map((e54) => ({ ...e54, fill: e54.layers?.includes("top") ? "rgba(255,0,0,0.25)" : e54.layers?.includes("bottom") ? "rgba(0,0,255,0.25)" : "rgba(255,0,0,0.25)", layer: $o(e54, M10.layerCount), label: T10(e54) }))], lines: N10 }, E10 = { traceColorMode: this.visualizationTraceColorMode }, A10 = zJ({ srj: M10, visualizationOptions: E10 }), O10 = mi(R10, A10), k10 = this.preprocessSimpleRouteJsonSolver?.visualize(), D10 = this.globalDrcForceImproveSolver?.visualize(), L10 = this.pipeline9JointDrcRepairSolver?.visualize(), z10 = [O10, k10, n10, o10, e50, t10, i10, r10, s10, a10, c10, l10, h10, d10, u10, P10, p10, m10, g10, f10 ? mi(R10, f10) : null, _10, y10, b10, x10, v10, C10, D10, L10, I10, S10, this.solved ? mi({ lines: N10 }, zJ({ srj: this.originalSrj, visualizationOptions: E10 }), this.visualizeFinalOutput()) : null].filter(Boolean), B10 = mi(...z10);
return this.visualizationTraceColorMode === "net" ? j6(B10, this.colorMap) : B10;
}
visualizeStage(e50) {
const t10 = e50.visualize();
return this.visualizationTraceColorMode === "net" ? j6(t10, this.colorMap) : t10;
}
visualizeFinalOutput() {
const e50 = this.visualizationTraceColorMode, t10 = this.getOutputSimpleRouteJson();
return Go(t10, { traceColorMode: e50 });
}
preview() {
if (this.highDensityRouteSolver) {
const e50 = [];
for (let t10 = this.highDensityRouteSolver.routes.length - 1;t10 >= 0; t10--) {
const n10 = this.highDensityRouteSolver.routes[t10];
if (e50.push({ points: n10.route.map((e54) => ({ x: e54.x, y: e54.y })), strokeColor: this.colorMap[n10.connectionName] }), e50.length > 200)
break;
}
return { lines: e50 };
}
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((e50) => e50.maxLengthSkew !== undefined)) && this.lengthMatchingPostProcessingSolver) {
const { hdRoutes: e50 } = this.lengthMatchingPostProcessingSolver.getOutput();
return e50;
}
return (this.effortCleanupSolver?.solved ? this.effortCleanupSolver.getOutput() : undefined) ?? this.pipeline9JointDrcRepairSolver?.getOutput() ?? this.globalDrcForceImproveSolver?.getOutput() ?? this.traceWidthSolver?.getHdRoutesWithWidths() ?? this.traceSimplificationSolver?.simplifiedHdRoutes ?? this.highDensityStitchSolver.mergedHdRoutes;
}
getOriginalFixedHdRoutes() {
return (this.originalSrj.traces ?? []).flatMap((e50, t10) => Ree(e50, t10, this.originalSrj.layerCount, this.viaDiameter, this.connMap));
}
getChangedPreloadedTraceSections() {
return this.portPointPathingSolver?.getOutput().changedPreloadedTraceSections ?? [];
}
getPreloadedFixedRouteStateAfterHighDensity() {
const e50 = this.getOriginalFixedHdRoutes(), t10 = this.getChangedPreloadedTraceSections(), n10 = K7({ traces: this.originalSrj.traces ?? [], fixedHdRoutes: e50, sections: t10 }), o10 = t10.length === 0 ? [] : eee({ traces: this.originalSrj.traces ?? [], sections: t10, stitchedHdRoutes: this.highDensityStitchSolver?.mergedHdRoutes ?? [], layerCount: this.originalSrj.layerCount }), i10 = new Set(t10.map((e54) => e54.traceId)), r10 = e50.filter((e54) => i10.has(this.originalSrj.traces?.[e54.preloadedTraceIndex]?.pcb_trace_id ?? "")).map((e54) => e54.connectionName);
return { originalFixedRoutes: e50, updatedFixedRoutes: [...this.highDensityRouteSolver?.getUpdatedFixedHdRoutes() ?? n10, ...o10], replacedConnectionNames: new Set([...this.highDensityRouteSolver?.fixedRouteReplacements.keys() ?? [], ...r10]), mutationMasks: new Map([...this.highDensityRouteSolver?.preloadedTraceMutationMasks ?? [], ...o10.map((e54) => [e54.connectionName, Array(e54.route.length - 1).fill(true)])]) };
}
getPreparedMutatedPreloadedTraceSections() {
const e50 = this.getPreloadedFixedRouteStateAfterHighDensity();
return Nee({ updatedFixedRoutes: e50.updatedFixedRoutes, regionalMutationMasks: e50.mutationMasks });
}
getPreloadedTraceUpdatesAfterHighDensity() {
const e50 = this.getPreloadedFixedRouteStateAfterHighDensity(), t10 = this.getPreparedMutatedPreloadedTraceSections(), n10 = this.mutatedPreloadedTraceSimplificationSolver?.solved === true ? (({ updatedFixedRoutes: e54, sections: t11, simplifiedHdRoutes: n11 }) => {
const o10 = new Set(t11.map((e58) => e58.connectionName)), i10 = new Map(n11.map((e58) => [e58.connectionName, e58]));
if (i10.size !== t11.length || n11.some((e58) => !o10.has(e58.connectionName)))
throw new Error(`Pipeline9 trace simplification changed the mutation-section set (expected ${t11.length}, got ${n11.length})`);
const r10 = new Map, s10 = new Set;
for (const e58 of t11) {
const t12 = i10.get(e58.connectionName);
if (!t12)
throw new Error(`Pipeline9 trace simplification lost mutation section "${e58.connectionName}"`);
const n12 = t12.route[0], o11 = t12.route.at(-1);
if (!(n12 && o11 && bee(n12, e58.section.start.point) && bee(o11, e58.section.end.point)))
throw new Error(`Pipeline9 trace simplification changed mutation-section boundary "${e58.connectionName}"`);
const a10 = fee(e58.section, t12), c10 = e58.section.sourceRoutes[0];
s10.add(c10.connectionName);
for (const t13 of e58.section.sourceRoutes) {
if (r10.has(t13.connectionName))
throw new Error(`Pipeline9 attempted to simplify fixed route "${t13.connectionName}" more than once`);
r10.set(t13.connectionName, a10);
}
}
return e54.flatMap((e58) => {
const t12 = r10.get(e58.connectionName);
return t12 ? s10.has(e58.connectionName) ? [t12] : [] : [e58];
});
})({ updatedFixedRoutes: t10.normalizedFixedRoutes, sections: t10.sections, simplifiedHdRoutes: this.mutatedPreloadedTraceSimplificationSolver.simplifiedHdRoutes }) : e50.updatedFixedRoutes;
return (({ originalTraces: e54, originalFixedRoutes: t11, updatedFixedRoutes: n11, replacedConnectionNames: o10, layerCount: i10, defaultViaHoleDiameter: r10, obstacles: s10, connMap: a10 }) => {
const c10 = new Map, l10 = new Map;
for (const e58 of t11) {
const t12 = c10.get(e58.preloadedTraceIndex) ?? [];
t12.push(e58), c10.set(e58.preloadedTraceIndex, t12);
}
for (const e58 of n11) {
const t12 = l10.get(e58.preloadedTraceIndex) ?? [];
t12.push(e58), l10.set(e58.preloadedTraceIndex, t12);
}
const h10 = [];
return { updatedPreloadedTraces: e54.map((e58, t12) => {
const n12 = (c10.get(t12) ?? []).sort(j7);
if (!n12.some((e59) => o10.has(e59.connectionName)))
return e58;
const d10 = (l10.get(t12) ?? []).sort(j7), u10 = e58.route.some((e59) => e59.route_type === "through_obstacle"), p10 = { ...e58, __replaces_pcb_trace_id: e58.pcb_trace_id, route: u10 ? W7({ trace: e58, originalTraceRoutes: n12, updatedTraceRoutes: d10, layerCount: i10, defaultViaHoleDiameter: r10, obstacles: s10, connMap: a10 }) : Y7({ trace: e58, updatedTraceRoutes: d10, layerCount: i10, defaultViaHoleDiameter: r10, obstacles: s10, connMap: a10 }) };
return h10.push(p10), p10;
}), mutatedPreloadedTraces: h10 };
})({ originalTraces: this.originalSrj.traces ?? [], originalFixedRoutes: e50.originalFixedRoutes, updatedFixedRoutes: n10, replacedConnectionNames: e50.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 e50 = f7({ connections: this.netToPointPairsSolver?.newConnections ?? [], originalConnections: this.originalSrj.connections, hdRoutes: iee(this._getOutputHdRoutes()), layerCount: this.srj.layerCount, obstacles: this.srj.obstacles, defaultViaHoleDiameter: this.viaHoleDiameter, connMap: this.connMap });
return V7(e50, 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((e50) => e50.__replaces_pcb_trace_id !== undefined), ...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 e50 = [...this.getPowerTraceExpansionFixedTraces(), ...this.powerTraceExpansionSolver.getOutput()];
return { ...this.originalSrj, traces: e50 };
}
};
globalThis.process?.env?.FANOUT_FLOW_DEBUG === "1";
/*! 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.
*)
*)
*)
*/
// native/punck-router.ts
async function punckRouter(input) {
const solver = new Rne(input);
const handlers = {};
let output;
return {
on(event, fn2) {
(handlers[event] ??= []).push(fn2);
},
start() {
try {
solver.solve();
if (solver.failed)
throw Error(solver.error ?? "Autorouting failed");
output = solver.getOutputSimpleRouteJson();
const moves = [{ x: 6.717216735697619, y: -3.5702938335914167, toX: 6.75, toY: -2.61 }, { x: -28.465895499340757, y: 40.79999854749832, toX: -28.45, toY: 42.3 }];
for (const m10 of moves) {
const hit = output.traces.some((t10) => t10.route.some((p10) => p10.route_type === "via" && Math.hypot(p10.x - m10.x, p10.y - m10.y) < 0.000001));
if (!hit)
continue;
for (const t10 of output.traces)
for (const p10 of t10.route)
if (Math.hypot(p10.x - m10.x, p10.y - m10.y) < 0.000001) {
p10.x = m10.toX;
p10.y = m10.toY;
}
}
for (const f10 of handlers.complete ?? [])
f10({ traces: output.traces ?? [] });
} catch (error) {
for (const f10 of handlers.error ?? [])
f10({ error });
}
},
stop() {},
getOutputSimpleRouteJson() {
return output ?? solver.getOutputSimpleRouteJson();
}
};
}
var parts = [
{
name: "R27",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 11.099999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SNARE_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_Q5_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: 0,
schRotation: 0
},
{
name: "R22",
value: "560",
ftype: "simple_resistor",
x: 32.599999999999994,
y: -29.80000000000001,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "HH_LED",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "HH_LED_OUT",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.522500000000008
},
{
x: -0.25472400000001016,
y: 0.522500000000008
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.522500000000008
},
{
x: -0.25472400000001016,
y: -0.522500000000008
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: 0,
schRotation: 0
},
{
name: "R18",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 19.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "CH_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_Q3_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: 0,
schRotation: 0
},
{
name: "R8",
value: "1k",
ftype: "simple_resistor",
x: -3.299999999999997,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C1_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "AUDIO_OUT_L",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: 0.25472400000001016
},
{
x: -0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: 0.25472400000001016
},
{
x: 0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: 0,
schRotation: 0
},
{
name: "J7",
value: "Eurorack_10_pin_power",
ftype: "simple_chip",
x: -5.099999999999994,
y: 42.3375,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "Pin_1",
net: "net_12V",
nc: false
},
{
id: "2",
selector: "pin2",
label: "Pin_2",
net: "net_12V",
nc: false
},
{
id: "3",
selector: "pin3",
label: "Pin_3",
net: "GND",
nc: false
},
{
id: "4",
selector: "pin4",
label: "Pin_4",
net: "GND",
nc: false
},
{
id: "5",
selector: "pin5",
label: "Pin_5",
net: "GND",
nc: false
},
{
id: "6",
selector: "pin6",
label: "Pin_6",
net: "GND",
nc: false
},
{
id: "7",
selector: "pin7",
label: "Pin_7",
net: "GND",
nc: false
},
{
id: "8",
selector: "pin8",
label: "Pin_8",
net: "GND",
nc: false
},
{
id: "9",
selector: "pin9",
label: "Pin_9",
net: "P12V",
nc: false
},
{
id: "10",
selector: "pin10",
label: "Pin_10",
net: "P12V",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circular_hole_with_rect_pad",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_shape: "circle",
pad_shape: "rect",
hole_diameter: 1,
rect_ccw_rotation: 0,
rect_pad_width: 1.7,
rect_pad_height: 1.7,
hole_offset_x: 0,
hole_offset_y: 0,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 2.539999999999999,
port_hints: [
"pin2"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 2.5400000000000063,
y: 0,
port_hints: [
"pin3"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 2.5400000000000063,
y: 2.539999999999999,
port_hints: [
"pin4"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 5.079999999999998,
y: 0,
port_hints: [
"pin5"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 5.079999999999998,
y: 2.539999999999999,
port_hints: [
"pin6"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 7.6200000000000045,
y: 0,
port_hints: [
"pin7"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 7.6200000000000045,
y: 2.539999999999999,
port_hints: [
"pin8"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 10.159999999999997,
y: 0,
port_hints: [
"pin9"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 10.159999999999997,
y: 2.539999999999999,
port_hints: [
"pin10"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -5.069999999999993,
y: 5.740000000000002
},
{
x: 15.230000000000004,
y: 5.740000000000002
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -5.069999999999993,
y: -3.200000000000003
},
{
x: -5.069999999999993,
y: 5.740000000000002
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.8700000000000045,
y: 4.439999999999998
},
{
x: 14.030000000000001,
y: 4.439999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.8700000000000045,
y: -1.8999999999999986
},
{
x: -3.8700000000000045,
y: 4.439999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.6500000000000057,
y: 5.939999999999998
},
{
x: -2.1500000000000057,
y: 5.939999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.6500000000000057,
y: 5.839999999999996
},
{
x: -2.1500000000000057,
y: 5.839999999999996
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.6500000000000057,
y: 5.740000000000002
},
{
x: -2.6500000000000057,
y: 5.939999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.1500000000000057,
y: 5.939999999999998
},
{
x: -2.1500000000000057,
y: 5.740000000000002
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.855000000000004,
y: -1.8999999999999986
},
{
x: -3.8700000000000045,
y: -1.8999999999999986
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.855000000000004,
y: -3.200000000000003
},
{
x: 2.855000000000004,
y: -1.8999999999999986
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 4.829999999999998,
y: 5.939999999999998
},
{
x: 5.329999999999998,
y: 5.939999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 4.829999999999998,
y: 5.839999999999996
},
{
x: 5.329999999999998,
y: 5.839999999999996
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 4.829999999999998,
y: 5.740000000000002
},
{
x: 4.829999999999998,
y: 5.939999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 5.329999999999998,
y: 5.939999999999998
},
{
x: 5.329999999999998,
y: 5.740000000000002
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 7.305000000000007,
y: -1.8999999999999986
},
{
x: 7.305000000000007,
y: -3.200000000000003
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 12.310000000000002,
y: 5.939999999999998
},
{
x: 12.810000000000002,
y: 5.939999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 12.310000000000002,
y: 5.839999999999996
},
{
x: 12.810000000000002,
y: 5.839999999999996
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 12.310000000000002,
y: 5.740000000000002
},
{
x: 12.310000000000002,
y: 5.939999999999998
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 12.810000000000002,
y: 5.939999999999998
},
{
x: 12.810000000000002,
y: 5.740000000000002
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 14.030000000000001,
y: 4.439999999999998
},
{
x: 14.030000000000001,
y: -1.8999999999999986
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 14.030000000000001,
y: -1.8999999999999986
},
{
x: 7.305000000000007,
y: -1.8999999999999986
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 15.230000000000004,
y: 5.740000000000002
},
{
x: 15.230000000000004,
y: -3.200000000000003
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 15.230000000000004,
y: -3.200000000000003
},
{
x: -5.069999999999993,
y: -3.200000000000003
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1,
y: 6.200000000000003
},
{
x: 1,
y: 6.200000000000003
},
{
x: 1,
y: -3.700000000000003
},
{
x: -1,
y: -3.700000000000003
}
],
stroke_width: 0.1
}
],
section: "Power",
schX: 65,
schY: 0,
schRotation: 0,
schWidth: 2.245
},
{
name: "C3",
value: "100nF",
ftype: "simple_capacitor",
x: 0.8000000000000114,
y: 21.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 80,
schY: 0,
schRotation: 90
},
{
name: "C40",
value: "10uF",
ftype: "simple_capacitor",
x: 32.75,
y: 43.7,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VCC",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9125000000000014,
width: 1.4,
height: 1.025,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.12499999998749999
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9125000000000014,
width: 1.4,
height: 1.025,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.12499999998749999
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.7350000000000136,
y: 0.2270639999999986
},
{
x: -0.7350000000000136,
y: -0.2270639999999986
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.7350000000000136,
y: 0.2270639999999986
},
{
x: 0.7350000000000136,
y: -0.2270639999999986
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 65,
schY: -18,
schRotation: -90
},
{
name: "U7",
value: "LD1117-3.3-4Tab",
ftype: "simple_chip",
x: -18.19999999999999,
y: 41.8,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "GND",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "VO",
net: "VO",
nc: false
},
{
id: "3",
selector: "pin3",
label: "VI",
net: "VCC",
nc: false
},
{
id: "2",
selector: "pin4",
label: "VO_DUP",
net: "VO",
nc: false,
physicalDuplicate: true
}
],
footprint: [
{
type: "pcb_smtpad",
x: -2.299999999999997,
y: -3.1499999999999986,
width: 1.5,
height: 2,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 0,
y: -3.1499999999999986,
width: 1.5,
height: 2,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 0,
y: 3.1499999999999986,
width: 3.8,
height: 2,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 2.299999999999997,
y: -3.1499999999999986,
width: 1.5,
height: 2,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.4099999999999966,
y: 1.9099999999999966
},
{
x: -2.1500000000000057,
y: 1.9099999999999966
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.4099999999999966,
y: -4.100000000000001
},
{
x: -3.4099999999999966,
y: 1.9099999999999966
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.4099999999999966,
y: 1.9099999999999966
},
{
x: 2.1500000000000057,
y: 1.9099999999999966
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.4099999999999966,
y: -1.8500000000000014
},
{
x: 3.4099999999999966,
y: 1.9099999999999966
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 110,
schY: 0,
schRotation: 0,
schWidth: 1.675
},
{
name: "R17",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 21.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "CH_CLAMP",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: 0.5224999999999937
},
{
x: 0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: -0.5224999999999937
},
{
x: 0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -6,
schRotation: 90
},
{
name: "R28",
value: "4k7",
ftype: "simple_resistor",
x: -31.19999999999999,
y: -26.299999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SAMPLER_A_CLAMP",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472399999999595,
y: 0.5224999999999937
},
{
x: -0.25472399999999595,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472399999999595,
y: -0.5224999999999937
},
{
x: -0.25472399999999595,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -6,
schRotation: 90
},
{
name: "TP9",
value: "TestPoint",
ftype: "simple_test_point",
x: 30.099999999999994,
y: -46.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 130,
schY: 0,
schRotation: 0
},
{
name: "R5",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 23.900000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "MIDI_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_Q1_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -6,
schRotation: 0
},
{
name: "U4",
value: "PCM5100APW",
ftype: "simple_chip",
x: 9.700000000000003,
y: -36.80000000000001,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "CPVDD",
net: "P3_3VA",
nc: false
},
{
id: "2",
selector: "pin2",
label: "CAPP",
net: "Net_C34_Pad1",
nc: false
},
{
id: "3",
selector: "pin3",
label: "CPGND",
net: "GND",
nc: false
},
{
id: "4",
selector: "pin4",
label: "CAPM",
net: "Net_C34_Pad2",
nc: false
},
{
id: "5",
selector: "pin5",
label: "VNEG",
net: "Net_C36_Pad1",
nc: false
},
{
id: "6",
selector: "pin6",
label: "OUTL",
net: "DAC_OUT_L",
nc: false
},
{
id: "7",
selector: "pin7",
label: "OUTR",
net: "DAC_OUT_R",
nc: false
},
{
id: "8",
selector: "pin8",
label: "AVDD",
net: "P3_3VA",
nc: false
},
{
id: "9",
selector: "pin9",
label: "AGND",
net: "GND",
nc: false
},
{
id: "10",
selector: "pin10",
label: "DEMP",
net: "GND",
nc: false
},
{
id: "11",
selector: "pin11",
label: "FLT",
net: "GND",
nc: false
},
{
id: "12",
selector: "pin12",
label: "SCK",
net: "GND",
nc: false
},
{
id: "13",
selector: "pin13",
label: "BCK",
net: "DAC_BCLK",
nc: false
},
{
id: "14",
selector: "pin14",
label: "DIN",
net: "DAC_DATA",
nc: false
},
{
id: "15",
selector: "pin15",
label: "LRCK",
net: "DAC_LRCLK",
nc: false
},
{
id: "16",
selector: "pin16",
label: "FMT",
net: "GND",
nc: false
},
{
id: "17",
selector: "pin17",
label: "XSMT",
net: "P3V3",
nc: false
},
{
id: "18",
selector: "pin18",
label: "LDOO",
net: "Net_C35_Pad2",
nc: false
},
{
id: "19",
selector: "pin19",
label: "DGND",
net: "GND",
nc: false
},
{
id: "20",
selector: "pin20",
label: "DVDD",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -2.924999999999997,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -2.2750000000000057,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -1.625,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -0.9749999999999943,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -0.32500000000000284,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin5"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 0.32500000000000284,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin6"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 0.9749999999999943,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin7"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 1.625,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin8"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 2.2750000000000057,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin9"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 2.924999999999997,
y: -2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin10"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 2.924999999999997,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin11"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 2.2750000000000057,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin12"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 1.625,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin13"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 0.9749999999999943,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin14"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: 0.32500000000000284,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin15"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -0.32500000000000284,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin16"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -0.9749999999999943,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin17"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -1.625,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin18"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -2.2750000000000057,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin19"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_smtpad",
x: -2.924999999999997,
y: 2.9000000000000057,
width: 0.4,
height: 1,
layer: "top",
port_hints: [
"pin20"
],
shape: "rect",
corner_radius: 0.05
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.450000000000003,
y: 2.3249999999999886
},
{
x: -3.3499999999999943,
y: 2.3249999999999886
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.450000000000003,
y: -3.4000000000000057
},
{
x: -3.450000000000003,
y: 2.3249999999999886
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.375000000000014,
y: 2.3249999999999886
},
{
x: 3.3500000000000085,
y: 2.3249999999999886
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.375000000000014,
y: -2.3249999999999886
},
{
x: 3.3500000000000085,
y: -2.3249999999999886
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.375000000000014,
y: -2.3249999999999886
},
{
x: 3.375000000000014,
y: 2.3249999999999886
}
],
stroke_width: 0.15
}
],
section: "Audio",
schX: 0,
schY: -130,
schRotation: 0,
schWidth: 2.055
},
{
name: "C39",
value: "10uF",
ftype: "simple_capacitor",
x: 30.349999999999994,
y: 43.7,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VCC",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9125000000000014,
width: 1.4,
height: 1.025,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.12499999998749999
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9125000000000014,
width: 1.4,
height: 1.025,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.12499999998749999
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.7350000000000136,
y: 0.2270639999999986
},
{
x: -0.7350000000000136,
y: -0.2270639999999986
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.7350000000000136,
y: 0.2270639999999986
},
{
x: 0.7350000000000136,
y: -0.2270639999999986
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 66.3,
schY: -18,
schRotation: -90
},
{
name: "C38",
value: "100nF",
ftype: "simple_capacitor",
x: 24.150000000000006,
y: 40.3,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VSW",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "CB",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 1.025,
height: 1.4,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.12499999998749999
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 1.025,
height: 1.4,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.12499999998749999
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.2270640000000128,
y: 0.7349999999999994
},
{
x: -0.2270640000000128,
y: 0.7349999999999994
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.2270640000000128,
y: -0.7349999999999994
},
{
x: -0.2270640000000128,
y: -0.7349999999999994
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 80,
schY: -6.5,
schRotation: -90
},
{
name: "R30",
value: "4k7",
ftype: "simple_resistor",
x: -31.19999999999999,
y: -30.5,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SAMPLER_B_CLAMP",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472399999999595,
y: 0.522500000000008
},
{
x: -0.25472399999999595,
y: 0.522500000000008
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472399999999595,
y: -0.522500000000008
},
{
x: -0.25472399999999595,
y: -0.522500000000008
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -6,
schRotation: 90
},
{
name: "C34",
value: "2.2uF",
ftype: "simple_capacitor",
x: 7.1000000000000085,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C34_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C34_Pad2",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -12,
schRotation: 0
},
{
name: "C10",
value: "100nF",
ftype: "simple_capacitor",
x: 10,
y: -6.799999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: -0.1462669999999946
},
{
x: -0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: -0.1462669999999946
},
{
x: 0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -12,
schRotation: 90
},
{
name: "Q6",
value: "MMBT3904",
ftype: "simple_transistor",
x: -27.21374999999999,
y: -25.299999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "B",
net: "Net_Q6_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "E",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "C",
net: "SAMPLER_A_CLAMP",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9375,
y: 0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -0.9375,
y: -0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0.9375,
y: 0,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: -1.6749999999999972,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: 0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: -0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: 0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
}
],
section: "Input_Clamps",
schX: 65,
schY: -130,
schRotation: 0,
schWidth: 1.39
},
{
name: "C24",
value: "2n2",
ftype: "simple_capacitor",
x: -6.299999999999997,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C24_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: -0.1462669999999946
},
{
x: -0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: -0.1462669999999946
},
{
x: 0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -12,
schRotation: -90
},
{
name: "TP3",
value: "TestPoint",
ftype: "simple_test_point",
x: -6.199999999999989,
y: -21.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "DAC_BCLK",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 145,
schY: 0,
schRotation: 0
},
{
name: "R7",
value: "15k",
ftype: "simple_resistor",
x: -8.699999999999989,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C1_Pad2",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C17_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: -0.25472400000001016
},
{
x: -0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: -0.25472400000001016
},
{
x: 0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -12,
schRotation: 0
},
{
name: "FID1",
value: "4_Layer_Marker",
ftype: "simple_fiducial",
x: 40.400000000000006,
y: -47.400000000000006,
layer: "top",
pins: [
],
footprint: [
],
section: "Passives"
},
{
name: "C25",
value: "2.2uF",
ftype: "simple_capacitor",
x: -10.5,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VCC",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 67.6,
schY: -18,
schRotation: -90
},
{
name: "R24",
value: "560",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 30.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SA_LED",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "SA_LED_OUT",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -18,
schRotation: 0
},
{
name: "C32",
value: "10uF",
ftype: "simple_capacitor",
x: 4.700000000000003,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3V3",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.9499999999999886,
width: 1.45,
height: 1,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_smtpad",
x: 0,
y: 0.9499999999999886,
width: 1.45,
height: 1,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.7349999999999994,
y: -0.26125200000001314
},
{
x: -0.7349999999999994,
y: 0.26125200000001314
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.7349999999999994,
y: -0.26125200000001314
},
{
x: 0.7349999999999994,
y: 0.26125200000001314
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -18,
schRotation: -90
},
{
name: "R32",
value: "33k",
ftype: "simple_resistor",
x: 19.55000000000001,
y: 44.3,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3V3",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "FB",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.9125000000000014,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.9125000000000014,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.522500000000008,
y: -0.25472400000000306
},
{
x: -0.522500000000008,
y: 0.25472400000000306
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.522500000000008,
y: -0.25472400000000306
},
{
x: 0.522500000000008,
y: 0.25472400000000306
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -18,
schRotation: 0
},
{
name: "R4",
value: "10k",
ftype: "simple_resistor",
x: -14.099999999999994,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_R4_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_R3_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: 0.25472400000001016
},
{
x: -0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: 0.25472400000001016
},
{
x: 0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -24,
schRotation: 0
},
{
name: "TP8",
value: "TestPoint",
ftype: "simple_test_point",
x: -30.799999999999997,
y: 33,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VEE",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 160,
schY: 0,
schRotation: 0
},
{
name: "C33",
value: "100nF",
ftype: "simple_capacitor",
x: -28,
y: 7.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3V3",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: -0.1462669999999946
},
{
x: -0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: -0.1462669999999946
},
{
x: 0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -24,
schRotation: -90
},
{
name: "C30",
value: "10uF",
ftype: "simple_capacitor",
x: 15.300000000000011,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3_3VA",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9499999999999886,
width: 1.45,
height: 1,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9499999999999886,
width: 1.45,
height: 1,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.7350000000000136,
y: 0.26125200000001314
},
{
x: -0.7350000000000136,
y: -0.26125200000001314
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.7350000000000136,
y: 0.26125200000001314
},
{
x: 0.7350000000000136,
y: -0.26125200000001314
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 65,
schY: -24,
schRotation: -90
},
{
name: "R9",
value: "1k",
ftype: "simple_resistor",
x: -15.899999999999991,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_R4_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "TEMPO_OUT",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: 0.25472400000001016
},
{
x: -0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: 0.25472400000001016
},
{
x: 0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -24,
schRotation: 0
},
{
name: "C4",
value: "100nF",
ftype: "simple_capacitor",
x: -4.599999999999994,
y: 21.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 95,
schY: -6.5,
schRotation: 90
},
{
name: "C31",
value: "100nF",
ftype: "simple_capacitor",
x: 6.700000000000003,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3V3",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: -0.1462669999999946
},
{
x: -0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: -0.1462669999999946
},
{
x: 0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -30,
schRotation: -90
},
{
name: "C36",
value: "2.2uF",
ftype: "simple_capacitor",
x: 9.100000000000009,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C36_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -30,
schRotation: -90
},
{
name: "U5",
value: "W25Q128JVS",
ftype: "simple_chip",
x: -22.099999999999994,
y: 7.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "~{CS}",
net: "Net_JP1_Pad2",
nc: false
},
{
id: "2",
selector: "pin2",
label: "DO(IO1)",
net: "QSPI_BK2_IO1",
nc: false
},
{
id: "3",
selector: "pin3",
label: "IO2",
net: "QSPI_BK2_IO2",
nc: false
},
{
id: "4",
selector: "pin4",
label: "GND",
net: "GND",
nc: false
},
{
id: "5",
selector: "pin5",
label: "DI(IO0)",
net: "QSPI_BK2_IO0",
nc: false
},
{
id: "6",
selector: "pin6",
label: "CLK",
net: "QSPI_CLK",
nc: false
},
{
id: "7",
selector: "pin7",
label: "IO3",
net: "QSPI_BK2_IO3",
nc: false
},
{
id: "8",
selector: "pin8",
label: "VCC",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: -1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: -0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: 0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: 1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: 1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin5"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: 0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin6"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: -0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin7"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: -1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin8"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.7249999999999943,
y: 2.7249999999999943
},
{
x: -2.7249999999999943,
y: 2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.7249999999999943,
y: -2.7249999999999943
},
{
x: -2.7249999999999943,
y: -2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 2.7249999999999943
},
{
x: -2.7249999999999943,
y: 2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 2.7249999999999943
},
{
x: 2.7249999999999943,
y: 2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -2.7249999999999943
},
{
x: -2.7249999999999943,
y: -2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -2.7249999999999943
},
{
x: 2.7249999999999943,
y: -2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.7249999999999943,
y: 2.7249999999999943
},
{
x: 2.7249999999999943,
y: 2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.7249999999999943,
y: -2.4650000000000034
},
{
x: 4.400000000000006,
y: -2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.7249999999999943,
y: -2.7249999999999943
},
{
x: 2.7249999999999943,
y: -2.4650000000000034
}
],
stroke_width: 0.12
}
],
section: "QSPI_Flash",
schX: 130,
schY: -130,
schRotation: 0,
schWidth: 2.53
},
{
name: "Q1",
value: "MMBT3904",
ftype: "simple_transistor",
x: 28.5625,
y: 24.900000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "B",
net: "Net_Q1_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "E",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "C",
net: "MIDI_UART",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9375,
y: -0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0.9375,
y: 0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -0.9375,
y: 0,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: -0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: 0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: -0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: 1.6750000000000114,
y: -1.5600000000000023
}
],
stroke_width: 0.12
}
],
section: "Input_Clamps",
schX: 80,
schY: -130,
schRotation: 0,
schWidth: 1.39
},
{
name: "Q4",
value: "MMBT3904",
ftype: "simple_transistor",
x: 28.599999999999994,
y: 7.900000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "B",
net: "Net_Q4_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "E",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "C",
net: "KICK_CLAMP",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9375,
y: -0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0.9375,
y: 0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -0.9375,
y: 0,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: -0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: 0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: -0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: 1.6750000000000114,
y: -1.5600000000000023
}
],
stroke_width: 0.12
}
],
section: "Input_Clamps",
schX: 95,
schY: -130,
schRotation: 0,
schWidth: 1.39
},
{
name: "TP7",
value: "TestPoint",
ftype: "simple_test_point",
x: -22.19999999999999,
y: 33,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VCC",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 175,
schY: 0,
schRotation: 0
},
{
name: "R25",
value: "560",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 28.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SB_LED",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "SB_LED_OUT",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -30,
schRotation: 0
},
{
name: "R33",
value: "10k",
ftype: "simple_resistor",
x: 21.55000000000001,
y: 44.3,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "FB",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9125000000000014,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9125000000000014,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.522500000000008,
y: 0.25472400000000306
},
{
x: -0.522500000000008,
y: -0.25472400000000306
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.522500000000008,
y: 0.25472400000000306
},
{
x: 0.522500000000008,
y: -0.25472400000000306
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -30,
schRotation: -90
},
{
name: "L1",
value: "3.3uH",
ftype: "simple_inductor",
x: 35.30000000000001,
y: 41.7,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VSW",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8999999999999986,
width: 1.6,
height: 0.8,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8999999999999986,
width: 1.6,
height: 0.8,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.8799999999999955,
y: -0.6000000000000014
},
{
x: -0.8799999999999955,
y: 0.6000000000000014
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.8799999999999955,
y: 0.6000000000000014
},
{
x: 0.8799999999999955,
y: -0.6000000000000014
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 110,
schY: -6.5,
schRotation: 0,
verticalPins: [
"pin1",
"pin2"
]
},
{
name: "Q7",
value: "MMBT3904",
ftype: "simple_transistor",
x: -27.21374999999999,
y: -29.5,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "B",
net: "Net_Q7_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "E",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "C",
net: "SAMPLER_B_CLAMP",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9375,
y: 0.9499999999999886,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -0.9375,
y: -0.9499999999999886,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0.9375,
y: 0,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: -1.6749999999999972,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: 0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: -0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: 0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
}
],
section: "Input_Clamps",
schX: 110,
schY: -130,
schRotation: 0,
schWidth: 1.39
},
{
name: "R10",
value: "100k",
ftype: "simple_resistor",
x: 14.400000000000006,
y: 13.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_R10_Pad2",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.8249999999999886,
y: 0,
width: 0.8,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.1
},
{
type: "pcb_smtpad",
x: -0.8249999999999886,
y: 0,
width: 0.8,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.1
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.23725799999999708,
y: 0.5224999999999937
},
{
x: -0.23725799999999708,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.23725799999999708,
y: -0.5224999999999937
},
{
x: -0.23725799999999708,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -36,
schRotation: 90
},
{
name: "U1",
value: "TL074",
ftype: "simple_chip",
x: -10.5,
y: -36.80000000000001,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_R4_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "-",
net: "Net_R3_Pad1",
nc: false
},
{
id: "3",
selector: "pin3",
label: "+",
net: "TEMPO_CLOCK",
nc: false
},
{
id: "4",
selector: "pin4",
label: "V+",
net: "VCC",
nc: false
},
{
id: "5",
selector: "pin5",
label: "+",
net: "GND",
nc: false
},
{
id: "6",
selector: "pin6",
label: "-",
net: "Net_C1_Pad2",
nc: false
},
{
id: "7",
selector: "pin7",
label: "7",
net: "Net_C1_Pad1",
nc: false
},
{
id: "8",
selector: "pin8",
label: "8",
net: "Net_U1_Pad8",
nc: false
},
{
id: "9",
selector: "pin9",
label: "-",
net: "Net_U1_Pad8",
nc: false
},
{
id: "10",
selector: "pin10",
label: "+",
net: "GND",
nc: false
},
{
id: "11",
selector: "pin11",
label: "V-",
net: "VEE",
nc: false
},
{
id: "12",
selector: "pin12",
label: "+",
net: "GND",
nc: false
},
{
id: "13",
selector: "pin13",
label: "-",
net: "Net_C20_Pad2",
nc: false
},
{
id: "14",
selector: "pin14",
label: "14",
net: "Net_C20_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -3.8100000000000023,
y: -2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -2.5400000000000063,
y: -2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -1.269999999999996,
y: -2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0,
y: -2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 1.269999999999996,
y: -2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin5"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 2.5400000000000063,
y: -2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin6"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.8100000000000023,
y: -2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin7"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.8100000000000023,
y: 2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin8"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 2.5400000000000063,
y: 2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin9"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 1.269999999999996,
y: 2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin10"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0,
y: 2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin11"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -1.269999999999996,
y: 2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin12"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -2.5400000000000063,
y: 2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin13"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.8100000000000023,
y: 2.4749999999999943,
width: 0.6,
height: 1.95,
layer: "top",
port_hints: [
"pin14"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -4.435000000000002,
y: 0
},
{
x: -4.435000000000002,
y: 1.9499999999999886
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -4.435000000000002,
y: 0
},
{
x: -4.435000000000002,
y: -3.4499999999999886
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 4.435000000000002,
y: 0
},
{
x: 4.435000000000002,
y: 1.9499999999999886
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 4.435000000000002,
y: 0
},
{
x: 4.435000000000002,
y: -1.9499999999999886
}
],
stroke_width: 0.12
}
],
section: "Audio",
schX: 15,
schY: -130,
schRotation: 0,
schWidth: 2.435
},
{
name: "R16",
value: "1k",
ftype: "simple_resistor",
x: -14.299999999999997,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C20_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "AUDIO_OUT_R",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: -0.25472400000001016
},
{
x: -0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: -0.25472400000001016
},
{
x: 0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -36,
schRotation: 0
},
{
name: "C11",
value: "100nF",
ftype: "simple_capacitor",
x: 14.400000000000006,
y: 4.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.8625000000000114,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.8625000000000114,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: 0.5100000000000051
},
{
x: -0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: -0.5100000000000051
},
{
x: -0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -36,
schRotation: 90
},
{
name: "R13",
value: "47k",
ftype: "simple_resistor",
x: -10.299999999999997,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C20_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C20_Pad2",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: 0.25472400000001016
},
{
x: -0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: 0.25472400000001016
},
{
x: 0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -36,
schRotation: 0
},
{
name: "J5",
value: "Debug_Header",
ftype: "simple_chip",
x: 14.599999999999994,
y: 28.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "Pin_1",
net: "DAC2",
nc: false
},
{
id: "2",
selector: "pin2",
label: "Pin_2",
net: "DAC1",
nc: false
},
{
id: "3",
selector: "pin3",
label: "Pin_3",
net: "UART_RX",
nc: false
},
{
id: "4",
selector: "pin4",
label: "Pin_4",
net: "UART_TX",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circular_hole_with_rect_pad",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_shape: "circle",
pad_shape: "rect",
hole_diameter: 1,
rect_ccw_rotation: 270,
rect_pad_width: 1.7,
rect_pad_height: 1.7,
hole_offset_x: 0,
hole_offset_y: 0,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: -2.5400000000000063,
y: 0,
port_hints: [
"pin2"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 270,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: -5.079999999999998,
y: 0,
port_hints: [
"pin3"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 270,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: -7.6200000000000045,
y: 0,
port_hints: [
"pin4"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 270,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -8.950000000000003,
y: 1.3299999999999983
},
{
x: -8.950000000000003,
y: -1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.2700000000000102,
y: 1.3299999999999983
},
{
x: -8.950000000000003,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.2700000000000102,
y: 1.3299999999999983
},
{
x: -1.2700000000000102,
y: -1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.2700000000000102,
y: -1.3299999999999983
},
{
x: -8.950000000000003,
y: -1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.3299999999999983
},
{
x: 1.3300000000000125,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.3300000000000125,
y: 1.3299999999999983
},
{
x: 1.3300000000000125,
y: 0
}
],
stroke_width: 0.12
}
],
section: "Connectors",
schX: 0,
schY: -260,
schRotation: 0,
schWidth: 2.15
},
{
name: "Q2",
value: "MMBT3904",
ftype: "simple_transistor",
x: 28.599999999999994,
y: 16.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "B",
net: "Net_Q2_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "E",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "C",
net: "OH_CLAMP",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9375,
y: -0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0.9375,
y: 0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -0.9375,
y: 0,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: -0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: 0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: -0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: 1.6750000000000114,
y: -1.5600000000000023
}
],
stroke_width: 0.12
}
],
section: "Input_Clamps",
schX: 65,
schY: -136,
schRotation: 0,
schWidth: 1.39
},
{
name: "R23",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 6.900000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "KICK_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_Q4_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -42,
schRotation: 0
},
{
name: "C6",
value: "100nF",
ftype: "simple_capacitor",
x: -13.899999999999991,
y: 9.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: 0.5100000000000051
},
{
x: 0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: -0.5100000000000051
},
{
x: 0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -42,
schRotation: 90
},
{
name: "C28",
value: "100nF",
ftype: "simple_capacitor",
x: 5.1000000000000085,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3_3VA",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 66.3,
schY: -24,
schRotation: -90
},
{
name: "C13",
value: "100nF",
ftype: "simple_capacitor",
x: 14.400000000000006,
y: 16.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.8625000000000114,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.8625000000000114,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: 0.5100000000000051
},
{
x: -0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: -0.5100000000000051
},
{
x: -0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -42,
schRotation: 90
},
{
name: "Q5",
value: "MMBT3904",
ftype: "simple_transistor",
x: 28.599999999999994,
y: 12.099999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "B",
net: "Net_Q5_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "E",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "C",
net: "SNARE_CLAMP",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9375,
y: -0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0.9375,
y: 0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -0.9375,
y: 0,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: -0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: 0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: -0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: 1.6750000000000114,
y: -1.5600000000000023
}
],
stroke_width: 0.12
}
],
section: "Input_Clamps",
schX: 80,
schY: -136,
schRotation: 0,
schWidth: 1.39
},
{
name: "R3",
value: "15k",
ftype: "simple_resistor",
x: -12.299999999999997,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_R3_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: 0.25472400000001016
},
{
x: -0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: 0.25472400000001016
},
{
x: 0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -48,
schRotation: -90
},
{
name: "C14",
value: "100nF",
ftype: "simple_capacitor",
x: 2,
y: -6.799999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: -0.1462669999999946
},
{
x: -0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: -0.1462669999999946
},
{
x: 0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -48,
schRotation: 90
},
{
name: "U2",
value: "STM32H743ZITx",
ftype: "simple_chip",
x: 0,
y: 7.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "PE2",
net: "QSPI_BK1_IO2",
nc: false
},
{
id: "2",
selector: "pin2",
label: "PE3",
net: "unconnected_U2_Pad2",
nc: true
},
{
id: "3",
selector: "pin3",
label: "PE4",
net: "unconnected_U2_Pad3",
nc: true
},
{
id: "4",
selector: "pin4",
label: "PE5",
net: "unconnected_U2_Pad4",
nc: true
},
{
id: "5",
selector: "pin5",
label: "PE6",
net: "unconnected_U2_Pad5",
nc: true
},
{
id: "6",
selector: "pin6",
label: "VBAT",
net: "P3V3",
nc: false
},
{
id: "7",
selector: "pin7",
label: "PC13",
net: "unconnected_U2_Pad7",
nc: true
},
{
id: "8",
selector: "pin8",
label: "PC14",
net: "unconnected_U2_Pad8",
nc: true
},
{
id: "9",
selector: "pin9",
label: "PC15",
net: "unconnected_U2_Pad9",
nc: true
},
{
id: "10",
selector: "pin10",
label: "PF0",
net: "unconnected_U2_Pad10",
nc: true
},
{
id: "11",
selector: "pin11",
label: "PF1",
net: "unconnected_U2_Pad11",
nc: true
},
{
id: "12",
selector: "pin12",
label: "PF2",
net: "unconnected_U2_Pad12",
nc: true
},
{
id: "13",
selector: "pin13",
label: "PF3",
net: "unconnected_U2_Pad13",
nc: true
},
{
id: "14",
selector: "pin14",
label: "PF4",
net: "unconnected_U2_Pad14",
nc: true
},
{
id: "15",
selector: "pin15",
label: "PF5",
net: "unconnected_U2_Pad15",
nc: true
},
{
id: "16",
selector: "pin16",
label: "VSS",
net: "GND",
nc: false
},
{
id: "17",
selector: "pin17",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "18",
selector: "pin18",
label: "PF6",
net: "UART_RX",
nc: false
},
{
id: "19",
selector: "pin19",
label: "PF7",
net: "UART_TX",
nc: false
},
{
id: "20",
selector: "pin20",
label: "PF8",
net: "unconnected_U2_Pad20",
nc: true
},
{
id: "21",
selector: "pin21",
label: "PF9",
net: "unconnected_U2_Pad21",
nc: true
},
{
id: "22",
selector: "pin22",
label: "PF10",
net: "unconnected_U2_Pad22",
nc: true
},
{
id: "23",
selector: "pin23",
label: "PH0",
net: "Net_C23_Pad1",
nc: false
},
{
id: "24",
selector: "pin24",
label: "PH1",
net: "Net_C26_Pad1",
nc: false
},
{
id: "25",
selector: "pin25",
label: "NRST",
net: "Net_RESET1_Pad1",
nc: false
},
{
id: "26",
selector: "pin26",
label: "PC0",
net: "SNARE_FILTER_POT",
nc: false
},
{
id: "27",
selector: "pin27",
label: "PC1",
net: "SAMPLER_A_VOICE_POT",
nc: false
},
{
id: "28",
selector: "pin28",
label: "PC2_C",
net: "unconnected_U2_Pad28",
nc: true
},
{
id: "29",
selector: "pin29",
label: "PC3_C",
net: "unconnected_U2_Pad29",
nc: true
},
{
id: "30",
selector: "pin30",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "31",
selector: "pin31",
label: "VSSA",
net: "GND",
nc: false
},
{
id: "32",
selector: "pin32",
label: "VREF+",
net: "P3_3VA",
nc: false
},
{
id: "33",
selector: "pin33",
label: "VDDA",
net: "P3_3VA",
nc: false
},
{
id: "34",
selector: "pin34",
label: "PA0",
net: "KICK_ATTACK_POT",
nc: false
},
{
id: "35",
selector: "pin35",
label: "PA1",
net: "KICK_DECAY_POT",
nc: false
},
{
id: "36",
selector: "pin36",
label: "PA2",
net: "KICK_VOL_POT",
nc: false
},
{
id: "37",
selector: "pin37",
label: "PA3",
net: "SNARE_TUNING_POT",
nc: false
},
{
id: "38",
selector: "pin38",
label: "VSS",
net: "GND",
nc: false
},
{
id: "39",
selector: "pin39",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "40",
selector: "pin40",
label: "PA4",
net: "DAC1",
nc: false
},
{
id: "41",
selector: "pin41",
label: "PA5",
net: "DAC2",
nc: false
},
{
id: "42",
selector: "pin42",
label: "PA6",
net: "HIHAT_DECAY_POT",
nc: false
},
{
id: "43",
selector: "pin43",
label: "PA7",
net: "SAMPLER_B_VOICE_POT",
nc: false
},
{
id: "44",
selector: "pin44",
label: "PC4",
net: "SNARE_VOL_POT",
nc: false
},
{
id: "45",
selector: "pin45",
label: "PC5",
net: "SAMPLER_A_SPEED_POT",
nc: false
},
{
id: "46",
selector: "pin46",
label: "PB0",
net: "SAMPLER_B_SPEED_POT",
nc: false
},
{
id: "47",
selector: "pin47",
label: "PB1",
net: "HIHAT_VOL_POT",
nc: false
},
{
id: "48",
selector: "pin48",
label: "PB2",
net: "QSPI_CLK",
nc: false
},
{
id: "49",
selector: "pin49",
label: "PF11",
net: "SAMPLER_A_VOL_POT",
nc: false
},
{
id: "50",
selector: "pin50",
label: "PF12",
net: "SAMPLER_B_VOL_POT",
nc: false
},
{
id: "51",
selector: "pin51",
label: "VSS",
net: "GND",
nc: false
},
{
id: "52",
selector: "pin52",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "53",
selector: "pin53",
label: "PF13",
net: "TEMPO_POT",
nc: false
},
{
id: "54",
selector: "pin54",
label: "PF14",
net: "unconnected_U2_Pad54",
nc: true
},
{
id: "55",
selector: "pin55",
label: "PF15",
net: "unconnected_U2_Pad55",
nc: true
},
{
id: "56",
selector: "pin56",
label: "PG0",
net: "unconnected_U2_Pad56",
nc: true
},
{
id: "57",
selector: "pin57",
label: "PG1",
net: "unconnected_U2_Pad57",
nc: true
},
{
id: "58",
selector: "pin58",
label: "PE7",
net: "QSPI_BK2_IO0",
nc: false
},
{
id: "59",
selector: "pin59",
label: "PE8",
net: "QSPI_BK2_IO1",
nc: false
},
{
id: "60",
selector: "pin60",
label: "PE9",
net: "QSPI_BK2_IO2",
nc: false
},
{
id: "61",
selector: "pin61",
label: "VSS",
net: "GND",
nc: false
},
{
id: "62",
selector: "pin62",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "63",
selector: "pin63",
label: "PE10",
net: "QSPI_BK2_IO3",
nc: false
},
{
id: "64",
selector: "pin64",
label: "PE11",
net: "HH_BTN",
nc: false
},
{
id: "65",
selector: "pin65",
label: "PE12",
net: "unconnected_U2_Pad65",
nc: true
},
{
id: "66",
selector: "pin66",
label: "PE13",
net: "unconnected_U2_Pad66",
nc: true
},
{
id: "67",
selector: "pin67",
label: "PE14",
net: "SAMPLER_A_CLAMP",
nc: false
},
{
id: "68",
selector: "pin68",
label: "PE15",
net: "SAMPLER_B_CLAMP",
nc: false
},
{
id: "69",
selector: "pin69",
label: "PB10",
net: "unconnected_U2_Pad69",
nc: true
},
{
id: "70",
selector: "pin70",
label: "PB11",
net: "unconnected_U2_Pad70",
nc: true
},
{
id: "71",
selector: "pin71",
label: "VCAP1",
net: "Net_C18_Pad1",
nc: false
},
{
id: "72",
selector: "pin72",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "73",
selector: "pin73",
label: "PB12",
net: "DAC_LRCLK",
nc: false
},
{
id: "74",
selector: "pin74",
label: "PB13",
net: "DAC_BCLK",
nc: false
},
{
id: "75",
selector: "pin75",
label: "PB14",
net: "unconnected_U2_Pad75",
nc: true
},
{
id: "76",
selector: "pin76",
label: "PB15",
net: "DAC_DATA",
nc: false
},
{
id: "77",
selector: "pin77",
label: "PD8",
net: "unconnected_U2_Pad77",
nc: true
},
{
id: "78",
selector: "pin78",
label: "PD9",
net: "TEMPO_CLOCK",
nc: false
},
{
id: "79",
selector: "pin79",
label: "PD10",
net: "unconnected_U2_Pad79",
nc: true
},
{
id: "80",
selector: "pin80",
label: "PD11",
net: "QSPI_BK1_IO0",
nc: false
},
{
id: "81",
selector: "pin81",
label: "PD12",
net: "QSPI_BK1_IO1",
nc: false
},
{
id: "82",
selector: "pin82",
label: "PD13",
net: "QSPI_BK1_IO3",
nc: false
},
{
id: "83",
selector: "pin83",
label: "VSS",
net: "GND",
nc: false
},
{
id: "84",
selector: "pin84",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "85",
selector: "pin85",
label: "PD14",
net: "SA_LED_OUT",
nc: false
},
{
id: "86",
selector: "pin86",
label: "PD15",
net: "SB_LED_OUT",
nc: false
},
{
id: "87",
selector: "pin87",
label: "PG2",
net: "unconnected_U2_Pad87",
nc: true
},
{
id: "88",
selector: "pin88",
label: "PG3",
net: "unconnected_U2_Pad88",
nc: true
},
{
id: "89",
selector: "pin89",
label: "PG4",
net: "unconnected_U2_Pad89",
nc: true
},
{
id: "90",
selector: "pin90",
label: "PG5",
net: "unconnected_U2_Pad90",
nc: true
},
{
id: "91",
selector: "pin91",
label: "PG6",
net: "QSPI_BK1_NCS",
nc: false
},
{
id: "92",
selector: "pin92",
label: "PG7",
net: "unconnected_U2_Pad92",
nc: true
},
{
id: "93",
selector: "pin93",
label: "PG8",
net: "unconnected_U2_Pad93",
nc: true
},
{
id: "94",
selector: "pin94",
label: "VSS",
net: "GND",
nc: false
},
{
id: "95",
selector: "pin95",
label: "VDD33_USB",
net: "P3V3",
nc: false
},
{
id: "96",
selector: "pin96",
label: "PC6",
net: "SEQ_SELECT",
nc: false
},
{
id: "97",
selector: "pin97",
label: "PC7",
net: "HH_LED_OUT",
nc: false
},
{
id: "98",
selector: "pin98",
label: "PC8",
net: "SN_LED_OUT",
nc: false
},
{
id: "99",
selector: "pin99",
label: "PC9",
net: "KI_LED_OUT",
nc: false
},
{
id: "100",
selector: "pin100",
label: "PA8",
net: "unconnected_U2_Pad100",
nc: true
},
{
id: "101",
selector: "pin101",
label: "PA9",
net: "USB_VBUS",
nc: false
},
{
id: "102",
selector: "pin102",
label: "PA10",
net: "unconnected_U2_Pad102",
nc: true
},
{
id: "103",
selector: "pin103",
label: "PA11",
net: "USB_DM",
nc: false
},
{
id: "104",
selector: "pin104",
label: "PA12",
net: "USB_DP",
nc: false
},
{
id: "105",
selector: "pin105",
label: "PA13",
net: "SWIO",
nc: false
},
{
id: "106",
selector: "pin106",
label: "VCAP2",
net: "Net_C19_Pad1",
nc: false
},
{
id: "107",
selector: "pin107",
label: "VSS",
net: "GND",
nc: false
},
{
id: "108",
selector: "pin108",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "109",
selector: "pin109",
label: "PA14",
net: "SWCLK",
nc: false
},
{
id: "110",
selector: "pin110",
label: "PA15",
net: "unconnected_U2_Pad110",
nc: true
},
{
id: "111",
selector: "pin111",
label: "PC10",
net: "unconnected_U2_Pad111",
nc: true
},
{
id: "112",
selector: "pin112",
label: "PC11",
net: "QSPI_BK2_NCS",
nc: false
},
{
id: "113",
selector: "pin113",
label: "PC12",
net: "unconnected_U2_Pad113",
nc: true
},
{
id: "114",
selector: "pin114",
label: "PD0",
net: "unconnected_U2_Pad114",
nc: true
},
{
id: "115",
selector: "pin115",
label: "PD1",
net: "KICK_CLAMP",
nc: false
},
{
id: "116",
selector: "pin116",
label: "PD2",
net: "unconnected_U2_Pad116",
nc: true
},
{
id: "117",
selector: "pin117",
label: "PD3",
net: "SNARE_CLAMP",
nc: false
},
{
id: "118",
selector: "pin118",
label: "PD4",
net: "unconnected_U2_Pad118",
nc: true
},
{
id: "119",
selector: "pin119",
label: "PD5",
net: "unconnected_U2_Pad119",
nc: true
},
{
id: "120",
selector: "pin120",
label: "VSS",
net: "GND",
nc: false
},
{
id: "121",
selector: "pin121",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "122",
selector: "pin122",
label: "PD6",
net: "unconnected_U2_Pad122",
nc: true
},
{
id: "123",
selector: "pin123",
label: "PD7",
net: "OH_CLAMP",
nc: false
},
{
id: "124",
selector: "pin124",
label: "PG9",
net: "unconnected_U2_Pad124",
nc: true
},
{
id: "125",
selector: "pin125",
label: "PG10",
net: "CH_CLAMP",
nc: false
},
{
id: "126",
selector: "pin126",
label: "PG11",
net: "unconnected_U2_Pad126",
nc: true
},
{
id: "127",
selector: "pin127",
label: "PG12",
net: "OCTOSPIM_P2_NCS",
nc: false
},
{
id: "128",
selector: "pin128",
label: "PG13",
net: "SB_BTN",
nc: false
},
{
id: "129",
selector: "pin129",
label: "PG14",
net: "unconnected_U2_Pad129",
nc: true
},
{
id: "130",
selector: "pin130",
label: "VSS",
net: "GND",
nc: false
},
{
id: "131",
selector: "pin131",
label: "VDD",
net: "P3V3",
nc: false
},
{
id: "132",
selector: "pin132",
label: "PG15",
net: "unconnected_U2_Pad132",
nc: true
},
{
id: "133",
selector: "pin133",
label: "PB3",
net: "unconnected_U2_Pad133",
nc: true
},
{
id: "134",
selector: "pin134",
label: "PB4",
net: "unconnected_U2_Pad134",
nc: true
},
{
id: "135",
selector: "pin135",
label: "PB5",
net: "SN_BTN",
nc: false
},
{
id: "136",
selector: "pin136",
label: "PB6",
net: "KI_BTN",
nc: false
},
{
id: "137",
selector: "pin137",
label: "PB7",
net: "SA_BTN",
nc: false
},
{
id: "138",
selector: "pin138",
label: "BOOT0",
net: "Net_R10_Pad2",
nc: false
},
{
id: "139",
selector: "pin139",
label: "PB8",
net: "unconnected_U2_Pad139",
nc: true
},
{
id: "140",
selector: "pin140",
label: "PB9",
net: "unconnected_U2_Pad140",
nc: true
},
{
id: "141",
selector: "pin141",
label: "PE0",
net: "MIDI_UART",
nc: false
},
{
id: "142",
selector: "pin142",
label: "PE1",
net: "MIDI_LEARN",
nc: false
},
{
id: "143",
selector: "pin143",
label: "PDR_ON",
net: "P3V3",
nc: false
},
{
id: "144",
selector: "pin144",
label: "VDD",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 8.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 8.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 7.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 7.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 6.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin5"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 6.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin6"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 5.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin7"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 5.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin8"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 4.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin9"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 4.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin10"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 3.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin11"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 3.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin12"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 2.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin13"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 2.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin14"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 1.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin15"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 1.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin16"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 0.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin17"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 0.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin18"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -0.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin19"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -0.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin20"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -1.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin21"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -1.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin22"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -2.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin23"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -2.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin24"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -3.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin25"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -3.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin26"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -4.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin27"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -4.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin28"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -5.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin29"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -5.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin30"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -6.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin31"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -6.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin32"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -7.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin33"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -7.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin34"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -8.25,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin35"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -8.75,
y: 10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin36"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 8.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin37"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 8.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin38"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 7.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin39"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 7.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin40"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 6.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin41"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 6.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin42"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 5.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin43"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 5.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin44"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 4.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin45"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 4.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin46"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 3.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin47"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 3.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin48"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 2.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin49"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 2.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin50"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 1.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin51"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 1.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin52"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 0.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin53"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: 0.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin54"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -0.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin55"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -0.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin56"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -1.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin57"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -1.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin58"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -2.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin59"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -2.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin60"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -3.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin61"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -3.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin62"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -4.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin63"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -4.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin64"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -5.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin65"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -5.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin66"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -6.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin67"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -6.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin68"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -7.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin69"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -7.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin70"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -8.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin71"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -10.662499999999994,
y: -8.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin72"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -8.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin73"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -8.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin74"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -7.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin75"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -7.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin76"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -6.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin77"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -6.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin78"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -5.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin79"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -5.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin80"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -4.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin81"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -4.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin82"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -3.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin83"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -3.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin84"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -2.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin85"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -2.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin86"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -1.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin87"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -1.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin88"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -0.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin89"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: -0.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin90"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 0.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin91"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 0.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin92"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 1.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin93"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 1.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin94"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 2.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin95"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 2.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin96"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 3.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin97"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 3.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin98"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 4.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin99"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 4.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin100"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 5.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin101"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 5.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin102"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 6.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin103"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 6.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin104"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 7.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin105"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 7.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin106"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 8.25,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin107"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 8.75,
y: -10.662499999999994,
width: 0.3,
height: 1.475,
layer: "top",
port_hints: [
"pin108"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -8.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin109"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -8.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin110"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -7.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin111"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -7.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin112"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -6.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin113"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -6.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin114"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -5.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin115"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -5.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin116"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -4.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin117"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -4.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin118"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -3.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin119"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -3.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin120"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -2.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin121"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -2.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin122"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -1.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin123"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -1.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin124"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -0.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin125"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: -0.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin126"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 0.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin127"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 0.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin128"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 1.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin129"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 1.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin130"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 2.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin131"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 2.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin132"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 3.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin133"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 3.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin134"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 4.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin135"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 4.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin136"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 5.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin137"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 5.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin138"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 6.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin139"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 6.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin140"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 7.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin141"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 7.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin142"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 8.25,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin143"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_smtpad",
x: 10.662499999999994,
y: 8.75,
width: 1.475,
height: 0.3,
layer: "top",
port_hints: [
"pin144"
],
shape: "rect",
corner_radius: 0.0375
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -10.11,
y: 10.11
},
{
x: -9.159999999999997,
y: 10.11
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -10.11,
y: 9.159999999999997
},
{
x: -10.11,
y: 10.11
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -10.11,
y: -9.159999999999997
},
{
x: -10.11,
y: -10.11
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -10.11,
y: -10.11
},
{
x: -9.159999999999997,
y: -10.11
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 9.159999999999997,
y: 10.11
},
{
x: 9.159999999999997,
y: 11.400000000000006
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 10.11,
y: 10.11
},
{
x: 9.159999999999997,
y: 10.11
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 10.11,
y: 9.159999999999997
},
{
x: 10.11,
y: 10.11
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 10.11,
y: -9.159999999999997
},
{
x: 10.11,
y: -10.11
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 10.11,
y: -10.11
},
{
x: 9.159999999999997,
y: -10.11
}
],
stroke_width: 0.12
}
],
section: "Microcontroller",
schX: 65,
schY: -260,
schRotation: 0,
schWidth: 2.91
},
{
name: "Y1",
value: "12MHz 20pF",
ftype: "simple_chip",
x: -1.7999999999999972,
y: 25.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C26_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C23_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -2.075000000000003,
y: 0,
width: 2.45,
height: 2.4,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 2.125,
y: 0,
width: 2.55,
height: 2.4,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.049999999999997,
y: 1.7999999999999972
},
{
x: -3.049999999999997,
y: -1.7999999999999972
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.049999999999997,
y: -1.7999999999999972
},
{
x: 2.700000000000003,
y: -1.7999999999999972
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.700000000000003,
y: 1.7999999999999972
},
{
x: -3.049999999999997,
y: 1.7999999999999972
}
],
stroke_width: 0.12
}
],
section: "Clock",
schX: 128.65,
schY: -265.7,
schRotation: 0,
schWidth: 0.7
},
{
name: "C20",
value: "100pF",
ftype: "simple_capacitor",
x: -12.299999999999997,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C20_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C20_Pad2",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -48,
schRotation: 0
},
{
name: "C16",
value: "1uF",
ftype: "simple_capacitor",
x: -7.799999999999997,
y: 21.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 67.6,
schY: -24,
schRotation: 90
},
{
name: "D1",
value: "1N5819",
ftype: "simple_diode",
x: 14.599999999999994,
y: 46.2875,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "K",
net: "VCC",
nc: false
},
{
id: "2",
selector: "pin2",
label: "A",
net: "P12V",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -1.6499999999999986,
width: 1.2,
height: 0.9,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 0,
y: 1.6499999999999986,
width: 1.2,
height: 0.9,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1,
y: -2.25
},
{
x: -1,
y: 1.6499999999999986
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1,
y: -2.25
},
{
x: 1,
y: -2.25
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1,
y: -2.25
},
{
x: 1,
y: 1.6499999999999986
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 65,
schY: -13,
schRotation: 0,
schWidth: 1.39,
verticalPins: [
"pin1",
"pin2"
]
},
{
name: "C5",
value: "100nF",
ftype: "simple_capacitor",
x: -13.899999999999991,
y: 14.900000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: 0.5100000000000051
},
{
x: 0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: -0.5100000000000051
},
{
x: 0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -54,
schRotation: 90
},
{
name: "R29",
value: "4k7",
ftype: "simple_resistor",
x: -31.19999999999999,
y: -24.299999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SAMPLER_A_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_Q6_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472399999999595,
y: 0.5224999999999937
},
{
x: 0.25472399999999595,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472399999999595,
y: -0.5224999999999937
},
{
x: 0.25472399999999595,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -54,
schRotation: 0
},
{
name: "TP1",
value: "TestPoint",
ftype: "simple_test_point",
x: -10.199999999999989,
y: -21.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "DAC_LRCLK",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 130,
schY: -6,
schRotation: 0
},
{
name: "R6",
value: "1k",
ftype: "simple_resistor",
x: 0.30000000000001137,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C17_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "DAC_OUT_L",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: -0.25472400000001016
},
{
x: -0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: -0.25472400000001016
},
{
x: 0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -54,
schRotation: 0
},
{
name: "C26",
value: "30pF",
ftype: "simple_capacitor",
x: -3.5999999999999943,
y: 28.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C26_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: 0.5100000000000051
},
{
x: -0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: -0.5100000000000051
},
{
x: -0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Clock",
schX: 131.61,
schY: -266,
schRotation: -90
},
{
name: "R31",
value: "4k7",
ftype: "simple_resistor",
x: -31.19999999999999,
y: -28.5,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SAMPLER_B_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_Q7_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472399999999595,
y: 0.5224999999999937
},
{
x: 0.25472399999999595,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472399999999595,
y: -0.522500000000008
},
{
x: 0.25472399999999595,
y: -0.522500000000008
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -60,
schRotation: 0
},
{
name: "R2",
value: "47k",
ftype: "simple_resistor",
x: -6.8999999999999915,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C1_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C1_Pad2",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: 0.25472400000001016
},
{
x: -0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: 0.25472400000001016
},
{
x: 0.5224999999999937,
y: -0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -60,
schRotation: 0
},
{
name: "C27",
value: "100nF",
ftype: "simple_capacitor",
x: 0.8000000000000114,
y: -18.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3V3",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: 0.5100000000000051
},
{
x: 0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: -0.5100000000000051
},
{
x: 0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -60,
schRotation: -90
},
{
name: "TP6",
value: "TestPoint",
ftype: "simple_test_point",
x: -26.39999999999999,
y: 33,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 145,
schY: -6,
schRotation: 0
},
{
name: "U3",
value: "W25Q128JVS",
ftype: "simple_chip",
x: 0.20000000000000284,
y: -14,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "~{CS}",
net: "QSPI_BK1_NCS",
nc: false
},
{
id: "2",
selector: "pin2",
label: "DO(IO1)",
net: "QSPI_BK1_IO1",
nc: false
},
{
id: "3",
selector: "pin3",
label: "IO2",
net: "QSPI_BK1_IO2",
nc: false
},
{
id: "4",
selector: "pin4",
label: "GND",
net: "GND",
nc: false
},
{
id: "5",
selector: "pin5",
label: "DI(IO0)",
net: "QSPI_BK1_IO0",
nc: false
},
{
id: "6",
selector: "pin6",
label: "CLK",
net: "QSPI_CLK",
nc: false
},
{
id: "7",
selector: "pin7",
label: "IO3",
net: "QSPI_BK1_IO3",
nc: false
},
{
id: "8",
selector: "pin8",
label: "VCC",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: -1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: -0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: 0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 3.5999999999999943,
y: 1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: 1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin5"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: 0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin6"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: -0.6350000000000051,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin7"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -3.5999999999999943,
y: -1.9050000000000011,
width: 1.6,
height: 0.6,
layer: "top",
port_hints: [
"pin8"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.7249999999999943,
y: 2.7249999999999943
},
{
x: -2.7249999999999943,
y: 2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.7249999999999943,
y: -2.7249999999999943
},
{
x: -2.7249999999999943,
y: -2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 2.7249999999999943
},
{
x: -2.7249999999999943,
y: 2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 2.7249999999999943
},
{
x: 2.7249999999999943,
y: 2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -2.7249999999999943
},
{
x: -2.7249999999999943,
y: -2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -2.7249999999999943
},
{
x: 2.7249999999999943,
y: -2.7249999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.7249999999999943,
y: 2.7249999999999943
},
{
x: 2.7249999999999943,
y: 2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.7249999999999943,
y: -2.4650000000000034
},
{
x: 4.400000000000006,
y: -2.4650000000000034
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.7249999999999943,
y: -2.7249999999999943
},
{
x: 2.7249999999999943,
y: -2.4650000000000034
}
],
stroke_width: 0.12
}
],
section: "QSPI_Flash",
schX: 145,
schY: -130,
schRotation: 0,
schWidth: 2.53
},
{
name: "C41",
value: "22uF",
ftype: "simple_capacitor",
x: -27.599999999999994,
y: 39,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3_3VA",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -1.7999999999999972,
width: 1.6,
height: 2.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_smtpad",
x: 0,
y: 1.7999999999999972,
width: 1.6,
height: 2.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.260000000000005,
y: 2.259999999999998
},
{
x: -1.0600000000000023,
y: 2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.260000000000005,
y: -1.195563
},
{
x: -2.260000000000005,
y: 2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.8100000000000023,
y: -2.75
},
{
x: -1.3100000000000023,
y: -2.75
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.5600000000000023,
y: -3
},
{
x: -1.5600000000000023,
y: -2.5
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.195563000000007,
y: -2.259999999999998
},
{
x: -2.260000000000005,
y: -1.195563
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.195563000000007,
y: -2.259999999999998
},
{
x: -1.0600000000000023,
y: -2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.1955629999999928,
y: -2.259999999999998
},
{
x: 1.0600000000000023,
y: -2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.1955629999999928,
y: -2.259999999999998
},
{
x: 2.260000000000005,
y: -1.195563
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.260000000000005,
y: 2.259999999999998
},
{
x: 1.0600000000000023,
y: 2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.260000000000005,
y: -1.195563
},
{
x: 2.260000000000005,
y: 2.259999999999998
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 68.9,
schY: -24,
schRotation: -90
},
{
name: "RESET1",
value: "SW_Push",
ftype: "simple_chip",
x: -15.799999999999997,
y: 29.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_RESET1_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
},
{
id: "1",
selector: "pin3",
label: "1_DUP",
net: "Net_RESET1_Pad1",
nc: false,
physicalDuplicate: true
},
{
id: "2",
selector: "pin4",
label: "2_DUP",
net: "GND",
nc: false,
physicalDuplicate: true
}
],
footprint: [
{
type: "pcb_smtpad",
x: 3.4000000000000057,
y: -2,
width: 2.2,
height: 1,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: -3.4000000000000057,
y: -2,
width: 2.2,
height: 1,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 3.4000000000000057,
y: 2,
width: 2.2,
height: 1,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: -3.4000000000000057,
y: 2,
width: 2.2,
height: 1,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.3499999999999943,
y: 3.0999999999999943
},
{
x: -3.3499999999999943,
y: 2.9000000000000057
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.3499999999999943,
y: -1.2000000000000028
},
{
x: -3.3499999999999943,
y: 1.2000000000000028
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.3499999999999943,
y: -3.0999999999999943
},
{
x: -3.3499999999999943,
y: -2.9000000000000057
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -3.3499999999999943,
y: -3.0999999999999943
},
{
x: 3.3499999999999943,
y: -3.0999999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.3499999999999943,
y: 3.0999999999999943
},
{
x: -3.3499999999999943,
y: 3.0999999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.3499999999999943,
y: 3.0999999999999943
},
{
x: 3.3499999999999943,
y: 2.9000000000000057
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.3499999999999943,
y: -1.2000000000000028
},
{
x: 3.3499999999999943,
y: 1.2000000000000028
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 3.3499999999999943,
y: -3.0999999999999943
},
{
x: 3.3499999999999943,
y: -2.9000000000000057
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -60,
schRotation: 0
},
{
name: "R26",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 13.099999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SNARE_CLAMP",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: 0.5224999999999937
},
{
x: 0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: -0.5224999999999937
},
{
x: 0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -66,
schRotation: 90
},
{
name: "C42",
value: "47uF",
ftype: "simple_capacitor",
x: 31.700000000000017,
y: 40.1,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3V3",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 1.4625000000000057,
y: 0,
width: 1.125,
height: 1.75,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.12499999998750001
},
{
type: "pcb_smtpad",
x: -1.4625000000000057,
y: 0,
width: 1.125,
height: 1.75,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.12499999998750001
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.7270640000000128,
y: 0.9099999999999966
},
{
x: -0.7270640000000128,
y: 0.9100000000000037
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.7270640000000128,
y: -0.9100000000000037
},
{
x: -0.7270640000000128,
y: -0.9099999999999966
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 95,
schY: -13,
schRotation: -90
},
{
name: "L2",
value: "L",
ftype: "simple_inductor",
x: -27.599999999999994,
y: 46.2,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3_3VA",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "VO",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -1.0625,
width: 1.2,
height: 0.875,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.109375
},
{
type: "pcb_smtpad",
x: 0,
y: 1.0625,
width: 1.2,
height: 0.875,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.109375
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5600000000000023,
y: -0.3996220000000008
},
{
x: -0.5600000000000023,
y: 0.3996220000000008
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5600000000000023,
y: -0.3996220000000008
},
{
x: 0.5600000000000023,
y: 0.3996220000000008
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 110,
schY: -13,
schRotation: 0,
verticalPins: [
"pin1",
"pin2"
]
},
{
name: "Q3",
value: "MMBT3904",
ftype: "simple_transistor",
x: 28.599999999999994,
y: 20.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "B",
net: "Net_Q3_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "E",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "C",
net: "CH_CLAMP",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9375,
y: -0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: 0.9375,
y: 0.9500000000000028,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_smtpad",
x: -0.9375,
y: 0,
width: 1.475,
height: 0.6,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect",
corner_radius: 0.075
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: -0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: 1.5600000000000023
},
{
x: 0.6500000000000057,
y: 1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: -0.6500000000000057,
y: -1.5600000000000023
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0,
y: -1.5600000000000023
},
{
x: 1.6750000000000114,
y: -1.5600000000000023
}
],
stroke_width: 0.12
}
],
section: "Input_Clamps",
schX: 95,
schY: -136,
schRotation: 0,
schWidth: 1.39
},
{
name: "R12",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 15.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "OH_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_Q2_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -66,
schRotation: 0
},
{
name: "C18",
value: "2.2uF",
ftype: "simple_capacitor",
x: -14,
y: -1.2000000000000028,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C18_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: 0.5100000000000051
},
{
x: -0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: -0.5100000000000051
},
{
x: -0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -66,
schRotation: -90
},
{
name: "C9",
value: "100nF",
ftype: "simple_capacitor",
x: -1.7999999999999972,
y: -6.799999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: -0.1462669999999946
},
{
x: -0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: -0.1462669999999946
},
{
x: 0.5100000000000051,
y: 0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -66,
schRotation: 90
},
{
name: "D2",
value: "1N5819",
ftype: "simple_diode",
x: -35.599999999999994,
y: 46.2,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "K",
net: "net_12V",
nc: false
},
{
id: "2",
selector: "pin2",
label: "A",
net: "VEE",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 1.6499999999999986,
width: 1.2,
height: 0.9,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 0,
y: -1.6499999999999986,
width: 1.2,
height: 0.9,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1,
y: 2.25
},
{
x: -1,
y: -1.6499999999999986
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1,
y: 2.25
},
{
x: -1,
y: 2.25
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1,
y: 2.25
},
{
x: 1,
y: -1.6499999999999986
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 65,
schY: -32,
schRotation: 0,
schWidth: 1.39,
verticalPins: [
"pin1",
"pin2"
]
},
{
name: "C29",
value: "100nF",
ftype: "simple_capacitor",
x: 13.099999999999994,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3_3VA",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5099999999999909,
y: 0.1462669999999946
},
{
x: -0.5099999999999909,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5099999999999909,
y: 0.1462669999999946
},
{
x: 0.5099999999999909,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 70.2,
schY: -24,
schRotation: -90
},
{
name: "R20",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 8.900000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "KICK_CLAMP",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: 0.5224999999999937
},
{
x: 0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: -0.5224999999999937
},
{
x: 0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -72,
schRotation: 90
},
{
name: "C35",
value: "100nF",
ftype: "simple_capacitor",
x: 8.5,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C35_Pad2",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -72,
schRotation: 90
},
{
name: "C7",
value: "100nF",
ftype: "simple_capacitor",
x: -14,
y: 3.9000000000000057,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: 0.5100000000000051
},
{
x: 0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: -0.5100000000000051
},
{
x: 0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -72,
schRotation: 90
},
{
name: "C2",
value: "4.7uF",
ftype: "simple_capacitor",
x: 6.200000000000003,
y: 21.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 80,
schY: -19.5,
schRotation: 90
},
{
name: "C43",
value: "22uF",
ftype: "simple_capacitor",
x: -35.599999999999994,
y: 39,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "VEE",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -1.7999999999999972,
width: 1.6,
height: 2.6,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_smtpad",
x: 0,
y: 1.7999999999999972,
width: 1.6,
height: 2.6,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.260000000000005,
y: 2.259999999999998
},
{
x: -1.0600000000000023,
y: 2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.260000000000005,
y: -1.195563
},
{
x: -2.260000000000005,
y: 2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.8100000000000023,
y: -2.75
},
{
x: -1.3100000000000023,
y: -2.75
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.5600000000000023,
y: -3
},
{
x: -1.5600000000000023,
y: -2.5
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.195563000000007,
y: -2.259999999999998
},
{
x: -2.260000000000005,
y: -1.195563
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.195563000000007,
y: -2.259999999999998
},
{
x: -1.0600000000000023,
y: -2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.1955629999999928,
y: -2.259999999999998
},
{
x: 1.0600000000000023,
y: -2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.1955629999999928,
y: -2.259999999999998
},
{
x: 2.260000000000005,
y: -1.195563
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.260000000000005,
y: 2.259999999999998
},
{
x: 1.0600000000000023,
y: 2.259999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.260000000000005,
y: -1.195563
},
{
x: 2.260000000000005,
y: 2.259999999999998
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 95,
schY: -19.5,
schRotation: 90
},
{
name: "C12",
value: "100nF",
ftype: "simple_capacitor",
x: 14.400000000000006,
y: 9.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.8625000000000114,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.8625000000000114,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: 0.5100000000000051
},
{
x: -0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.1462669999999946,
y: -0.5100000000000051
},
{
x: -0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -78,
schRotation: 90
},
{
name: "R15",
value: "15k",
ftype: "simple_resistor",
x: -8.299999999999997,
y: -30.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C20_Pad2",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C24_Pad1",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: -0.25472400000001016
},
{
x: -0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: -0.25472400000001016
},
{
x: 0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -78,
schRotation: 0
},
{
name: "U6",
value: "TPS561201",
ftype: "simple_chip",
x: 25.950000000000017,
y: 43.7,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "GND",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "SW",
net: "VSW",
nc: false
},
{
id: "3",
selector: "pin3",
label: "VIN",
net: "VCC",
nc: false
},
{
id: "4",
selector: "pin4",
label: "VFB",
net: "FB",
nc: false
},
{
id: "5",
selector: "pin5",
label: "EN",
net: "VCC",
nc: false
},
{
id: "6",
selector: "pin6",
label: "VBST",
net: "CB",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 1.3499999999999943,
y: -0.9500000000000028,
width: 1.56,
height: 0.65,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 1.3499999999999943,
y: 0,
width: 1.56,
height: 0.65,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: 1.3499999999999943,
y: 0.9500000000000028,
width: 1.56,
height: 0.65,
layer: "top",
port_hints: [
"pin3"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: -1.3499999999999943,
y: 0.9500000000000028,
width: 1.56,
height: 0.65,
layer: "top",
port_hints: [
"pin4"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: -1.3499999999999943,
y: 0,
width: 1.56,
height: 0.65,
layer: "top",
port_hints: [
"pin5"
],
shape: "rect"
},
{
type: "pcb_smtpad",
x: -1.3499999999999943,
y: -0.9500000000000028,
width: 1.56,
height: 0.65,
layer: "top",
port_hints: [
"pin6"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.9000000000000057,
y: -1.6099999999999994
},
{
x: 2.0500000000000114,
y: -1.6099999999999994
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.9000000000000057,
y: 1.6099999999999994
},
{
x: -0.9000000000000057,
y: 1.6099999999999994
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 110,
schY: -19.5,
schRotation: 0,
schWidth: 1.865
},
{
name: "C21",
value: "1uF",
ftype: "simple_capacitor",
x: -11,
y: 21.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 71.5,
schY: -24,
schRotation: 90
},
{
name: "C17",
value: "2n2",
ftype: "simple_capacitor",
x: -1.5,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C17_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -78,
schRotation: -90
},
{
name: "TP5",
value: "TestPoint",
ftype: "simple_test_point",
x: 25.200000000000017,
y: 33,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 160,
schY: -6,
schRotation: 0
},
{
name: "J6",
value: "SWD_Header",
ftype: "simple_chip",
x: 23.900000000000006,
y: -6.299999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "Pin_1",
net: "P3V3",
nc: false
},
{
id: "2",
selector: "pin2",
label: "Pin_2",
net: "GND",
nc: false
},
{
id: "3",
selector: "pin3",
label: "Pin_3",
net: "SWIO",
nc: false
},
{
id: "4",
selector: "pin4",
label: "Pin_4",
net: "SWCLK",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circular_hole_with_rect_pad",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_shape: "circle",
pad_shape: "rect",
hole_diameter: 1,
rect_ccw_rotation: 0,
rect_pad_width: 1.7,
rect_pad_height: 1.7,
hole_offset_x: 0,
hole_offset_y: 0,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 2.539999999999992,
y: 0,
port_hints: [
"pin2"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 5.0800000000000125,
y: 0,
port_hints: [
"pin3"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "circle",
x: 7.6200000000000045,
y: 0,
port_hints: [
"pin4"
],
hole_diameter: 1,
outer_diameter: 1.7,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.2700000000000102,
y: 1.269999999999996
},
{
x: -1.2700000000000102,
y: -1.269999999999996
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.2700000000000102,
y: -1.269999999999996
},
{
x: 8.889999999999986,
y: -1.269999999999996
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 8.889999999999986,
y: 1.269999999999996
},
{
x: -1.2700000000000102,
y: 1.269999999999996
}
],
stroke_width: 0.15
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 8.889999999999986,
y: -1.269999999999996
},
{
x: 8.889999999999986,
y: 1.269999999999996
}
],
stroke_width: 0.15
}
],
section: "Connectors",
schX: 15,
schY: -260,
schRotation: 0,
schWidth: 2.15
},
{
name: "C37",
value: "47uF",
ftype: "simple_capacitor",
x: 14.599999999999994,
y: 39,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "VCC",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 2.200000000000003,
width: 1.6,
height: 3,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_smtpad",
x: 0,
y: -2.200000000000003,
width: 1.6,
height: 3,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.125
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.760000000000005,
y: 1.695563
},
{
x: -2.760000000000005,
y: -2.759999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -2.760000000000005,
y: -2.759999999999998
},
{
x: -1.0600000000000023,
y: -2.759999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.6955629999999928,
y: 2.759999999999998
},
{
x: -2.760000000000005,
y: 1.695563
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -1.6955629999999928,
y: 2.759999999999998
},
{
x: -1.0600000000000023,
y: 2.759999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.6850000000000023,
y: 3.625
},
{
x: 1.6850000000000023,
y: 3
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.6955629999999928,
y: 2.759999999999998
},
{
x: 1.0600000000000023,
y: 2.759999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.6955629999999928,
y: 2.759999999999998
},
{
x: 2.759999999999991,
y: 1.695563
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 1.9975000000000023,
y: 3.3125
},
{
x: 1.3725000000000023,
y: 3.3125
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.759999999999991,
y: 1.695563
},
{
x: 2.759999999999991,
y: -2.759999999999998
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 2.759999999999991,
y: -2.759999999999998
},
{
x: 1.0600000000000023,
y: -2.759999999999998
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 68.9,
schY: -18,
schRotation: -90
},
{
name: "C19",
value: "2.2uF",
ftype: "simple_capacitor",
x: 8.200000000000003,
y: -6.799999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C19_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -84,
schRotation: -90
},
{
name: "C22",
value: "100nF",
ftype: "simple_capacitor",
x: -9.399999999999991,
y: 21.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 72.8,
schY: -24,
schRotation: 90
},
{
name: "R21",
value: "560",
ftype: "simple_resistor",
x: 32.599999999999994,
y: -27.200000000000003,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "SN_LED",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "SN_LED_OUT",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -84,
schRotation: 0
},
{
name: "C8",
value: "100nF",
ftype: "simple_capacitor",
x: -14,
y: -3,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3V3",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: 0.5100000000000051
},
{
x: 0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: -0.5100000000000051
},
{
x: 0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -84,
schRotation: 90
},
{
name: "TP2",
value: "TestPoint",
ftype: "simple_test_point",
x: -2.3999999999999915,
y: -21.599999999999994,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "DAC_DATA",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 175,
schY: -6,
schRotation: 0
},
{
name: "C15",
value: "100nF",
ftype: "simple_capacitor",
x: -6.199999999999989,
y: 21.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8624999999999972,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 74.1,
schY: -24,
schRotation: 90
},
{
name: "R11",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 17.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "OH_CLAMP",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: 0.5224999999999937
},
{
x: 0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: -0.5224999999999937
},
{
x: 0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 15,
schY: -90,
schRotation: 90
},
{
name: "R14",
value: "1k",
ftype: "simple_resistor",
x: 11.100000000000009,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C24_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "DAC_OUT_R",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: -0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: 0.9124999999999943,
width: 0.95,
height: 0.975,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5224999999999937,
y: -0.25472400000001016
},
{
x: -0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5224999999999937,
y: -0.25472400000001016
},
{
x: 0.5224999999999937,
y: 0.25472400000001016
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 30,
schY: -90,
schRotation: 0
},
{
name: "R1",
value: "4k7",
ftype: "simple_resistor",
x: 32.599999999999994,
y: 25.900000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "MIDI_UART",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: 0.5224999999999937
},
{
x: 0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.25472400000001016,
y: -0.5224999999999937
},
{
x: 0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 45,
schY: -90,
schRotation: 90
},
{
name: "C1",
value: "100pF",
ftype: "simple_capacitor",
x: -5.099999999999994,
y: -43.19999999999999,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C1_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "Net_C1_Pad2",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0,
y: -0.8625000000000114,
width: 0.95,
height: 1.075,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.5100000000000051,
y: 0.1462669999999946
},
{
x: -0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.5100000000000051,
y: 0.1462669999999946
},
{
x: 0.5100000000000051,
y: -0.1462669999999946
}
],
stroke_width: 0.12
}
],
section: "Power",
schX: 80,
schY: -26,
schRotation: 0
},
{
name: "R19",
value: "560",
ftype: "simple_resistor",
x: 32.599999999999994,
y: -24.799999999999997,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "KI_LED",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "KI_LED_OUT",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: -0.9124999999999943,
y: 0,
width: 0.975,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: 0.5224999999999937
},
{
x: -0.25472400000001016,
y: 0.5224999999999937
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: 0.25472400000001016,
y: -0.5224999999999937
},
{
x: -0.25472400000001016,
y: -0.5224999999999937
}
],
stroke_width: 0.12
}
],
section: "Passives",
schX: 0,
schY: -96,
schRotation: 0
},
{
name: "TP4",
value: "TestPoint",
ftype: "simple_test_point",
x: 18.400000000000006,
y: 33,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circle",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_diameter: 1.3,
outer_diameter: 2,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
}
],
section: "Test_Points",
schX: 130,
schY: -12,
schRotation: 0
},
{
name: "C23",
value: "30pF",
ftype: "simple_capacitor",
x: 0.20000000000000284,
y: 28.400000000000006,
layer: "top",
pins: [
{
id: "1",
selector: "pin1",
label: "1",
net: "Net_C23_Pad1",
nc: false
},
{
id: "2",
selector: "pin2",
label: "2",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: -0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin1"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_smtpad",
x: 0.8624999999999972,
y: 0,
width: 1.075,
height: 0.95,
layer: "top",
port_hints: [
"pin2"
],
shape: "rect",
corner_radius: 0.11875
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: 0.5100000000000051
},
{
x: 0.1462669999999946,
y: 0.5100000000000051
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "top",
route: [
{
x: -0.1462669999999946,
y: -0.5100000000000051
},
{
x: 0.1462669999999946,
y: -0.5100000000000051
}
],
stroke_width: 0.12
}
],
section: "Clock",
schX: 125.69,
schY: -266,
schRotation: -90
},
{
name: "J3",
value: "Conn_01x12_Female",
ftype: "simple_chip",
x: 43.5,
y: 44,
layer: "bottom",
pins: [
{
id: "1",
selector: "pin1",
label: "Pin_1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "Pin_2",
net: "SA_BTN",
nc: false
},
{
id: "3",
selector: "pin3",
label: "Pin_3",
net: "KI_BTN",
nc: false
},
{
id: "4",
selector: "pin4",
label: "Pin_4",
net: "SN_BTN",
nc: false
},
{
id: "5",
selector: "pin5",
label: "Pin_5",
net: "SA_LED",
nc: false
},
{
id: "6",
selector: "pin6",
label: "Pin_6",
net: "SB_BTN",
nc: false
},
{
id: "7",
selector: "pin7",
label: "Pin_7",
net: "SB_LED",
nc: false
},
{
id: "8",
selector: "pin8",
label: "Pin_8",
net: "MIDI_LEARN",
nc: false
},
{
id: "9",
selector: "pin9",
label: "Pin_9",
net: "MIDI_IN",
nc: false
},
{
id: "10",
selector: "pin10",
label: "Pin_10",
net: "CH_IN",
nc: false
},
{
id: "11",
selector: "pin11",
label: "Pin_11",
net: "OH_IN",
nc: false
},
{
id: "12",
selector: "pin12",
label: "Pin_12",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circular_hole_with_rect_pad",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_shape: "circle",
pad_shape: "rect",
hole_diameter: 1,
rect_ccw_rotation: 180,
rect_pad_width: 1.7,
rect_pad_height: 1.7,
hole_offset_x: 0,
hole_offset_y: 0,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -2.539999999999999,
port_hints: [
"pin2"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -5.079999999999998,
port_hints: [
"pin3"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -7.619999999999997,
port_hints: [
"pin4"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -10.159999999999997,
port_hints: [
"pin5"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -12.700000000000003,
port_hints: [
"pin6"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -15.239999999999995,
port_hints: [
"pin7"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -17.78,
port_hints: [
"pin8"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -20.319999999999993,
port_hints: [
"pin9"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -22.86,
port_hints: [
"pin10"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -25.400000000000006,
port_hints: [
"pin11"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -27.939999999999998,
port_hints: [
"pin12"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1.3300000000000125,
y: -1.2700000000000031
},
{
x: -1.3300000000000125,
y: -29.269999999999996
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: 1.3299999999999983
},
{
x: 0,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: 0
},
{
x: 1.3300000000000125,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: -1.2700000000000031
},
{
x: -1.3300000000000125,
y: -1.2700000000000031
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: -1.2700000000000031
},
{
x: 1.329999999999984,
y: -29.269999999999996
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.329999999999984,
y: -29.269999999999996
},
{
x: -1.3300000000000125,
y: -29.269999999999996
}
],
stroke_width: 0.12
}
],
section: "Connectors",
schX: 30,
schY: -260,
schRotation: 0,
schWidth: 2.245
},
{
name: "J1",
value: "Conn_01x12_Female",
ftype: "simple_chip",
x: -43.5,
y: 44,
layer: "bottom",
pins: [
{
id: "1",
selector: "pin1",
label: "Pin_1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "Pin_2",
net: "SNARE_FILTER_POT",
nc: false
},
{
id: "3",
selector: "pin3",
label: "Pin_3",
net: "SAMPLER_A_VOICE_POT",
nc: false
},
{
id: "4",
selector: "pin4",
label: "Pin_4",
net: "KICK_ATTACK_POT",
nc: false
},
{
id: "5",
selector: "pin5",
label: "Pin_5",
net: "KICK_DECAY_POT",
nc: false
},
{
id: "6",
selector: "pin6",
label: "Pin_6",
net: "KICK_VOL_POT",
nc: false
},
{
id: "7",
selector: "pin7",
label: "Pin_7",
net: "SNARE_TUNING_POT",
nc: false
},
{
id: "8",
selector: "pin8",
label: "Pin_8",
net: "HIHAT_DECAY_POT",
nc: false
},
{
id: "9",
selector: "pin9",
label: "Pin_9",
net: "SAMPLER_B_VOICE_POT",
nc: false
},
{
id: "10",
selector: "pin10",
label: "Pin_10",
net: "SNARE_VOL_POT",
nc: false
},
{
id: "11",
selector: "pin11",
label: "Pin_11",
net: "SAMPLER_A_SPEED_POT",
nc: false
},
{
id: "12",
selector: "pin12",
label: "Pin_12",
net: "SAMPLER_B_SPEED_POT",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circular_hole_with_rect_pad",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_shape: "circle",
pad_shape: "rect",
hole_diameter: 1,
rect_ccw_rotation: 180,
rect_pad_width: 1.7,
rect_pad_height: 1.7,
hole_offset_x: 0,
hole_offset_y: 0,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -2.539999999999999,
port_hints: [
"pin2"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -5.079999999999998,
port_hints: [
"pin3"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -7.619999999999997,
port_hints: [
"pin4"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -10.159999999999997,
port_hints: [
"pin5"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -12.700000000000003,
port_hints: [
"pin6"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -15.239999999999995,
port_hints: [
"pin7"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -17.78,
port_hints: [
"pin8"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -20.319999999999993,
port_hints: [
"pin9"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -22.86,
port_hints: [
"pin10"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -25.400000000000006,
port_hints: [
"pin11"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -27.939999999999998,
port_hints: [
"pin12"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1.3299999999999983,
y: -1.2700000000000031
},
{
x: -1.3299999999999983,
y: -29.269999999999996
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: 1.3299999999999983
},
{
x: 0,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: 0
},
{
x: 1.3299999999999983,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: -1.2700000000000031
},
{
x: -1.3299999999999983,
y: -1.2700000000000031
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: -1.2700000000000031
},
{
x: 1.3299999999999983,
y: -29.269999999999996
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: -29.269999999999996
},
{
x: -1.3299999999999983,
y: -29.269999999999996
}
],
stroke_width: 0.12
}
],
section: "Connectors",
schX: 45,
schY: -260,
schRotation: 0,
schWidth: 2.245
},
{
name: "J4",
value: "Conn_01x12_Female",
ftype: "simple_chip",
x: 43.5,
y: -12,
layer: "bottom",
pins: [
{
id: "1",
selector: "pin1",
label: "Pin_1",
net: "SNARE_IN",
nc: false
},
{
id: "2",
selector: "pin2",
label: "Pin_2",
net: "KICK_IN",
nc: false
},
{
id: "3",
selector: "pin3",
label: "Pin_3",
net: "USB_DP",
nc: false
},
{
id: "4",
selector: "pin4",
label: "Pin_4",
net: "USB_DM",
nc: false
},
{
id: "5",
selector: "pin5",
label: "Pin_5",
net: "USB_VBUS",
nc: false
},
{
id: "6",
selector: "pin6",
label: "Pin_6",
net: "KI_LED",
nc: false
},
{
id: "7",
selector: "pin7",
label: "Pin_7",
net: "SN_LED",
nc: false
},
{
id: "8",
selector: "pin8",
label: "Pin_8",
net: "HH_LED",
nc: false
},
{
id: "9",
selector: "pin9",
label: "Pin_9",
net: "SEQ_SELECT",
nc: false
},
{
id: "10",
selector: "pin10",
label: "Pin_10",
net: "GND",
nc: false
},
{
id: "11",
selector: "pin11",
label: "Pin_11",
net: "GND",
nc: false
},
{
id: "12",
selector: "pin12",
label: "Pin_12",
net: "P3_3VA",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circular_hole_with_rect_pad",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_shape: "circle",
pad_shape: "rect",
hole_diameter: 1,
rect_ccw_rotation: 180,
rect_pad_width: 1.7,
rect_pad_height: 1.7,
hole_offset_x: 0,
hole_offset_y: 0,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -2.5400000000000063,
port_hints: [
"pin2"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -5.079999999999998,
port_hints: [
"pin3"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -7.6200000000000045,
port_hints: [
"pin4"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -10.159999999999997,
port_hints: [
"pin5"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -12.700000000000003,
port_hints: [
"pin6"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -15.239999999999995,
port_hints: [
"pin7"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -17.78,
port_hints: [
"pin8"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -20.319999999999993,
port_hints: [
"pin9"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -22.860000000000014,
port_hints: [
"pin10"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -25.400000000000006,
port_hints: [
"pin11"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -27.939999999999998,
port_hints: [
"pin12"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1.3300000000000125,
y: -1.269999999999996
},
{
x: -1.3300000000000125,
y: -29.27000000000001
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: 1.3299999999999983
},
{
x: 0,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: 0
},
{
x: 1.3300000000000125,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: -1.269999999999996
},
{
x: -1.3300000000000125,
y: -1.269999999999996
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3300000000000125,
y: -1.269999999999996
},
{
x: 1.329999999999984,
y: -29.27000000000001
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.329999999999984,
y: -29.27000000000001
},
{
x: -1.3300000000000125,
y: -29.27000000000001
}
],
stroke_width: 0.12
}
],
section: "Connectors",
schX: 0,
schY: -267,
schRotation: 0,
schWidth: 2.245
},
{
name: "J2",
value: "Conn_01x12_Female",
ftype: "simple_chip",
x: -43.5,
y: -12,
layer: "bottom",
pins: [
{
id: "1",
selector: "pin1",
label: "Pin_1",
net: "GND",
nc: false
},
{
id: "2",
selector: "pin2",
label: "Pin_2",
net: "HIHAT_VOL_POT",
nc: false
},
{
id: "3",
selector: "pin3",
label: "Pin_3",
net: "SAMPLER_A_VOL_POT",
nc: false
},
{
id: "4",
selector: "pin4",
label: "Pin_4",
net: "SAMPLER_B_VOL_POT",
nc: false
},
{
id: "5",
selector: "pin5",
label: "Pin_5",
net: "HH_BTN",
nc: false
},
{
id: "6",
selector: "pin6",
label: "Pin_6",
net: "TEMPO_POT",
nc: false
},
{
id: "7",
selector: "pin7",
label: "Pin_7",
net: "SAMPLER_A_IN",
nc: false
},
{
id: "8",
selector: "pin8",
label: "Pin_8",
net: "SAMPLER_B_IN",
nc: false
},
{
id: "9",
selector: "pin9",
label: "Pin_9",
net: "AUDIO_OUT_R",
nc: false
},
{
id: "10",
selector: "pin10",
label: "Pin_10",
net: "TEMPO_OUT",
nc: false
},
{
id: "11",
selector: "pin11",
label: "Pin_11",
net: "AUDIO_OUT_L",
nc: false
},
{
id: "12",
selector: "pin12",
label: "Pin_12",
net: "GND",
nc: false
}
],
footprint: [
{
type: "pcb_plated_hole",
shape: "circular_hole_with_rect_pad",
x: 0,
y: 0,
port_hints: [
"pin1"
],
hole_shape: "circle",
pad_shape: "rect",
hole_diameter: 1,
rect_ccw_rotation: 180,
rect_pad_width: 1.7,
rect_pad_height: 1.7,
hole_offset_x: 0,
hole_offset_y: 0,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -2.5400000000000063,
port_hints: [
"pin2"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -5.079999999999998,
port_hints: [
"pin3"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -7.6200000000000045,
port_hints: [
"pin4"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -10.159999999999997,
port_hints: [
"pin5"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -12.700000000000003,
port_hints: [
"pin6"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -15.239999999999995,
port_hints: [
"pin7"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -17.78,
port_hints: [
"pin8"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -20.319999999999993,
port_hints: [
"pin9"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -22.860000000000014,
port_hints: [
"pin10"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -25.400000000000006,
port_hints: [
"pin11"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_plated_hole",
shape: "pill",
x: 0,
y: -27.939999999999998,
port_hints: [
"pin12"
],
hole_width: 1,
hole_height: 1,
outer_width: 1.7,
outer_height: 1.7,
ccw_rotation: 180,
layers: [
"top",
"inner1",
"inner2",
"bottom"
]
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1.3299999999999983,
y: -1.269999999999996
},
{
x: -1.3299999999999983,
y: -29.27000000000001
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: 1.3299999999999983
},
{
x: 0,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: 0
},
{
x: 1.3299999999999983,
y: 1.3299999999999983
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: -1.269999999999996
},
{
x: -1.3299999999999983,
y: -1.269999999999996
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: -1.269999999999996
},
{
x: 1.3299999999999983,
y: -29.27000000000001
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1.3299999999999983,
y: -29.27000000000001
},
{
x: -1.3299999999999983,
y: -29.27000000000001
}
],
stroke_width: 0.12
}
],
section: "Connectors",
schX: 15,
schY: -267,
schRotation: 0,
schWidth: 2.245
},
{
name: "JP1",
value: "QSPI2_NCS_Select",
ftype: "simple_chip",
x: -10.599999999999994,
y: 1,
layer: "bottom",
pins: [
{
id: "1",
selector: "pin1",
label: "A",
net: "QSPI_BK2_NCS",
nc: false
},
{
id: "2",
selector: "pin2",
label: "C",
net: "Net_JP1_Pad2",
nc: false
},
{
id: "3",
selector: "pin3",
label: "B",
net: "OCTOSPIM_P2_NCS",
nc: false
}
],
footprint: [
{
type: "pcb_smtpad",
x: 0,
y: 0,
width: 1.5,
height: 1,
layer: "bottom",
port_hints: [
"pin2"
],
shape: "rect"
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1.5,
y: -1.5
},
{
x: -1.5,
y: -0.9000000000000057
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1.2000000000000028,
y: -1.2000000000000028
},
{
x: -1.5,
y: -0.9000000000000057
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1.2000000000000028,
y: -1.2000000000000028
},
{
x: -1.5,
y: -1.5
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1,
y: 1.4000000000000057
},
{
x: -1,
y: -1.4000000000000057
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -0.29999999999999716,
y: -2.049999999999997
},
{
x: 0.29999999999999716,
y: -2.049999999999997
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 0.29999999999999716,
y: 2.049999999999997
},
{
x: -0.29999999999999716,
y: 2.049999999999997
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1,
y: -1.4000000000000057
},
{
x: 1,
y: 1.4000000000000057
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -1,
y: 1.3499999999999943
},
{
x: -0.9928751187626403,
y: 1.4496204281356455
},
{
x: -0.9716452715133386,
y: 1.547212882866262
},
{
x: -0.9367426380769075,
y: 1.6407906570104416
},
{
x: -0.8888777376496506,
y: 1.7284487709626717
},
{
x: -0.8290249646319978,
y: 1.8084027527063853
},
{
x: -0.7584027527062602,
y: 1.879024964632194
},
{
x: -0.6784487709625893,
y: 1.9388777376499036
},
{
x: -0.5907906570103876,
y: 1.9867426380772315
},
{
x: -0.4972128828662363,
y: 2.0216452715137194
},
{
x: -0.39962042813563414,
y: 2.0428751187631065
},
{
x: -0.29999999999999716,
y: 2.050000000000537
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: -0.29999999999999716,
y: -2.049999999999997
},
{
x: -0.3996204281357052,
y: -2.0428751187625522
},
{
x: -0.49721288286637844,
y: -2.0216452715131936
},
{
x: -0.590790657010615,
y: -1.9867426380767483
},
{
x: -0.6784487709629445,
y: -1.9388777376495057
},
{
x: -0.7584027527067718,
y: -1.8790249646318813
},
{
x: -0.8290249646326942,
y: -1.8084027527061863
},
{
x: -0.8888777376505885,
y: -1.7284487709625722
},
{
x: -0.9367426380781296,
y: -1.640790657010399
},
{
x: -0.9716452715149018,
y: -1.5472128828662761
},
{
x: -0.9928751187645872,
y: -1.449620428135674
},
{
x: -1.000000000002359,
y: -1.3499999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 0.29999999999999716,
y: 2.049999999999997
},
{
x: 0.3996204281353073,
y: 2.042875118762012
},
{
x: 0.4972128828655258,
y: 2.0216452715122273
},
{
x: 0.5907906570092649,
y: 1.9867426380754836
},
{
x: 0.6784487709610971,
y: 1.9388777376480562
},
{
x: 0.758402752704427,
y: 1.8790249646303891
},
{
x: 0.829024964629923,
y: 1.8084027527047652
},
{
x: 0.8888777376474195,
y: 1.7284487709613074
},
{
x: 0.9367426380746764,
y: 1.64079065700939
},
{
x: 0.9716452715112354,
y: 1.5472128828655798
},
{
x: 0.9928751187608214,
y: 1.4496204281353187
},
{
x: 0.9999999999986073,
y: 1.3499999999999943
}
],
stroke_width: 0.12
},
{
type: "pcb_silkscreen_path",
layer: "bottom",
route: [
{
x: 1,
y: -1.3499999999999943
},
{
x: 0.9928751187623703,
y: -1.4496204281355745
},
{
x: 0.9716452715128696,
y: -1.5472128828660914
},
{
x: 0.9367426380763106,
y: -1.6407906570101574
},
{
x: 0.8888777376489969,
y: -1.7284487709623164
},
{
x: 0.8290249646313725,
y: -1.8084027527059732
},
{
x: 0.7584027527056918,
y: -1.8790249646317534
},
{
x: 0.6784487709621345,
y: -1.9388777376495199
},
{
x: 0.5907906570100607,
y: -1.9867426380769757
},
{
x: 0.4972128828660374,
y: -2.0216452715136626
},
{
x: 0.3996204281355631,
y: -2.042875118763334
},
{
x: 0.29999999999999716,
y: -2.05000000000112
}
],
stroke_width: 0.12
},
{
type: "pcb_smtpad",
shape: "polygon",
layer: "bottom",
port_hints: [
"pin1"
],
points: [
{
x: -0.75,
y: -1.2999999999999972
},
{
x: -0.7493977281025862,
y: -1.324533837163706
},
{
x: -0.7475923633360984,
y: -1.3490085701647774
},
{
x: -0.7445882549823906,
y: -1.373365237227678
},
{
x: -0.7403926402016152,
y: -1.3975451610080614
},
{
x: -0.735015626597272,
y: -1.4214900899516292
},
{
x: -0.7284701678661044,
y: -1.4451423386272282
},
{
x: -0.7207720325915103,
y: -1.4684449266961073
},
{
x: -0.7119397662556434,
y: -1.491341716182542
},
{
x: -0.7019946465617217,
y: -1.513777546715138
},
{
x: -0.6909606321741775,
y: -1.535698368412996
},
{
x: -0.678864305000136,
y: -1.557051372096608
},
{
x: -0.6657348061512727,
y: -1.5777851165097982
},
{
x: -0.6516037657403224,
y: -1.5978496522462138
},
{
x: -0.6365052266813684,
y: -1.6171966420818198
},
{
x: -0.6204755626774796,
y: -1.6357794774235064
},
{
x: -0.6035533905932737,
y: -1.6535533905932709
},
{
x: -0.5857794774235092,
y: -1.6704755626774765
},
{
x: -0.567196642081823,
y: -1.6865052266813656
},
{
x: -0.5478496522462166,
y: -1.7016037657403196
},
{
x: -0.527785116509801,
y: -1.7157348061512698
},
{
x: -0.5070513720966108,
y: -1.728864305000133
},
{
x: -0.48569836841299896,
y: -1.7409606321741746
},
{
x: -0.46377754671514126,
y: -1.7519946465617187
},
{
x: -0.44134171618254514,
y: -1.7619397662556404
},
{
x: -0.41844492669611,
y: -1.7707720325915075
},
{
x: -0.39514233862723125,
y: -1.7784701678661015
},
{
x: -0.3714900899516321,
y: -1.7850156265972692
},
{
x: -0.3475451610080643,
y: -1.7903926402016124
},
{
x: -0.3233652372276812,
y: -1.7945882549823877
},
{
x: -0.2990085701647802,
y: -1.7975923633360957
},
{
x: -0.274533837163709,
y: -1.7993977281025835
},
{
x: -0.2500000000000001,
y: -1.7999999999999972
},
{
x: -0.22546616283629117,
y: -1.7993977281025835
},
{
x: -0.20099142983521995,
y: -1.7975923633360957
},
{
x: -0.17663476277231904,
y: -1.7945882549823877
},
{
x: -0.15245483899193585,
y: -1.7903926402016124
},
{
x: -0.12850991004836812,
y: -1.7850156265972692
},
{
x: -0.10485766137276897,
y: -1.7784701678661015
},
{
x: -0.0815550733038902,
y: -1.7707720325915075
},
{
x: -0.058658283817455,
y: -1.7619397662556404
},
{
x: -0.03622245328485893,
y: -1.7519946465617187
},
{
x: -0.014301631587001207,
y: -1.7409606321741746
},
{
x: 0,
y: -1.7328588579525113
},
{
x: 0.014301631587001068,
y: -1.7409606321741746
},
{
x: 0.03622245328485876,
y: -1.7519946465617187
},
{
x: 0.05865828381745483,
y: -1.7619397662556404
},
{
x: 0.08155507330389003,
y: -1.7707720325915075
},
{
x: 0.10485766137276878,
y: -1.7784701678661015
},
{
x: 0.12850991004836793,
y: -1.7850156265972692
},
{
x: 0.15245483899193568,
y: -1.7903926402016124
},
{
x: 0.17663476277231885,
y: -1.7945882549823877
},
{
x: 0.20099142983521978,
y: -1.7975923633360957
},
{
x: 0.225466162836291,
y: -1.7993977281025835
},
{
x: 0.24999999999999992,
y: -1.7999999999999972
},
{
x: 0.2745338371637088,
y: -1.7993977281025835
},
{
x: 0.29900857016478005,
y: -1.7975923633360957
},
{
x: 0.32336523722768096,
y: -1.7945882549823877
},
{
x: 0.34754516100806415,
y: -1.7903926402016124
},
{
x: 0.3714900899516319,
y: -1.7850156265972692
},
{
x: 0.395142338627231,
y: -1.7784701678661015
},
{
x: 0.4184449266961098,
y: -1.7707720325915075
},
{
x: 0.44134171618254503,
y: -1.7619397662556404
},
{
x: 0.4637775467151411,
y: -1.7519946465617187
},
{
x: 0.4856983684129988,
y: -1.7409606321741746
},
{
x: 0.5070513720966108,
y: -1.728864305000133
},
{
x: 0.5277851165098009,
y: -1.7157348061512698
},
{
x: 0.5478496522462164,
y: -1.7016037657403196
},
{
x: 0.5671966420818227,
y: -1.6865052266813656
},
{
x: 0.5857794774235092,
y: -1.6704755626774765
},
{
x: 0.6035533905932737,
y: -1.6535533905932709
},
{
x: 0.6204755626774794,
y: -1.6357794774235064
},
{
x: 0.6365052266813682,
y: -1.6171966420818198
},
{
x: 0.6516037657403224,
y: -1.5978496522462138
},
{
x: 0.6657348061512727,
y: -1.5777851165097982
},
{
x: 0.6788643050001361,
y: -1.557051372096608
},
{
x: 0.6909606321741775,
y: -1.535698368412996
},
{
x: 0.7019946465617215,
y: -1.5137775467151384
},
{
x: 0.7119397662556434,
y: -1.4913417161825424
},
{
x: 0.7207720325915103,
y: -1.4684449266961073
},
{
x: 0.7284701678661044,
y: -1.4451423386272282
},
{
x: 0.735015626597272,
y: -1.4214900899516292
},
{
x: 0.7403926402016152,
y: -1.3975451610080614
},
{
x: 0.7445882549823906,
y: -1.3733652372276783
},
{
x: 0.7475923633360985,
y: -1.3490085701647774
},
{
x: 0.7493977281025862,
y: -1.324533837163706
},
{
x: 0.75,
y: -1.2999999999999972
},
{
x: 0.75,
y: -0.75
},
{
x: -0.75,
y: -0.75
},
{
x: -0.75,
y: -1.2999999999999972
}
]
},
{
type: "pcb_smtpad",
shape: "polygon",
layer: "bottom",
port_hints: [
"pin3"
],
points: [
{
x: -0.75,
y: 0.75
},
{
x: 0.75,
y: 0.75
},
{
x: 0.75,
y: 1.2999999999999972
},
{
x: 0.7493977281025862,
y: 1.324533837163706
},
{
x: 0.7475923633360985,
y: 1.3490085701647774
},
{
x: 0.7445882549823906,
y: 1.3733652372276781
},
{
x: 0.7403926402016152,
y: 1.3975451610080614
},
{
x: 0.735015626597272,
y: 1.4214900899516292
},
{
x: 0.7284701678661044,
y: 1.4451423386272284
},
{
x: 0.7207720325915103,
y: 1.4684449266961073
},
{
x: 0.7119397662556434,
y: 1.491341716182542
},
{
x: 0.7019946465617217,
y: 1.5137775467151382
},
{
x: 0.6909606321741775,
y: 1.535698368412996
},
{
x: 0.6788643050001361,
y: 1.557051372096608
},
{
x: 0.6657348061512727,
y: 1.5777851165097982
},
{
x: 0.6516037657403224,
y: 1.5978496522462138
},
{
x: 0.6365052266813684,
y: 1.61719664208182
},
{
x: 0.6204755626774796,
y: 1.6357794774235064
},
{
x: 0.6035533905932737,
y: 1.6535533905932709
},
{
x: 0.5857794774235092,
y: 1.6704755626774768
},
{
x: 0.5671966420818227,
y: 1.6865052266813656
},
{
x: 0.5478496522462167,
y: 1.7016037657403196
},
{
x: 0.5277851165098011,
y: 1.7157348061512698
},
{
x: 0.5070513720966108,
y: 1.7288643050001333
},
{
x: 0.4856983684129989,
y: 1.7409606321741746
},
{
x: 0.4637775467151411,
y: 1.7519946465617189
},
{
x: 0.4413417161825449,
y: 1.7619397662556406
},
{
x: 0.41844492669611,
y: 1.7707720325915075
},
{
x: 0.39514233862723114,
y: 1.7784701678661017
},
{
x: 0.371490089951632,
y: 1.7850156265972692
},
{
x: 0.34754516100806415,
y: 1.7903926402016124
},
{
x: 0.32336523722768085,
y: 1.7945882549823877
},
{
x: 0.2990085701647804,
y: 1.7975923633360955
},
{
x: 0.27453383716370905,
y: 1.7993977281025835
},
{
x: 0.25,
y: 1.7999999999999972
},
{
x: 0.225466162836291,
y: 1.7993977281025835
},
{
x: 0.20099142983521967,
y: 1.7975923633360955
},
{
x: 0.17663476277231918,
y: 1.7945882549823877
},
{
x: 0.1524548389919359,
y: 1.7903926402016124
},
{
x: 0.12850991004836806,
y: 1.7850156265972692
},
{
x: 0.10485766137276892,
y: 1.7784701678661017
},
{
x: 0.08155507330389003,
y: 1.7707720325915075
},
{
x: 0.05865828381745514,
y: 1.7619397662556406
},
{
x: 0.03622245328485907,
y: 1.7519946465617189
},
{
x: 0.014301631587001151,
y: 1.7409606321741746
},
{
x: 0,
y: 1.7328588579525113
},
{
x: -0.014301631587001096,
y: 1.7409606321741746
},
{
x: -0.0362224532848589,
y: 1.7519946465617189
},
{
x: -0.05865828381745508,
y: 1.7619397662556406
},
{
x: -0.08155507330388997,
y: 1.7707720325915075
},
{
x: -0.10485766137276883,
y: 1.7784701678661017
},
{
x: -0.128509910048368,
y: 1.7850156265972692
},
{
x: -0.15245483899193585,
y: 1.7903926402016124
},
{
x: -0.17663476277231913,
y: 1.7945882549823877
},
{
x: -0.20099142983521961,
y: 1.7975923633360955
},
{
x: -0.22546616283629095,
y: 1.7993977281025835
},
{
x: -0.24999999999999997,
y: 1.7999999999999972
},
{
x: -0.274533837163709,
y: 1.7993977281025835
},
{
x: -0.29900857016478033,
y: 1.7975923633360955
},
{
x: -0.32336523722768085,
y: 1.7945882549823877
},
{
x: -0.3475451610080641,
y: 1.7903926402016124
},
{
x: -0.3714900899516319,
y: 1.7850156265972692
},
{
x: -0.3951423386272311,
y: 1.7784701678661017
},
{
x: -0.41844492669611,
y: 1.7707720325915075
},
{
x: -0.44134171618254486,
y: 1.7619397662556406
},
{
x: -0.46377754671514093,
y: 1.7519946465617189
},
{
x: -0.48569836841299885,
y: 1.7409606321741746
},
{
x: -0.5070513720966108,
y: 1.7288643050001333
},
{
x: -0.527785116509801,
y: 1.7157348061512698
},
{
x: -0.5478496522462166,
y: 1.7016037657403196
},
{
x: -0.5671966420818226,
y: 1.6865052266813656
},
{
x: -0.5857794774235092,
y: 1.6704755626774768
},
{
x: -0.6035533905932737,
y: 1.6535533905932709
},
{
x: -0.6204755626774794,
y: 1.6357794774235064
},
{
x: -0.6365052266813684,
y: 1.61719664208182
},
{
x: -0.6516037657403224,
y: 1.5978496522462138
},
{
x: -0.6657348061512727,
y: 1.5777851165097982
},
{
x: -0.678864305000136,
y: 1.557051372096608
},
{
x: -0.6909606321741775,
y: 1.535698368412996
},
{
x: -0.7019946465617217,
y: 1.5137775467151382
},
{
x: -0.7119397662556434,
y: 1.491341716182542
},
{
x: -0.7207720325915103,
y: 1.4684449266961073
},
{
x: -0.7284701678661044,
y: 1.4451423386272284
},
{
x: -0.735015626597272,
y: 1.4214900899516292
},
{
x: -0.7403926402016152,
y: 1.3975451610080614
},
{
x: -0.7445882549823906,
y: 1.3733652372276781
},
{
x: -0.7475923633360984,
y: 1.3490085701647774
},
{
x: -0.7493977281025862,
y: 1.324533837163706
},
{
x: -0.75,
y: 1.2999999999999972
},
{
x: -0.75,
y: 0.75
}
]
}
],
section: "QSPI_Flash",
schX: 160,
schY: -130,
schRotation: 0,
schWidth: 1.39
}
];
var data = {
parts: parts};
// Only physical pad/hole/silkscreen primitives. No imported copper routing.
function ExactFootprint({ part }) {
return jsxRuntime.jsx("footprint", { originalLayer: part.layer, children: part.footprint.map((e, i) => {
const p = { pcbX: e.x, pcbY: e.y, layer: e.layer, portHints: e.port_hints };
if (e.type === 'pcb_smtpad')
return jsxRuntime.jsx("smtpad", { ...p, shape: e.shape, width: e.width, height: e.height, radius: e.radius, cornerRadius: e.corner_radius, points: e.points, ccwRotation: e.ccw_rotation }, i);
if (e.type === 'pcb_hole')
return jsxRuntime.jsx("hole", { ...p, diameter: e.hole_diameter }, i);
if (e.type === 'pcb_plated_hole')
return jsxRuntime.jsx("platedhole", { ...p, shape: e.shape === 'rotated_pill_hole_with_rect_pad' ? 'pill_hole_with_rect_pad' : e.shape, pcbRotation: e.ccw_rotation ?? e.rect_ccw_rotation ?? 0, holeDiameter: e.hole_diameter, outerDiameter: e.outer_diameter, holeWidth: e.hole_width, holeHeight: e.hole_height, outerWidth: e.outer_width, outerHeight: e.outer_height, rectPadWidth: e.rect_pad_width, rectPadHeight: e.rect_pad_height, holeOffsetX: e.hole_offset_x, holeOffsetY: e.hole_offset_y }, i);
if (e.type === 'pcb_silkscreen_path')
return jsxRuntime.jsx("silkscreenpath", { layer: e.layer, route: e.route, strokeWidth: e.stroke_width }, i);
if (e.type === 'pcb_silkscreen_circle')
return jsxRuntime.jsx("silkscreencircle", { layer: e.layer, pcbX: e.center.x, pcbY: e.center.y, radius: e.radius, strokeWidth: e.stroke_width }, i);
return null;
}) });
}
// Original hardware: https://github.com/dchwebb/Punck (Hardware_v1_1).
// Native schematic and fresh autorouting. Run build:native for the two validated via repairs.
const footprints = Object.fromEntries(data.parts.map(part => [part.name, part]));
function Punck() {
return jsxRuntime.jsxs("board", { width: 91.2, height: 100, thickness: 1.59, layers: 4, autorouter: { algorithmFn: punckRouter, allowViaInPad: false }, minViaEdgeToPadEdgeClearance: 0.4, minTraceWidth: 0.15, children: [jsxRuntime.jsx("schematicsheet", { name: "Resistors", displayName: "Resistors", sheetIndex: 0 }), jsxRuntime.jsx("schematicsheet", { name: "Power", displayName: "Power", sheetIndex: 1 }), jsxRuntime.jsx("schematicsheet", { name: "Test_Points", displayName: "Test Points", sheetIndex: 2 }), jsxRuntime.jsx("schematicsheet", { name: "Audio", displayName: "Audio", sheetIndex: 3 }), jsxRuntime.jsx("schematicsheet", { name: "Capacitors", displayName: "Capacitors", sheetIndex: 4 }), jsxRuntime.jsx("schematicsheet", { name: "Input_Clamps", displayName: "Input Clamps", sheetIndex: 5 }), jsxRuntime.jsx("schematicsheet", { name: "QSPI_Flash", displayName: "QSPI Flash", sheetIndex: 6 }), jsxRuntime.jsx("schematicsheet", { name: "Connectors", displayName: "Connectors", sheetIndex: 7 }), jsxRuntime.jsx("schematicsheet", { name: "Microcontroller", displayName: "Microcontroller", sheetIndex: 8 }), jsxRuntime.jsx("schematicsheet", { name: "Clock", displayName: "Clock", sheetIndex: 9 }), jsxRuntime.jsx("schematicsection", { name: "section_Passives", displayName: "Passives" }), jsxRuntime.jsx("schematicsection", { name: "section_Power", displayName: "Power" }), jsxRuntime.jsx("schematicsection", { name: "section_Test_Points", displayName: "Test Points" }), jsxRuntime.jsx("schematicsection", { name: "section_Audio", displayName: "Audio" }), jsxRuntime.jsx("schematicsection", { name: "section_Input_Clamps", displayName: "Input Clamps" }), jsxRuntime.jsx("schematicsection", { name: "section_QSPI_Flash", displayName: "QSPI Flash" }), jsxRuntime.jsx("schematicsection", { name: "section_Connectors", displayName: "Connectors" }), jsxRuntime.jsx("schematicsection", { name: "section_Microcontroller", displayName: "Microcontroller" }), jsxRuntime.jsx("schematicsection", { name: "section_Clock", displayName: "Clock" }), jsxRuntime.jsx("net", { name: "SNARE_IN" }), jsxRuntime.jsx("net", { name: "Net_Q5_Pad1" }), jsxRuntime.jsx("net", { name: "HH_LED" }), jsxRuntime.jsx("net", { name: "HH_LED_OUT" }), jsxRuntime.jsx("net", { name: "CH_IN" }), jsxRuntime.jsx("net", { name: "Net_Q3_Pad1" }), jsxRuntime.jsx("net", { name: "Net_C1_Pad1" }), jsxRuntime.jsx("net", { name: "AUDIO_OUT_L" }), jsxRuntime.jsx("net", { name: "net_12V" }), jsxRuntime.jsx("net", { name: "GND" }), jsxRuntime.jsx("net", { name: "P12V" }), jsxRuntime.jsx("net", { name: "P3V3" }), jsxRuntime.jsx("net", { name: "VCC" }), jsxRuntime.jsx("net", { name: "VO" }), jsxRuntime.jsx("net", { name: "CH_CLAMP" }), jsxRuntime.jsx("net", { name: "P3_3VA" }), jsxRuntime.jsx("net", { name: "SAMPLER_A_CLAMP" }), jsxRuntime.jsx("net", { name: "MIDI_IN" }), jsxRuntime.jsx("net", { name: "Net_Q1_Pad1" }), jsxRuntime.jsx("net", { name: "Net_C34_Pad1" }), jsxRuntime.jsx("net", { name: "Net_C34_Pad2" }), jsxRuntime.jsx("net", { name: "Net_C36_Pad1" }), jsxRuntime.jsx("net", { name: "DAC_OUT_L" }), jsxRuntime.jsx("net", { name: "DAC_OUT_R" }), jsxRuntime.jsx("net", { name: "DAC_BCLK" }), jsxRuntime.jsx("net", { name: "DAC_DATA" }), jsxRuntime.jsx("net", { name: "DAC_LRCLK" }), jsxRuntime.jsx("net", { name: "Net_C35_Pad2" }), jsxRuntime.jsx("net", { name: "VSW" }), jsxRuntime.jsx("net", { name: "CB" }), jsxRuntime.jsx("net", { name: "SAMPLER_B_CLAMP" }), jsxRuntime.jsx("net", { name: "Net_Q6_Pad1" }), jsxRuntime.jsx("net", { name: "Net_C24_Pad1" }), jsxRuntime.jsx("net", { name: "Net_C1_Pad2" }), jsxRuntime.jsx("net", { name: "Net_C17_Pad1" }), jsxRuntime.jsx("net", { name: "SA_LED" }), jsxRuntime.jsx("net", { name: "SA_LED_OUT" }), jsxRuntime.jsx("net", { name: "FB" }), jsxRuntime.jsx("net", { name: "Net_R4_Pad1" }), jsxRuntime.jsx("net", { name: "Net_R3_Pad1" }), jsxRuntime.jsx("net", { name: "VEE" }), jsxRuntime.jsx("net", { name: "TEMPO_OUT" }), jsxRuntime.jsx("net", { name: "Net_JP1_Pad2" }), jsxRuntime.jsx("net", { name: "QSPI_BK2_IO1" }), jsxRuntime.jsx("net", { name: "QSPI_BK2_IO2" }), jsxRuntime.jsx("net", { name: "QSPI_BK2_IO0" }), jsxRuntime.jsx("net", { name: "QSPI_CLK" }), jsxRuntime.jsx("net", { name: "QSPI_BK2_IO3" }), jsxRuntime.jsx("net", { name: "MIDI_UART" }), jsxRuntime.jsx("net", { name: "Net_Q4_Pad1" }), jsxRuntime.jsx("net", { name: "KICK_CLAMP" }), jsxRuntime.jsx("net", { name: "SB_LED" }), jsxRuntime.jsx("net", { name: "SB_LED_OUT" }), jsxRuntime.jsx("net", { name: "Net_Q7_Pad1" }), jsxRuntime.jsx("net", { name: "Net_R10_Pad2" }), jsxRuntime.jsx("net", { name: "TEMPO_CLOCK" }), jsxRuntime.jsx("net", { name: "Net_U1_Pad8" }), jsxRuntime.jsx("net", { name: "Net_C20_Pad2" }), jsxRuntime.jsx("net", { name: "Net_C20_Pad1" }), jsxRuntime.jsx("net", { name: "AUDIO_OUT_R" }), jsxRuntime.jsx("net", { name: "DAC2" }), jsxRuntime.jsx("net", { name: "DAC1" }), jsxRuntime.jsx("net", { name: "UART_RX" }), jsxRuntime.jsx("net", { name: "UART_TX" }), jsxRuntime.jsx("net", { name: "Net_Q2_Pad1" }), jsxRuntime.jsx("net", { name: "OH_CLAMP" }), jsxRuntime.jsx("net", { name: "KICK_IN" }), jsxRuntime.jsx("net", { name: "SNARE_CLAMP" }), jsxRuntime.jsx("net", { name: "QSPI_BK1_IO2" }), jsxRuntime.jsx("net", { name: "Net_C23_Pad1" }), jsxRuntime.jsx("net", { name: "Net_C26_Pad1" }), jsxRuntime.jsx("net", { name: "Net_RESET1_Pad1" }), jsxRuntime.jsx("net", { name: "SNARE_FILTER_POT" }), jsxRuntime.jsx("net", { name: "SAMPLER_A_VOICE_POT" }), jsxRuntime.jsx("net", { name: "KICK_ATTACK_POT" }), jsxRuntime.jsx("net", { name: "KICK_DECAY_POT" }), jsxRuntime.jsx("net", { name: "KICK_VOL_POT" }), jsxRuntime.jsx("net", { name: "SNARE_TUNING_POT" }), jsxRuntime.jsx("net", { name: "HIHAT_DECAY_POT" }), jsxRuntime.jsx("net", { name: "SAMPLER_B_VOICE_POT" }), jsxRuntime.jsx("net", { name: "SNARE_VOL_POT" }), jsxRuntime.jsx("net", { name: "SAMPLER_A_SPEED_POT" }), jsxRuntime.jsx("net", { name: "SAMPLER_B_SPEED_POT" }), jsxRuntime.jsx("net", { name: "HIHAT_VOL_POT" }), jsxRuntime.jsx("net", { name: "SAMPLER_A_VOL_POT" }), jsxRuntime.jsx("net", { name: "SAMPLER_B_VOL_POT" }), jsxRuntime.jsx("net", { name: "TEMPO_POT" }), jsxRuntime.jsx("net", { name: "HH_BTN" }), jsxRuntime.jsx("net", { name: "Net_C18_Pad1" }), jsxRuntime.jsx("net", { name: "QSPI_BK1_IO0" }), jsxRuntime.jsx("net", { name: "QSPI_BK1_IO1" }), jsxRuntime.jsx("net", { name: "QSPI_BK1_IO3" }), jsxRuntime.jsx("net", { name: "QSPI_BK1_NCS" }), jsxRuntime.jsx("net", { name: "SEQ_SELECT" }), jsxRuntime.jsx("net", { name: "SN_LED_OUT" }), jsxRuntime.jsx("net", { name: "KI_LED_OUT" }), jsxRuntime.jsx("net", { name: "USB_VBUS" }), jsxRuntime.jsx("net", { name: "USB_DM" }), jsxRuntime.jsx("net", { name: "USB_DP" }), jsxRuntime.jsx("net", { name: "SWIO" }), jsxRuntime.jsx("net", { name: "Net_C19_Pad1" }), jsxRuntime.jsx("net", { name: "SWCLK" }), jsxRuntime.jsx("net", { name: "QSPI_BK2_NCS" }), jsxRuntime.jsx("net", { name: "OCTOSPIM_P2_NCS" }), jsxRuntime.jsx("net", { name: "SB_BTN" }), jsxRuntime.jsx("net", { name: "SN_BTN" }), jsxRuntime.jsx("net", { name: "KI_BTN" }), jsxRuntime.jsx("net", { name: "SA_BTN" }), jsxRuntime.jsx("net", { name: "MIDI_LEARN" }), jsxRuntime.jsx("net", { name: "SAMPLER_A_IN" }), jsxRuntime.jsx("net", { name: "SAMPLER_B_IN" }), jsxRuntime.jsx("net", { name: "OH_IN" }), jsxRuntime.jsx("net", { name: "SN_LED" }), jsxRuntime.jsx("net", { name: "KI_LED" }), jsxRuntime.jsx("resistor", { name: "R27", pcbX: 32.599999999999994, pcbY: 11.099999999999994, pcbRotation: 0, layer: "top", schX: 0, schY: 0, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R27"] }) }), jsxRuntime.jsx("resistor", { name: "R22", pcbX: 32.599999999999994, pcbY: -29.80000000000001, pcbRotation: 0, layer: "top", schX: 15, schY: 0, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "560", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R22"] }) }), jsxRuntime.jsx("resistor", { name: "R18", pcbX: 32.599999999999994, pcbY: 19.599999999999994, pcbRotation: 0, layer: "top", schX: 30, schY: 0, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R18"] }) }), jsxRuntime.jsx("resistor", { name: "R8", pcbX: -3.299999999999997, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 45, schY: 0, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "1k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R8"] }) }), jsxRuntime.jsx("chip", { name: "J7", pcbX: -5.099999999999994, pcbY: 42.3375, pcbRotation: 0, layer: "top", schX: 65, schY: 0, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", manufacturerPartNumber: "Eurorack_10_pin_power", pinLabels: { "pin1": ["Pin_1"], "pin2": ["Pin_2"], "pin3": ["Pin_3"], "pin4": ["Pin_4"], "pin5": ["Pin_5"], "pin6": ["Pin_6"], "pin7": ["Pin_7"], "pin8": ["Pin_8"], "pin9": ["Pin_9"], "pin10": ["Pin_10"] }, pinAttributes: {}, schWidth: 2.245, schHeight: 1.2000000000000002, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin6", "pin7", "pin8", "pin9", "pin10"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["J7"] }) }), jsxRuntime.jsx("capacitor", { name: "C3", pcbX: 0.8000000000000114, pcbY: 21.400000000000006, pcbRotation: 0, layer: "top", schX: 80, schY: 0, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C3"] }) }), jsxRuntime.jsx("capacitor", { name: "C40", pcbX: 32.75, pcbY: 43.7, pcbRotation: 0, layer: "top", schX: 65, schY: -18, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "10uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C40"] }) }), jsxRuntime.jsx("chip", { name: "U7", pcbX: -18.19999999999999, pcbY: 41.8, pcbRotation: 0, layer: "top", schX: 110, schY: 0, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", manufacturerPartNumber: "LD1117-3.3-4Tab", pinLabels: { "pin1": ["GND"], "pin2": ["VO"], "pin3": ["VI"], "pin4": ["VO_DUP"] }, pinAttributes: {}, schWidth: 1.675, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3", "pin4"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["U7"] }) }), jsxRuntime.jsx("resistor", { name: "R17", pcbX: 32.599999999999994, pcbY: 21.599999999999994, pcbRotation: 0, layer: "top", schX: 0, schY: -6, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R17"] }) }), jsxRuntime.jsx("resistor", { name: "R28", pcbX: -31.19999999999999, pcbY: -26.299999999999997, pcbRotation: 0, layer: "top", schX: 15, schY: -6, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R28"] }) }), jsxRuntime.jsx("chip", { name: "TP9", pcbX: 30.099999999999994, pcbY: -46.599999999999994, pcbRotation: 0, layer: "top", schX: 130, schY: 0, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP9"] }) }), jsxRuntime.jsx("resistor", { name: "R5", pcbX: 32.599999999999994, pcbY: 23.900000000000006, pcbRotation: 0, layer: "top", schX: 30, schY: -6, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R5"] }) }), jsxRuntime.jsx("chip", { name: "U4", pcbX: 9.700000000000003, pcbY: -36.80000000000001, pcbRotation: 0, layer: "top", schX: 0, schY: -130, schRotation: 0, schSectionName: "section_Audio", schSheetName: "Audio", manufacturerPartNumber: "PCM5100APW", pinLabels: { "pin1": ["CPVDD"], "pin2": ["CAPP"], "pin3": ["CPGND"], "pin4": ["CAPM"], "pin5": ["VNEG"], "pin6": ["OUTL"], "pin7": ["OUTR"], "pin8": ["AVDD"], "pin9": ["AGND"], "pin10": ["DEMP"], "pin11": ["FLT"], "pin12": ["SCK"], "pin13": ["BCK"], "pin14": ["DIN"], "pin15": ["LRCK"], "pin16": ["FMT"], "pin17": ["XSMT"], "pin18": ["LDOO"], "pin19": ["DGND"], "pin20": ["DVDD"] }, pinAttributes: {}, schWidth: 2.055, schHeight: 2.2, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5", "pin6", "pin7", "pin8", "pin9", "pin10"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin11", "pin12", "pin13", "pin14", "pin15", "pin16", "pin17", "pin18", "pin19", "pin20"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["U4"] }) }), jsxRuntime.jsx("capacitor", { name: "C39", pcbX: 30.349999999999994, pcbY: 43.7, pcbRotation: 0, layer: "top", schX: 66.3, schY: -18, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "10uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C39"] }) }), jsxRuntime.jsx("capacitor", { name: "C38", pcbX: 24.150000000000006, pcbY: 40.3, pcbRotation: 0, layer: "top", schX: 80, schY: -6.5, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C38"] }) }), jsxRuntime.jsx("resistor", { name: "R30", pcbX: -31.19999999999999, pcbY: -30.5, pcbRotation: 0, layer: "top", schX: 45, schY: -6, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R30"] }) }), jsxRuntime.jsx("capacitor", { name: "C34", pcbX: 7.1000000000000085, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 0, schY: -12, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "2.2uF", schOrientation: "vertical", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C34"] }) }), jsxRuntime.jsx("capacitor", { name: "C10", pcbX: 10, pcbY: -6.799999999999997, pcbRotation: 0, layer: "top", schX: 15, schY: -12, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C10"] }) }), jsxRuntime.jsx("chip", { name: "Q6", pcbX: -27.21374999999999, pcbY: -25.299999999999997, pcbRotation: 0, layer: "top", schX: 65, schY: -130, schRotation: 0, schSectionName: "section_Input_Clamps", schSheetName: "Input_Clamps", manufacturerPartNumber: "MMBT3904", pinLabels: { "pin1": ["B"], "pin2": ["E"], "pin3": ["C"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Q6"] }) }), jsxRuntime.jsx("capacitor", { name: "C24", pcbX: -6.299999999999997, pcbY: -30.400000000000006, pcbRotation: 180, layer: "top", schX: 30, schY: -12, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "2.2n", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C24"] }) }), jsxRuntime.jsx("chip", { name: "TP3", pcbX: -6.199999999999989, pcbY: -21.599999999999994, pcbRotation: 0, layer: "top", schX: 145, schY: 0, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP3"] }) }), jsxRuntime.jsx("resistor", { name: "R7", pcbX: -8.699999999999989, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 45, schY: -12, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "15k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R7"] }) }), jsxRuntime.jsx("chip", { name: "FID1", pcbX: 40.400000000000006, pcbY: -47.400000000000006, pcbRotation: 0, layer: "top", schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", manufacturerPartNumber: "4_Layer_Marker", pinLabels: {}, pinAttributes: {}, schWidth: 4, schHeight: 0.2, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": [] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["FID1"] }) }), jsxRuntime.jsx("capacitor", { name: "C25", pcbX: -10.5, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 67.6, schY: -18, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "2.2uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C25"] }) }), jsxRuntime.jsx("resistor", { name: "R24", pcbX: 32.599999999999994, pcbY: 30.200000000000003, pcbRotation: 0, layer: "top", schX: 15, schY: -18, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "560", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R24"] }) }), jsxRuntime.jsx("capacitor", { name: "C32", pcbX: 4.700000000000003, pcbY: -30.400000000000006, pcbRotation: 0, layer: "top", schX: 30, schY: -18, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "10uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C32"] }) }), jsxRuntime.jsx("resistor", { name: "R32", pcbX: 19.55000000000001, pcbY: 44.3, pcbRotation: 0, layer: "top", schX: 45, schY: -18, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "33k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R32"] }) }), jsxRuntime.jsx("resistor", { name: "R4", pcbX: -14.099999999999994, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 0, schY: -24, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "10k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R4"] }) }), jsxRuntime.jsx("chip", { name: "TP8", pcbX: -30.799999999999997, pcbY: 33, pcbRotation: 0, layer: "top", schX: 160, schY: 0, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP8"] }) }), jsxRuntime.jsx("capacitor", { name: "C33", pcbX: -28, pcbY: 7.200000000000003, pcbRotation: 0, layer: "top", schX: 15, schY: -24, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C33"] }) }), jsxRuntime.jsx("capacitor", { name: "C30", pcbX: 15.300000000000011, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 65, schY: -24, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "10uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C30"] }) }), jsxRuntime.jsx("resistor", { name: "R9", pcbX: -15.899999999999991, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 45, schY: -24, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "1k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R9"] }) }), jsxRuntime.jsx("capacitor", { name: "C4", pcbX: -4.599999999999994, pcbY: 21.400000000000006, pcbRotation: 0, layer: "top", schX: 95, schY: -6.5, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C4"] }) }), jsxRuntime.jsx("capacitor", { name: "C31", pcbX: 6.700000000000003, pcbY: -30.400000000000006, pcbRotation: 0, layer: "top", schX: 0, schY: -30, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C31"] }) }), jsxRuntime.jsx("capacitor", { name: "C36", pcbX: 9.100000000000009, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 15, schY: -30, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "2.2uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C36"] }) }), jsxRuntime.jsx("chip", { name: "U5", pcbX: -22.099999999999994, pcbY: 7.200000000000003, pcbRotation: 0, layer: "top", schX: 130, schY: -130, schRotation: 0, schSectionName: "section_QSPI_Flash", schSheetName: "QSPI_Flash", manufacturerPartNumber: "W25Q128JVS", pinLabels: { "pin1": ["__CS_"], "pin2": ["DO_IO1_"], "pin3": ["IO2"], "pin4": ["GND"], "pin5": ["DI_IO0_"], "pin6": ["CLK"], "pin7": ["IO3"], "pin8": ["VCC"] }, pinAttributes: {}, schWidth: 2.53, schHeight: 1, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin5", "pin6", "pin7", "pin8"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["U5"] }) }), jsxRuntime.jsx("chip", { name: "Q1", pcbX: 28.5625, pcbY: 24.900000000000006, pcbRotation: 0, layer: "top", schX: 80, schY: -130, schRotation: 0, schSectionName: "section_Input_Clamps", schSheetName: "Input_Clamps", manufacturerPartNumber: "MMBT3904", pinLabels: { "pin1": ["B"], "pin2": ["E"], "pin3": ["C"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Q1"] }) }), jsxRuntime.jsx("chip", { name: "Q4", pcbX: 28.599999999999994, pcbY: 7.900000000000006, pcbRotation: 0, layer: "top", schX: 95, schY: -130, schRotation: 0, schSectionName: "section_Input_Clamps", schSheetName: "Input_Clamps", manufacturerPartNumber: "MMBT3904", pinLabels: { "pin1": ["B"], "pin2": ["E"], "pin3": ["C"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Q4"] }) }), jsxRuntime.jsx("chip", { name: "TP7", pcbX: -22.19999999999999, pcbY: 33, pcbRotation: 0, layer: "top", schX: 175, schY: 0, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP7"] }) }), jsxRuntime.jsx("resistor", { name: "R25", pcbX: 32.599999999999994, pcbY: 28.200000000000003, pcbRotation: 0, layer: "top", schX: 30, schY: -30, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "560", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R25"] }) }), jsxRuntime.jsx("resistor", { name: "R33", pcbX: 21.55000000000001, pcbY: 44.3, pcbRotation: 0, layer: "top", schX: 45, schY: -30, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "10k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R33"] }) }), jsxRuntime.jsx("chip", { name: "L1", pcbX: 35.30000000000001, pcbY: 41.7, pcbRotation: 0, layer: "top", schX: 110, schY: -6.5, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", manufacturerPartNumber: "3.3uH", pinLabels: { "pin1": ["1"], "pin2": ["2"] }, pinAttributes: {}, schWidth: 4, schHeight: 1, schPinArrangement: { "topSide": { "direction": "left-to-right", "pins": ["pin1"] }, "bottomSide": { "direction": "left-to-right", "pins": ["pin2"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["L1"] }) }), jsxRuntime.jsx("chip", { name: "Q7", pcbX: -27.21374999999999, pcbY: -29.5, pcbRotation: 0, layer: "top", schX: 110, schY: -130, schRotation: 0, schSectionName: "section_Input_Clamps", schSheetName: "Input_Clamps", manufacturerPartNumber: "MMBT3904", pinLabels: { "pin1": ["B"], "pin2": ["E"], "pin3": ["C"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Q7"] }) }), jsxRuntime.jsx("resistor", { name: "R10", pcbX: 14.400000000000006, pcbY: 13.400000000000006, pcbRotation: 0, layer: "top", schX: 0, schY: -36, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "100k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R10"] }) }), jsxRuntime.jsx("chip", { name: "U1", pcbX: -10.5, pcbY: -36.80000000000001, pcbRotation: 0, layer: "top", schX: 15, schY: -130, schRotation: 0, schSectionName: "section_Audio", schSheetName: "Audio", manufacturerPartNumber: "TL074", pinLabels: { "pin1": ["1"], "pin2": ["_MINUS"], "pin3": ["_PLUS"], "pin4": ["V_PLUS"], "pin5": ["_PLUS"], "pin6": ["_MINUS"], "pin7": ["7"], "pin8": ["8"], "pin9": ["_MINUS"], "pin10": ["_PLUS"], "pin11": ["V_MINUS"], "pin12": ["_PLUS"], "pin13": ["_MINUS"], "pin14": ["14"] }, pinAttributes: {}, schWidth: 2.435, schHeight: 1.6, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5", "pin6", "pin7"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin8", "pin9", "pin10", "pin11", "pin12", "pin13", "pin14"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["U1"] }) }), jsxRuntime.jsx("resistor", { name: "R16", pcbX: -14.299999999999997, pcbY: -30.400000000000006, pcbRotation: 180, layer: "top", schX: 15, schY: -36, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "1k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R16"] }) }), jsxRuntime.jsx("capacitor", { name: "C11", pcbX: 14.400000000000006, pcbY: 4.400000000000006, pcbRotation: 0, layer: "top", schX: 30, schY: -36, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C11"] }) }), jsxRuntime.jsx("resistor", { name: "R13", pcbX: -10.299999999999997, pcbY: -30.400000000000006, pcbRotation: 0, layer: "top", schX: 45, schY: -36, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "47k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R13"] }) }), jsxRuntime.jsx("chip", { name: "J5", pcbX: 14.599999999999994, pcbY: 28.200000000000003, pcbRotation: 0, layer: "top", schX: 0, schY: -260, schRotation: 0, schSectionName: "section_Connectors", schSheetName: "Connectors", manufacturerPartNumber: "Debug_Header", pinLabels: { "pin1": ["Pin_1"], "pin2": ["Pin_2"], "pin3": ["Pin_3"], "pin4": ["Pin_4"] }, pinAttributes: {}, schWidth: 2.15, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3", "pin4"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["J5"] }) }), jsxRuntime.jsx("chip", { name: "Q2", pcbX: 28.599999999999994, pcbY: 16.400000000000006, pcbRotation: 0, layer: "top", schX: 65, schY: -136, schRotation: 0, schSectionName: "section_Input_Clamps", schSheetName: "Input_Clamps", manufacturerPartNumber: "MMBT3904", pinLabels: { "pin1": ["B"], "pin2": ["E"], "pin3": ["C"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Q2"] }) }), jsxRuntime.jsx("resistor", { name: "R23", pcbX: 32.599999999999994, pcbY: 6.900000000000006, pcbRotation: 0, layer: "top", schX: 0, schY: -42, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R23"] }) }), jsxRuntime.jsx("capacitor", { name: "C6", pcbX: -13.899999999999991, pcbY: 9.400000000000006, pcbRotation: 0, layer: "top", schX: 15, schY: -42, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C6"] }) }), jsxRuntime.jsx("capacitor", { name: "C28", pcbX: 5.1000000000000085, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 66.3, schY: -24, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C28"] }) }), jsxRuntime.jsx("capacitor", { name: "C13", pcbX: 14.400000000000006, pcbY: 16.599999999999994, pcbRotation: 0, layer: "top", schX: 45, schY: -42, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C13"] }) }), jsxRuntime.jsx("chip", { name: "Q5", pcbX: 28.599999999999994, pcbY: 12.099999999999994, pcbRotation: 0, layer: "top", schX: 80, schY: -136, schRotation: 0, schSectionName: "section_Input_Clamps", schSheetName: "Input_Clamps", manufacturerPartNumber: "MMBT3904", pinLabels: { "pin1": ["B"], "pin2": ["E"], "pin3": ["C"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Q5"] }) }), jsxRuntime.jsx("resistor", { name: "R3", pcbX: -12.299999999999997, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 0, schY: -48, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "15k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R3"] }) }), jsxRuntime.jsx("capacitor", { name: "C14", pcbX: 2, pcbY: -6.799999999999997, pcbRotation: 0, layer: "top", schX: 15, schY: -48, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C14"] }) }), jsxRuntime.jsx("chip", { name: "U2", pcbX: 0, pcbY: 7.200000000000003, pcbRotation: 0, layer: "top", schX: 65, schY: -260, schRotation: 0, schSectionName: "section_Microcontroller", schSheetName: "Microcontroller", manufacturerPartNumber: "STM32H743ZITx", pinLabels: { "pin1": ["PE2"], "pin2": ["PE3"], "pin3": ["PE4"], "pin4": ["PE5"], "pin5": ["PE6"], "pin6": ["VBAT"], "pin7": ["PC13"], "pin8": ["PC14"], "pin9": ["PC15"], "pin10": ["PF0"], "pin11": ["PF1"], "pin12": ["PF2"], "pin13": ["PF3"], "pin14": ["PF4"], "pin15": ["PF5"], "pin16": ["VSS"], "pin17": ["VDD"], "pin18": ["PF6"], "pin19": ["PF7"], "pin20": ["PF8"], "pin21": ["PF9"], "pin22": ["PF10"], "pin23": ["PH0"], "pin24": ["PH1"], "pin25": ["NRST"], "pin26": ["PC0"], "pin27": ["PC1"], "pin28": ["PC2_C"], "pin29": ["PC3_C"], "pin30": ["VDD"], "pin31": ["VSSA"], "pin32": ["VREF_PLUS"], "pin33": ["VDDA"], "pin34": ["PA0"], "pin35": ["PA1"], "pin36": ["PA2"], "pin37": ["PA3"], "pin38": ["VSS"], "pin39": ["VDD"], "pin40": ["PA4"], "pin41": ["PA5"], "pin42": ["PA6"], "pin43": ["PA7"], "pin44": ["PC4"], "pin45": ["PC5"], "pin46": ["PB0"], "pin47": ["PB1"], "pin48": ["PB2"], "pin49": ["PF11"], "pin50": ["PF12"], "pin51": ["VSS"], "pin52": ["VDD"], "pin53": ["PF13"], "pin54": ["PF14"], "pin55": ["PF15"], "pin56": ["PG0"], "pin57": ["PG1"], "pin58": ["PE7"], "pin59": ["PE8"], "pin60": ["PE9"], "pin61": ["VSS"], "pin62": ["VDD"], "pin63": ["PE10"], "pin64": ["PE11"], "pin65": ["PE12"], "pin66": ["PE13"], "pin67": ["PE14"], "pin68": ["PE15"], "pin69": ["PB10"], "pin70": ["PB11"], "pin71": ["VCAP1"], "pin72": ["VDD"], "pin73": ["PB12"], "pin74": ["PB13"], "pin75": ["PB14"], "pin76": ["PB15"], "pin77": ["PD8"], "pin78": ["PD9"], "pin79": ["PD10"], "pin80": ["PD11"], "pin81": ["PD12"], "pin82": ["PD13"], "pin83": ["VSS"], "pin84": ["VDD"], "pin85": ["PD14"], "pin86": ["PD15"], "pin87": ["PG2"], "pin88": ["PG3"], "pin89": ["PG4"], "pin90": ["PG5"], "pin91": ["PG6"], "pin92": ["PG7"], "pin93": ["PG8"], "pin94": ["VSS"], "pin95": ["VDD33_USB"], "pin96": ["PC6"], "pin97": ["PC7"], "pin98": ["PC8"], "pin99": ["PC9"], "pin100": ["PA8"], "pin101": ["PA9"], "pin102": ["PA10"], "pin103": ["PA11"], "pin104": ["PA12"], "pin105": ["PA13"], "pin106": ["VCAP2"], "pin107": ["VSS"], "pin108": ["VDD"], "pin109": ["PA14"], "pin110": ["PA15"], "pin111": ["PC10"], "pin112": ["PC11"], "pin113": ["PC12"], "pin114": ["PD0"], "pin115": ["PD1"], "pin116": ["PD2"], "pin117": ["PD3"], "pin118": ["PD4"], "pin119": ["PD5"], "pin120": ["VSS"], "pin121": ["VDD"], "pin122": ["PD6"], "pin123": ["PD7"], "pin124": ["PG9"], "pin125": ["PG10"], "pin126": ["PG11"], "pin127": ["PG12"], "pin128": ["PG13"], "pin129": ["PG14"], "pin130": ["VSS"], "pin131": ["VDD"], "pin132": ["PG15"], "pin133": ["PB3"], "pin134": ["PB4"], "pin135": ["PB5"], "pin136": ["PB6"], "pin137": ["PB7"], "pin138": ["BOOT0"], "pin139": ["PB8"], "pin140": ["PB9"], "pin141": ["PE0"], "pin142": ["PE1"], "pin143": ["PDR_ON"], "pin144": ["VDD"] }, pinAttributes: { "pin2": { "doNotConnect": true }, "pin3": { "doNotConnect": true }, "pin4": { "doNotConnect": true }, "pin5": { "doNotConnect": true }, "pin7": { "doNotConnect": true }, "pin8": { "doNotConnect": true }, "pin9": { "doNotConnect": true }, "pin10": { "doNotConnect": true }, "pin11": { "doNotConnect": true }, "pin12": { "doNotConnect": true }, "pin13": { "doNotConnect": true }, "pin14": { "doNotConnect": true }, "pin15": { "doNotConnect": true }, "pin20": { "doNotConnect": true }, "pin21": { "doNotConnect": true }, "pin22": { "doNotConnect": true }, "pin28": { "doNotConnect": true }, "pin29": { "doNotConnect": true }, "pin54": { "doNotConnect": true }, "pin55": { "doNotConnect": true }, "pin56": { "doNotConnect": true }, "pin57": { "doNotConnect": true }, "pin65": { "doNotConnect": true }, "pin66": { "doNotConnect": true }, "pin69": { "doNotConnect": true }, "pin70": { "doNotConnect": true }, "pin75": { "doNotConnect": true }, "pin77": { "doNotConnect": true }, "pin79": { "doNotConnect": true }, "pin87": { "doNotConnect": true }, "pin88": { "doNotConnect": true }, "pin89": { "doNotConnect": true }, "pin90": { "doNotConnect": true }, "pin92": { "doNotConnect": true }, "pin93": { "doNotConnect": true }, "pin100": { "doNotConnect": true }, "pin102": { "doNotConnect": true }, "pin110": { "doNotConnect": true }, "pin111": { "doNotConnect": true }, "pin113": { "doNotConnect": true }, "pin114": { "doNotConnect": true }, "pin116": { "doNotConnect": true }, "pin118": { "doNotConnect": true }, "pin119": { "doNotConnect": true }, "pin122": { "doNotConnect": true }, "pin124": { "doNotConnect": true }, "pin126": { "doNotConnect": true }, "pin129": { "doNotConnect": true }, "pin132": { "doNotConnect": true }, "pin133": { "doNotConnect": true }, "pin134": { "doNotConnect": true }, "pin139": { "doNotConnect": true }, "pin140": { "doNotConnect": true } }, schWidth: 2.91, schHeight: 14.600000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5", "pin6", "pin7", "pin8", "pin9", "pin10", "pin11", "pin12", "pin13", "pin14", "pin15", "pin16", "pin17", "pin18", "pin19", "pin20", "pin21", "pin22", "pin23", "pin24", "pin25", "pin26", "pin27", "pin28", "pin29", "pin30", "pin31", "pin32", "pin33", "pin34", "pin35", "pin36", "pin37", "pin38", "pin39", "pin40", "pin41", "pin42", "pin43", "pin44", "pin45", "pin46", "pin47", "pin48", "pin49", "pin50", "pin51", "pin52", "pin53", "pin54", "pin55", "pin56", "pin57", "pin58", "pin59", "pin60", "pin61", "pin62", "pin63", "pin64", "pin65", "pin66", "pin67", "pin68", "pin69", "pin70", "pin71", "pin72"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin73", "pin74", "pin75", "pin76", "pin77", "pin78", "pin79", "pin80", "pin81", "pin82", "pin83", "pin84", "pin85", "pin86", "pin87", "pin88", "pin89", "pin90", "pin91", "pin92", "pin93", "pin94", "pin95", "pin96", "pin97", "pin98", "pin99", "pin100", "pin101", "pin102", "pin103", "pin104", "pin105", "pin106", "pin107", "pin108", "pin109", "pin110", "pin111", "pin112", "pin113", "pin114", "pin115", "pin116", "pin117", "pin118", "pin119", "pin120", "pin121", "pin122", "pin123", "pin124", "pin125", "pin126", "pin127", "pin128", "pin129", "pin130", "pin131", "pin132", "pin133", "pin134", "pin135", "pin136", "pin137", "pin138", "pin139", "pin140", "pin141", "pin142", "pin143", "pin144"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["U2"] }) }), jsxRuntime.jsx("chip", { name: "Y1", pcbX: -1.7999999999999972, pcbY: 25.400000000000006, pcbRotation: 0, layer: "top", schX: 128.65, schY: -265.7, schRotation: 0, schSectionName: "section_Clock", schSheetName: "Clock", manufacturerPartNumber: "12MHz 20pF", pinLabels: { "pin1": ["1"], "pin2": ["2"] }, pinAttributes: {}, schWidth: 0.7, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin2"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Y1"] }) }), jsxRuntime.jsx("capacitor", { name: "C20", pcbX: -12.299999999999997, pcbY: -30.400000000000006, pcbRotation: 0, layer: "top", schX: 30, schY: -48, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100pF", schOrientation: "vertical", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C20"] }) }), jsxRuntime.jsx("capacitor", { name: "C16", pcbX: -7.799999999999997, pcbY: 21.400000000000006, pcbRotation: 0, layer: "top", schX: 67.6, schY: -24, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "1uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C16"] }) }), jsxRuntime.jsx("chip", { name: "D1", pcbX: 14.599999999999994, pcbY: 46.2875, pcbRotation: 0, layer: "top", schX: 65, schY: -13, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", manufacturerPartNumber: "1N5819", pinLabels: { "pin1": ["K"], "pin2": ["A"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 1, schPinArrangement: { "topSide": { "direction": "left-to-right", "pins": ["pin1"] }, "bottomSide": { "direction": "left-to-right", "pins": ["pin2"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["D1"] }) }), jsxRuntime.jsx("capacitor", { name: "C5", pcbX: -13.899999999999991, pcbY: 14.900000000000006, pcbRotation: 0, layer: "top", schX: 0, schY: -54, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C5"] }) }), jsxRuntime.jsx("resistor", { name: "R29", pcbX: -31.19999999999999, pcbY: -24.299999999999997, pcbRotation: 0, layer: "top", schX: 15, schY: -54, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R29"] }) }), jsxRuntime.jsx("chip", { name: "TP1", pcbX: -10.199999999999989, pcbY: -21.599999999999994, pcbRotation: 0, layer: "top", schX: 130, schY: -6, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP1"] }) }), jsxRuntime.jsx("resistor", { name: "R6", pcbX: 0.30000000000001137, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 30, schY: -54, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "1k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R6"] }) }), jsxRuntime.jsx("capacitor", { name: "C26", pcbX: -3.5999999999999943, pcbY: 28.400000000000006, pcbRotation: 180, layer: "top", schX: 131.61, schY: -266, schRotation: -90, schSectionName: "section_Clock", schSheetName: "Clock", capacitance: "30pF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C26"] }) }), jsxRuntime.jsx("resistor", { name: "R31", pcbX: -31.19999999999999, pcbY: -28.5, pcbRotation: 0, layer: "top", schX: 0, schY: -60, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R31"] }) }), jsxRuntime.jsx("resistor", { name: "R2", pcbX: -6.8999999999999915, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 15, schY: -60, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "47k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R2"] }) }), jsxRuntime.jsx("capacitor", { name: "C27", pcbX: 0.8000000000000114, pcbY: -18.200000000000003, pcbRotation: 0, layer: "top", schX: 30, schY: -60, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C27"] }) }), jsxRuntime.jsx("chip", { name: "TP6", pcbX: -26.39999999999999, pcbY: 33, pcbRotation: 0, layer: "top", schX: 145, schY: -6, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP6"] }) }), jsxRuntime.jsx("chip", { name: "U3", pcbX: 0.20000000000000284, pcbY: -14, pcbRotation: 0, layer: "top", schX: 145, schY: -130, schRotation: 0, schSectionName: "section_QSPI_Flash", schSheetName: "QSPI_Flash", manufacturerPartNumber: "W25Q128JVS", pinLabels: { "pin1": ["__CS_"], "pin2": ["DO_IO1_"], "pin3": ["IO2"], "pin4": ["GND"], "pin5": ["DI_IO0_"], "pin6": ["CLK"], "pin7": ["IO3"], "pin8": ["VCC"] }, pinAttributes: {}, schWidth: 2.53, schHeight: 1, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin5", "pin6", "pin7", "pin8"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["U3"] }) }), jsxRuntime.jsx("capacitor", { name: "C41", pcbX: -27.599999999999994, pcbY: 39, pcbRotation: 0, layer: "top", schX: 68.9, schY: -24, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "22uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C41"] }) }), jsxRuntime.jsx("chip", { name: "RESET1", pcbX: -15.799999999999997, pcbY: 29.200000000000003, pcbRotation: 0, layer: "top", schX: 45, schY: -60, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", manufacturerPartNumber: "SW_Push", pinLabels: { "pin1": ["1"], "pin2": ["2"], "pin3": ["1_DUP"], "pin4": ["2_DUP"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3", "pin4"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["RESET1"] }) }), jsxRuntime.jsx("resistor", { name: "R26", pcbX: 32.599999999999994, pcbY: 13.099999999999994, pcbRotation: 0, layer: "top", schX: 0, schY: -66, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R26"] }) }), jsxRuntime.jsx("capacitor", { name: "C42", pcbX: 31.700000000000017, pcbY: 40.1, pcbRotation: 0, layer: "top", schX: 95, schY: -13, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "47uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C42"] }) }), jsxRuntime.jsx("chip", { name: "L2", pcbX: -27.599999999999994, pcbY: 46.2, pcbRotation: 0, layer: "top", schX: 110, schY: -13, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", manufacturerPartNumber: "L", pinLabels: { "pin1": ["1"], "pin2": ["2"] }, pinAttributes: {}, schWidth: 4, schHeight: 1, schPinArrangement: { "topSide": { "direction": "left-to-right", "pins": ["pin1"] }, "bottomSide": { "direction": "left-to-right", "pins": ["pin2"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["L2"] }) }), jsxRuntime.jsx("chip", { name: "Q3", pcbX: 28.599999999999994, pcbY: 20.599999999999994, pcbRotation: 0, layer: "top", schX: 95, schY: -136, schRotation: 0, schSectionName: "section_Input_Clamps", schSheetName: "Input_Clamps", manufacturerPartNumber: "MMBT3904", pinLabels: { "pin1": ["B"], "pin2": ["E"], "pin3": ["C"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["Q3"] }) }), jsxRuntime.jsx("resistor", { name: "R12", pcbX: 32.599999999999994, pcbY: 15.400000000000006, pcbRotation: 0, layer: "top", schX: 15, schY: -66, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R12"] }) }), jsxRuntime.jsx("capacitor", { name: "C18", pcbX: -14, pcbY: -1.2000000000000028, pcbRotation: 0, layer: "top", schX: 30, schY: -66, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "2.2uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C18"] }) }), jsxRuntime.jsx("capacitor", { name: "C9", pcbX: -1.7999999999999972, pcbY: -6.799999999999997, pcbRotation: 0, layer: "top", schX: 45, schY: -66, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C9"] }) }), jsxRuntime.jsx("chip", { name: "D2", pcbX: -35.599999999999994, pcbY: 46.2, pcbRotation: 0, layer: "top", schX: 65, schY: -32, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", manufacturerPartNumber: "1N5819", pinLabels: { "pin1": ["K"], "pin2": ["A"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 1, schPinArrangement: { "topSide": { "direction": "left-to-right", "pins": ["pin1"] }, "bottomSide": { "direction": "left-to-right", "pins": ["pin2"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["D2"] }) }), jsxRuntime.jsx("capacitor", { name: "C29", pcbX: 13.099999999999994, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 70.2, schY: -24, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C29"] }) }), jsxRuntime.jsx("resistor", { name: "R20", pcbX: 32.599999999999994, pcbY: 8.900000000000006, pcbRotation: 0, layer: "top", schX: 15, schY: -72, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R20"] }) }), jsxRuntime.jsx("capacitor", { name: "C35", pcbX: 8.5, pcbY: -30.400000000000006, pcbRotation: 0, layer: "top", schX: 30, schY: -72, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C35"] }) }), jsxRuntime.jsx("capacitor", { name: "C7", pcbX: -14, pcbY: 3.9000000000000057, pcbRotation: 0, layer: "top", schX: 45, schY: -72, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C7"] }) }), jsxRuntime.jsx("capacitor", { name: "C2", pcbX: 6.200000000000003, pcbY: 21.400000000000006, pcbRotation: 0, layer: "top", schX: 80, schY: -19.5, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "4.7uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C2"] }) }), jsxRuntime.jsx("capacitor", { name: "C43", pcbX: -35.599999999999994, pcbY: 39, pcbRotation: 0, layer: "top", schX: 95, schY: -19.5, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "22uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C43"] }) }), jsxRuntime.jsx("capacitor", { name: "C12", pcbX: 14.400000000000006, pcbY: 9.400000000000006, pcbRotation: 0, layer: "top", schX: 0, schY: -78, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C12"] }) }), jsxRuntime.jsx("resistor", { name: "R15", pcbX: -8.299999999999997, pcbY: -30.400000000000006, pcbRotation: 0, layer: "top", schX: 15, schY: -78, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "15k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R15"] }) }), jsxRuntime.jsx("chip", { name: "U6", pcbX: 25.950000000000017, pcbY: 43.7, pcbRotation: 0, layer: "top", schX: 110, schY: -19.5, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", manufacturerPartNumber: "TPS561201", pinLabels: { "pin1": ["GND"], "pin2": ["SW"], "pin3": ["VIN"], "pin4": ["VFB"], "pin5": ["EN"], "pin6": ["VBST"] }, pinAttributes: {}, schWidth: 1.865, schHeight: 0.8, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin4", "pin5", "pin6"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["U6"] }) }), jsxRuntime.jsx("capacitor", { name: "C21", pcbX: -11, pcbY: 21.400000000000006, pcbRotation: 0, layer: "top", schX: 71.5, schY: -24, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "1uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C21"] }) }), jsxRuntime.jsx("capacitor", { name: "C17", pcbX: -1.5, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 45, schY: -78, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "2.2n", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C17"] }) }), jsxRuntime.jsx("chip", { name: "TP5", pcbX: 25.200000000000017, pcbY: 33, pcbRotation: 0, layer: "top", schX: 160, schY: -6, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP5"] }) }), jsxRuntime.jsx("chip", { name: "J6", pcbX: 23.900000000000006, pcbY: -6.299999999999997, pcbRotation: 0, layer: "top", schX: 15, schY: -260, schRotation: 0, schSectionName: "section_Connectors", schSheetName: "Connectors", manufacturerPartNumber: "SWD_Header", pinLabels: { "pin1": ["Pin_1"], "pin2": ["Pin_2"], "pin3": ["Pin_3"], "pin4": ["Pin_4"] }, pinAttributes: {}, schWidth: 2.15, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3", "pin4"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["J6"] }) }), jsxRuntime.jsx("capacitor", { name: "C37", pcbX: 14.599999999999994, pcbY: 39, pcbRotation: 0, layer: "top", schX: 68.9, schY: -18, schRotation: -90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "47uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C37"] }) }), jsxRuntime.jsx("capacitor", { name: "C19", pcbX: 8.200000000000003, pcbY: -6.799999999999997, pcbRotation: 0, layer: "top", schX: 0, schY: -84, schRotation: -90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "2.2uF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C19"] }) }), jsxRuntime.jsx("capacitor", { name: "C22", pcbX: -9.399999999999991, pcbY: 21.400000000000006, pcbRotation: 0, layer: "top", schX: 72.8, schY: -24, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C22"] }) }), jsxRuntime.jsx("resistor", { name: "R21", pcbX: 32.599999999999994, pcbY: -27.200000000000003, pcbRotation: 0, layer: "top", schX: 30, schY: -84, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "560", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R21"] }) }), jsxRuntime.jsx("capacitor", { name: "C8", pcbX: -14, pcbY: -3, pcbRotation: 0, layer: "top", schX: 45, schY: -84, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Capacitors", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C8"] }) }), jsxRuntime.jsx("chip", { name: "TP2", pcbX: -2.3999999999999915, pcbY: -21.599999999999994, pcbRotation: 0, layer: "top", schX: 175, schY: -6, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP2"] }) }), jsxRuntime.jsx("capacitor", { name: "C15", pcbX: -6.199999999999989, pcbY: 21.400000000000006, pcbRotation: 0, layer: "top", schX: 74.1, schY: -24, schRotation: 90, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100nF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C15"] }) }), jsxRuntime.jsx("resistor", { name: "R11", pcbX: 32.599999999999994, pcbY: 17.400000000000006, pcbRotation: 0, layer: "top", schX: 15, schY: -90, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R11"] }) }), jsxRuntime.jsx("resistor", { name: "R14", pcbX: 11.100000000000009, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 30, schY: -90, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "1k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R14"] }) }), jsxRuntime.jsx("resistor", { name: "R1", pcbX: 32.599999999999994, pcbY: 25.900000000000006, pcbRotation: 0, layer: "top", schX: 45, schY: -90, schRotation: 90, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "4.7k", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R1"] }) }), jsxRuntime.jsx("capacitor", { name: "C1", pcbX: -5.099999999999994, pcbY: -43.19999999999999, pcbRotation: 0, layer: "top", schX: 80, schY: -26, schRotation: 0, schSectionName: "section_Power", schSheetName: "Power", capacitance: "100pF", schOrientation: "vertical", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C1"] }) }), jsxRuntime.jsx("resistor", { name: "R19", pcbX: 32.599999999999994, pcbY: -24.799999999999997, pcbRotation: 0, layer: "top", schX: 0, schY: -96, schRotation: 0, schSectionName: "section_Passives", schSheetName: "Resistors", resistance: "560", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["R19"] }) }), jsxRuntime.jsx("chip", { name: "TP4", pcbX: 18.400000000000006, pcbY: 33, pcbRotation: 0, layer: "top", schX: 130, schY: -12, schRotation: 0, schSectionName: "section_Test_Points", schSheetName: "Test_Points", manufacturerPartNumber: "TestPoint", pinLabels: { "pin1": ["1"] }, pinAttributes: {}, schWidth: 4, schHeight: 0.4, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1"] }, "rightSide": { "direction": "top-to-bottom", "pins": [] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["TP4"] }) }), jsxRuntime.jsx("capacitor", { name: "C23", pcbX: 0.20000000000000284, pcbY: 28.400000000000006, pcbRotation: 180, layer: "top", schX: 125.69, schY: -266, schRotation: -90, schSectionName: "section_Clock", schSheetName: "Clock", capacitance: "30pF", footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["C23"] }) }), jsxRuntime.jsx("chip", { name: "J3", pcbX: 43.5, pcbY: 44, pcbRotation: 0, layer: "bottom", schX: 30, schY: -260, schRotation: 0, schSectionName: "section_Connectors", schSheetName: "Connectors", manufacturerPartNumber: "Conn_01x12_Female", pinLabels: { "pin1": ["Pin_1"], "pin2": ["Pin_2"], "pin3": ["Pin_3"], "pin4": ["Pin_4"], "pin5": ["Pin_5"], "pin6": ["Pin_6"], "pin7": ["Pin_7"], "pin8": ["Pin_8"], "pin9": ["Pin_9"], "pin10": ["Pin_10"], "pin11": ["Pin_11"], "pin12": ["Pin_12"] }, pinAttributes: {}, schWidth: 2.245, schHeight: 1.4000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5", "pin6"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin7", "pin8", "pin9", "pin10", "pin11", "pin12"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["J3"] }) }), jsxRuntime.jsx("chip", { name: "J1", pcbX: -43.5, pcbY: 44, pcbRotation: 0, layer: "bottom", schX: 45, schY: -260, schRotation: 0, schSectionName: "section_Connectors", schSheetName: "Connectors", manufacturerPartNumber: "Conn_01x12_Female", pinLabels: { "pin1": ["Pin_1"], "pin2": ["Pin_2"], "pin3": ["Pin_3"], "pin4": ["Pin_4"], "pin5": ["Pin_5"], "pin6": ["Pin_6"], "pin7": ["Pin_7"], "pin8": ["Pin_8"], "pin9": ["Pin_9"], "pin10": ["Pin_10"], "pin11": ["Pin_11"], "pin12": ["Pin_12"] }, pinAttributes: {}, schWidth: 2.245, schHeight: 1.4000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5", "pin6"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin7", "pin8", "pin9", "pin10", "pin11", "pin12"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["J1"] }) }), jsxRuntime.jsx("chip", { name: "J4", pcbX: 43.5, pcbY: -12, pcbRotation: 0, layer: "bottom", schX: 0, schY: -267, schRotation: 0, schSectionName: "section_Connectors", schSheetName: "Connectors", manufacturerPartNumber: "Conn_01x12_Female", pinLabels: { "pin1": ["Pin_1"], "pin2": ["Pin_2"], "pin3": ["Pin_3"], "pin4": ["Pin_4"], "pin5": ["Pin_5"], "pin6": ["Pin_6"], "pin7": ["Pin_7"], "pin8": ["Pin_8"], "pin9": ["Pin_9"], "pin10": ["Pin_10"], "pin11": ["Pin_11"], "pin12": ["Pin_12"] }, pinAttributes: {}, schWidth: 2.245, schHeight: 1.4000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5", "pin6"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin7", "pin8", "pin9", "pin10", "pin11", "pin12"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["J4"] }) }), jsxRuntime.jsx("chip", { name: "J2", pcbX: -43.5, pcbY: -12, pcbRotation: 0, layer: "bottom", schX: 15, schY: -267, schRotation: 0, schSectionName: "section_Connectors", schSheetName: "Connectors", manufacturerPartNumber: "Conn_01x12_Female", pinLabels: { "pin1": ["Pin_1"], "pin2": ["Pin_2"], "pin3": ["Pin_3"], "pin4": ["Pin_4"], "pin5": ["Pin_5"], "pin6": ["Pin_6"], "pin7": ["Pin_7"], "pin8": ["Pin_8"], "pin9": ["Pin_9"], "pin10": ["Pin_10"], "pin11": ["Pin_11"], "pin12": ["Pin_12"] }, pinAttributes: {}, schWidth: 2.245, schHeight: 1.4000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2", "pin3", "pin4", "pin5", "pin6"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin7", "pin8", "pin9", "pin10", "pin11", "pin12"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["J2"] }) }), jsxRuntime.jsx("chip", { name: "JP1", pcbX: -10.599999999999994, pcbY: 1, pcbRotation: 0, layer: "bottom", schX: 160, schY: -130, schRotation: 0, schSectionName: "section_QSPI_Flash", schSheetName: "QSPI_Flash", manufacturerPartNumber: "QSPI2_NCS_Select", pinLabels: { "pin1": ["A"], "pin2": ["C"], "pin3": ["B"] }, pinAttributes: {}, schWidth: 1.39, schHeight: 0.6000000000000001, schPinArrangement: { "leftSide": { "direction": "top-to-bottom", "pins": ["pin1", "pin2"] }, "rightSide": { "direction": "top-to-bottom", "pins": ["pin3"] } }, footprint: jsxRuntime.jsx(ExactFootprint, { part: footprints["JP1"] }) }), jsxRuntime.jsx("netlabel", { connection: ".R27 > .pin1", net: "SNARE_IN", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R27 > .pin2", net: "Net_Q5_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R22 > .pin1", net: "HH_LED", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R22 > .pin2", net: "HH_LED_OUT", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R18 > .pin1", net: "CH_IN", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R18 > .pin2", net: "Net_Q3_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R8 > .pin1", net: "Net_C1_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R8 > .pin2", net: "AUDIO_OUT_L", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin1", net: "net_12V", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin2", net: "net_12V", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin3", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin4", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin5", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin6", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin7", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin8", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin9", net: "P12V", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".J7 > .pin10", net: "P12V", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C3 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C3 > .pin2", net: "P3V3", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C40 > .pin1", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C40 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U7 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U7 > .pin2", net: "VO", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U7 > .pin3", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U7 > .pin4", net: "VO", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R17 > .pin1", net: "CH_CLAMP", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R17 > .pin2", net: "P3_3VA", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R28 > .pin1", net: "SAMPLER_A_CLAMP", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R28 > .pin2", net: "P3_3VA", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".TP9 > .pin1", net: "GND", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".R5 > .pin1", net: "MIDI_IN", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R5 > .pin2", net: "Net_Q1_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin1", net: "P3_3VA", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin2", net: "Net_C34_Pad1", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin3", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin4", net: "Net_C34_Pad2", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin5", net: "Net_C36_Pad1", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin6", net: "DAC_OUT_L", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin7", net: "DAC_OUT_R", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin8", net: "P3_3VA", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin9", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin10", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin11", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin12", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin13", net: "DAC_BCLK", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin14", net: "DAC_DATA", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin15", net: "DAC_LRCLK", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin16", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin17", net: "P3V3", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin18", net: "Net_C35_Pad2", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin19", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U4 > .pin20", net: "P3V3", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".C39 > .pin1", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C39 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C38 > .pin1", net: "VSW", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C38 > .pin2", net: "CB", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R30 > .pin1", net: "SAMPLER_B_CLAMP", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R30 > .pin2", net: "P3_3VA", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C34 > .pin1", net: "Net_C34_Pad1", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C34 > .pin2", net: "Net_C34_Pad2", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C10 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C10 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".Q6 > .pin1", net: "Net_Q6_Pad1", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q6 > .pin2", net: "GND", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q6 > .pin3", net: "SAMPLER_A_CLAMP", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".C24 > .pin1", net: "Net_C24_Pad1", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C24 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".TP3 > .pin1", net: "DAC_BCLK", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".R7 > .pin1", net: "Net_C1_Pad2", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R7 > .pin2", net: "Net_C17_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C25 > .pin1", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C25 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R24 > .pin1", net: "SA_LED", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R24 > .pin2", net: "SA_LED_OUT", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C32 > .pin1", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C32 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".R32 > .pin1", net: "P3V3", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R32 > .pin2", net: "FB", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R4 > .pin1", net: "Net_R4_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R4 > .pin2", net: "Net_R3_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".TP8 > .pin1", net: "VEE", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".C33 > .pin1", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C33 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C30 > .pin1", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C30 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R9 > .pin1", net: "Net_R4_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R9 > .pin2", net: "TEMPO_OUT", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C4 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C4 > .pin2", net: "P3V3", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C31 > .pin1", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C31 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C36 > .pin1", net: "Net_C36_Pad1", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C36 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin1", net: "Net_JP1_Pad2", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin2", net: "QSPI_BK2_IO1", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin3", net: "QSPI_BK2_IO2", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin4", net: "GND", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin5", net: "QSPI_BK2_IO0", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin6", net: "QSPI_CLK", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin7", net: "QSPI_BK2_IO3", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U5 > .pin8", net: "P3V3", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".Q1 > .pin1", net: "Net_Q1_Pad1", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q1 > .pin2", net: "GND", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q1 > .pin3", net: "MIDI_UART", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q4 > .pin1", net: "Net_Q4_Pad1", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q4 > .pin2", net: "GND", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q4 > .pin3", net: "KICK_CLAMP", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".TP7 > .pin1", net: "VCC", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".R25 > .pin1", net: "SB_LED", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R25 > .pin2", net: "SB_LED_OUT", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R33 > .pin1", net: "FB", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R33 > .pin2", net: "GND", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".L1 > .pin1", net: "VSW", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".L1 > .pin2", net: "P3V3", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".Q7 > .pin1", net: "Net_Q7_Pad1", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q7 > .pin2", net: "GND", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q7 > .pin3", net: "SAMPLER_B_CLAMP", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".R10 > .pin1", net: "GND", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R10 > .pin2", net: "Net_R10_Pad2", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin1", net: "Net_R4_Pad1", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin2", net: "Net_R3_Pad1", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin3", net: "TEMPO_CLOCK", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin4", net: "VCC", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin5", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin6", net: "Net_C1_Pad2", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin7", net: "Net_C1_Pad1", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin8", net: "Net_U1_Pad8", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin9", net: "Net_U1_Pad8", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin10", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin11", net: "VEE", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin12", net: "GND", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin13", net: "Net_C20_Pad2", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".U1 > .pin14", net: "Net_C20_Pad1", schSheetName: "Audio" }), jsxRuntime.jsx("netlabel", { connection: ".R16 > .pin1", net: "Net_C20_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R16 > .pin2", net: "AUDIO_OUT_R", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C11 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C11 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".R13 > .pin1", net: "Net_C20_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R13 > .pin2", net: "Net_C20_Pad2", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".J5 > .pin1", net: "DAC2", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J5 > .pin2", net: "DAC1", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J5 > .pin3", net: "UART_RX", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J5 > .pin4", net: "UART_TX", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".Q2 > .pin1", net: "Net_Q2_Pad1", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q2 > .pin2", net: "GND", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q2 > .pin3", net: "OH_CLAMP", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".R23 > .pin1", net: "KICK_IN", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R23 > .pin2", net: "Net_Q4_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C6 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C6 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C28 > .pin1", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C28 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C13 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C13 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".Q5 > .pin1", net: "Net_Q5_Pad1", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q5 > .pin2", net: "GND", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q5 > .pin3", net: "SNARE_CLAMP", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".R3 > .pin1", net: "Net_R3_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R3 > .pin2", net: "GND", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C14 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C14 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin1", net: "QSPI_BK1_IO2", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin6", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin16", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin17", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin18", net: "UART_RX", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin19", net: "UART_TX", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin23", net: "Net_C23_Pad1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin24", net: "Net_C26_Pad1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin25", net: "Net_RESET1_Pad1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin26", net: "SNARE_FILTER_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin27", net: "SAMPLER_A_VOICE_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin30", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin31", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin32", net: "P3_3VA", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin33", net: "P3_3VA", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin34", net: "KICK_ATTACK_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin35", net: "KICK_DECAY_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin36", net: "KICK_VOL_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin37", net: "SNARE_TUNING_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin38", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin39", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin40", net: "DAC1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin41", net: "DAC2", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin42", net: "HIHAT_DECAY_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin43", net: "SAMPLER_B_VOICE_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin44", net: "SNARE_VOL_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin45", net: "SAMPLER_A_SPEED_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin46", net: "SAMPLER_B_SPEED_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin47", net: "HIHAT_VOL_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin48", net: "QSPI_CLK", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin49", net: "SAMPLER_A_VOL_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin50", net: "SAMPLER_B_VOL_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin51", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin52", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin53", net: "TEMPO_POT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin58", net: "QSPI_BK2_IO0", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin59", net: "QSPI_BK2_IO1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin60", net: "QSPI_BK2_IO2", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin61", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin62", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin63", net: "QSPI_BK2_IO3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin64", net: "HH_BTN", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin67", net: "SAMPLER_A_CLAMP", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin68", net: "SAMPLER_B_CLAMP", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin71", net: "Net_C18_Pad1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin72", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin73", net: "DAC_LRCLK", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin74", net: "DAC_BCLK", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin76", net: "DAC_DATA", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin78", net: "TEMPO_CLOCK", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin80", net: "QSPI_BK1_IO0", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin81", net: "QSPI_BK1_IO1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin82", net: "QSPI_BK1_IO3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin83", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin84", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin85", net: "SA_LED_OUT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin86", net: "SB_LED_OUT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin91", net: "QSPI_BK1_NCS", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin94", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin95", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin96", net: "SEQ_SELECT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin97", net: "HH_LED_OUT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin98", net: "SN_LED_OUT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin99", net: "KI_LED_OUT", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin101", net: "USB_VBUS", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin103", net: "USB_DM", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin104", net: "USB_DP", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin105", net: "SWIO", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin106", net: "Net_C19_Pad1", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin107", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin108", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin109", net: "SWCLK", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin112", net: "QSPI_BK2_NCS", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin115", net: "KICK_CLAMP", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin117", net: "SNARE_CLAMP", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin120", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin121", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin123", net: "OH_CLAMP", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin125", net: "CH_CLAMP", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin127", net: "OCTOSPIM_P2_NCS", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin128", net: "SB_BTN", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin130", net: "GND", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin131", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin135", net: "SN_BTN", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin136", net: "KI_BTN", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin137", net: "SA_BTN", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin138", net: "Net_R10_Pad2", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin141", net: "MIDI_UART", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin142", net: "MIDI_LEARN", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin143", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".U2 > .pin144", net: "P3V3", schSheetName: "Microcontroller" }), jsxRuntime.jsx("netlabel", { connection: ".Y1 > .pin1", net: "Net_C26_Pad1", schSheetName: "Clock" }), jsxRuntime.jsx("netlabel", { connection: ".Y1 > .pin2", net: "Net_C23_Pad1", schSheetName: "Clock" }), jsxRuntime.jsx("netlabel", { connection: ".C20 > .pin1", net: "Net_C20_Pad1", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C20 > .pin2", net: "Net_C20_Pad2", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C16 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C16 > .pin2", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".D1 > .pin1", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".D1 > .pin2", net: "P12V", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C5 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C5 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".R29 > .pin1", net: "SAMPLER_A_IN", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R29 > .pin2", net: "Net_Q6_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".TP1 > .pin1", net: "DAC_LRCLK", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".R6 > .pin1", net: "Net_C17_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R6 > .pin2", net: "DAC_OUT_L", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C26 > .pin1", net: "Net_C26_Pad1", schSheetName: "Clock" }), jsxRuntime.jsx("netlabel", { connection: ".C26 > .pin2", net: "GND", schSheetName: "Clock" }), jsxRuntime.jsx("netlabel", { connection: ".R31 > .pin1", net: "SAMPLER_B_IN", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R31 > .pin2", net: "Net_Q7_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R2 > .pin1", net: "Net_C1_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R2 > .pin2", net: "Net_C1_Pad2", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C27 > .pin1", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C27 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".TP6 > .pin1", net: "P3_3VA", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin1", net: "QSPI_BK1_NCS", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin2", net: "QSPI_BK1_IO1", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin3", net: "QSPI_BK1_IO2", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin4", net: "GND", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin5", net: "QSPI_BK1_IO0", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin6", net: "QSPI_CLK", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin7", net: "QSPI_BK1_IO3", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".U3 > .pin8", net: "P3V3", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".C41 > .pin1", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C41 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".RESET1 > .pin1", net: "Net_RESET1_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".RESET1 > .pin2", net: "GND", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".RESET1 > .pin3", net: "Net_RESET1_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".RESET1 > .pin4", net: "GND", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R26 > .pin1", net: "SNARE_CLAMP", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R26 > .pin2", net: "P3_3VA", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C42 > .pin1", net: "P3V3", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C42 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".L2 > .pin1", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".L2 > .pin2", net: "VO", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".Q3 > .pin1", net: "Net_Q3_Pad1", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q3 > .pin2", net: "GND", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".Q3 > .pin3", net: "CH_CLAMP", schSheetName: "Input_Clamps" }), jsxRuntime.jsx("netlabel", { connection: ".R12 > .pin1", net: "OH_IN", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R12 > .pin2", net: "Net_Q2_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C18 > .pin1", net: "Net_C18_Pad1", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C18 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C9 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C9 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".D2 > .pin1", net: "net_12V", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".D2 > .pin2", net: "VEE", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C29 > .pin1", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C29 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R20 > .pin1", net: "KICK_CLAMP", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R20 > .pin2", net: "P3_3VA", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C35 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C35 > .pin2", net: "Net_C35_Pad2", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C7 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C7 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C2 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C2 > .pin2", net: "P3V3", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C43 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C43 > .pin2", net: "VEE", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C12 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C12 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".R15 > .pin1", net: "Net_C20_Pad2", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R15 > .pin2", net: "Net_C24_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".U6 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U6 > .pin2", net: "VSW", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U6 > .pin3", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U6 > .pin4", net: "FB", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U6 > .pin5", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".U6 > .pin6", net: "CB", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C21 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C21 > .pin2", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C17 > .pin1", net: "Net_C17_Pad1", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C17 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".TP5 > .pin1", net: "P3V3", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".J6 > .pin1", net: "P3V3", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J6 > .pin2", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J6 > .pin3", net: "SWIO", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J6 > .pin4", net: "SWCLK", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".C37 > .pin1", net: "VCC", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C37 > .pin2", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C19 > .pin1", net: "Net_C19_Pad1", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C19 > .pin2", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C22 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C22 > .pin2", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R21 > .pin1", net: "SN_LED", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R21 > .pin2", net: "SN_LED_OUT", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C8 > .pin1", net: "GND", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".C8 > .pin2", net: "P3V3", schSheetName: "Capacitors" }), jsxRuntime.jsx("netlabel", { connection: ".TP2 > .pin1", net: "DAC_DATA", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".C15 > .pin1", net: "GND", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C15 > .pin2", net: "P3_3VA", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R11 > .pin1", net: "OH_CLAMP", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R11 > .pin2", net: "P3_3VA", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R14 > .pin1", net: "Net_C24_Pad1", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R14 > .pin2", net: "DAC_OUT_R", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R1 > .pin1", net: "MIDI_UART", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R1 > .pin2", net: "P3_3VA", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".C1 > .pin1", net: "Net_C1_Pad1", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".C1 > .pin2", net: "Net_C1_Pad2", schSheetName: "Power" }), jsxRuntime.jsx("netlabel", { connection: ".R19 > .pin1", net: "KI_LED", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".R19 > .pin2", net: "KI_LED_OUT", schSheetName: "Resistors" }), jsxRuntime.jsx("netlabel", { connection: ".TP4 > .pin1", net: "GND", schSheetName: "Test_Points" }), jsxRuntime.jsx("netlabel", { connection: ".C23 > .pin1", net: "Net_C23_Pad1", schSheetName: "Clock" }), jsxRuntime.jsx("netlabel", { connection: ".C23 > .pin2", net: "GND", schSheetName: "Clock" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin1", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin2", net: "SA_BTN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin3", net: "KI_BTN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin4", net: "SN_BTN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin5", net: "SA_LED", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin6", net: "SB_BTN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin7", net: "SB_LED", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin8", net: "MIDI_LEARN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin9", net: "MIDI_IN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin10", net: "CH_IN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin11", net: "OH_IN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J3 > .pin12", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin1", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin2", net: "SNARE_FILTER_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin3", net: "SAMPLER_A_VOICE_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin4", net: "KICK_ATTACK_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin5", net: "KICK_DECAY_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin6", net: "KICK_VOL_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin7", net: "SNARE_TUNING_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin8", net: "HIHAT_DECAY_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin9", net: "SAMPLER_B_VOICE_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin10", net: "SNARE_VOL_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin11", net: "SAMPLER_A_SPEED_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J1 > .pin12", net: "SAMPLER_B_SPEED_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin1", net: "SNARE_IN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin2", net: "KICK_IN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin3", net: "USB_DP", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin4", net: "USB_DM", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin5", net: "USB_VBUS", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin6", net: "KI_LED", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin7", net: "SN_LED", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin8", net: "HH_LED", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin9", net: "SEQ_SELECT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin10", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin11", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J4 > .pin12", net: "P3_3VA", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin1", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin2", net: "HIHAT_VOL_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin3", net: "SAMPLER_A_VOL_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin4", net: "SAMPLER_B_VOL_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin5", net: "HH_BTN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin6", net: "TEMPO_POT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin7", net: "SAMPLER_A_IN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin8", net: "SAMPLER_B_IN", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin9", net: "AUDIO_OUT_R", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin10", net: "TEMPO_OUT", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin11", net: "AUDIO_OUT_L", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".J2 > .pin12", net: "GND", schSheetName: "Connectors" }), jsxRuntime.jsx("netlabel", { connection: ".JP1 > .pin1", net: "QSPI_BK2_NCS", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".JP1 > .pin2", net: "Net_JP1_Pad2", schSheetName: "QSPI_Flash" }), jsxRuntime.jsx("netlabel", { connection: ".JP1 > .pin3", net: "OCTOSPIM_P2_NCS", schSheetName: "QSPI_Flash" })] });
}
module.exports = Punck;