@tscircuit/capacity-autorouter 0.0.26 → 0.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/utils/combineVisualizations.ts","../lib/solvers/BaseSolver.ts","../node_modules/@tscircuit/math-utils/src/line-intersections.ts","../lib/utils/areNodesBordering.ts","../lib/solvers/CapacityMeshSolver/CapacityMeshEdgeSolver.ts","../node_modules/@babel/runtime/helpers/esm/extends.js","../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/isNativeFunction.js","../node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js","../node_modules/@babel/runtime/helpers/esm/construct.js","../node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js","../node_modules/polished/dist/polished.esm.js","../lib/solvers/colors.ts","../lib/utils/isPointInRect.ts","../lib/utils/doRectsOverlap.ts","../lib/utils/mapLayerNameToZ.ts","../lib/solvers/CapacityMeshSolver/CapacityMeshNodeSolver1.ts","../lib/solvers/CapacityMeshSolver/CapacityMeshNodeSolver2_NodesUnderObstacles.ts","../lib/solvers/CapacityMeshSolver/getNodeEdgeMap.ts","../lib/solvers/CapacityMeshSolver/CapacityEdgeToPortSegmentSolver.ts","../lib/solvers/CapacityMeshSolver/CapacitySegmentToPointSolver.ts","../lib/solvers/HighDensitySolver/SingleHighDensityRouteSolver.ts","../lib/solvers/HighDensitySolver/SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost.ts","../lib/utils/cloneAndShuffleArray.ts","../lib/utils/getBoundsFromNodeWithPortPoints.ts","../lib/utils/getMinDistBetweenEnteringPoints.ts","../lib/solvers/HighDensitySolver/IntraNodeSolver.ts","../lib/solvers/HyperParameterSupervisorSolver.ts","../lib/solvers/HyperHighDensitySolver/HyperSingleIntraNodeSolver.ts","../lib/utils/mergeRouteSegments.ts","../lib/solvers/HighDensitySolver/HighDensitySolver.ts","../node_modules/circuit-json-to-connectivity-map/src/findConnectedNetworks.ts","../node_modules/circuit-json-to-connectivity-map/src/ConnectivityMap.ts","../node_modules/circuit-json-to-connectivity-map/src/getSourcePortConnectivityMapFromCircuitJson.ts","../node_modules/circuit-json-to-connectivity-map/src/getFullConnectivityMapFromCircuitJson.ts","../node_modules/circuit-json-to-connectivity-map/src/PcbConnectivityMap.ts","../lib/utils/getConnectivityMapFromSimpleRouteJson.ts","../lib/utils/getTunedTotalCapacity1.ts","../lib/solvers/NetToPointPairsSolver/buildMinimumSpanningTree.ts","../lib/solvers/NetToPointPairsSolver/NetToPointPairsSolver.ts","../lib/utils/mapZToLayerName.ts","../lib/utils/convertHdRouteToSimplifiedRoute.ts","../lib/solvers/RouteStitchingSolver/SingleHighDensityRouteStitchSolver.ts","../lib/solvers/RouteStitchingSolver/MultipleHighDensityRouteStitchSolver.ts","../tests/fixtures/convertSrjToGraphicsObject.ts","../lib/solvers/UnravelSolver/getNodesNearNode.ts","../lib/solvers/UnravelSolver/createPointModificationsHash.ts","../lib/solvers/UnravelSolver/hasZRangeOverlap.ts","../lib/solvers/UnravelSolver/getIssuesInSection.ts","../lib/solvers/UnravelSolver/getLogProbability.ts","../lib/solvers/UnravelSolver/applyOperationToPointModifications.ts","../lib/solvers/UnravelSolver/createSegmentPointMap.ts","../lib/solvers/UnravelSolver/UnravelSectionSolver.ts","../lib/solvers/UnravelSolver/getDedupedSegments.ts","../lib/utils/getIntraNodeCrossingsFromSegments.ts","../lib/solvers/UnravelSolver/calculateCrossingProbabilityOfFailure.ts","../lib/solvers/UnravelSolver/UnravelMultiSectionSolver.ts","../lib/utils/createRectFromCapacityNode.ts","../lib/solvers/CapacityPathingSolver/CapacityPathingSolver.ts","../lib/solvers/CapacityPathingSolver/CapacityPathingSolver5.ts","../lib/solvers/StrawSolver/StrawSolver.ts","../lib/solvers/SingleLayerNodeMerger/SingleLayerNodeMergerSolver.ts","../lib/solvers/AutoroutingPipelineSolver.ts"],"sourcesContent":["import type { GraphicsObject } from \"graphics-debug\"\n\nexport const combineVisualizations = (\n ...visualizations: GraphicsObject[]\n): GraphicsObject => {\n const combined: GraphicsObject = {\n points: [],\n lines: [],\n circles: [],\n rects: [],\n }\n\n visualizations.forEach((viz, i) => {\n if (viz.lines) {\n combined.lines = [\n ...(combined.lines || []),\n ...viz.lines.map((l) => ({ ...l, step: i })),\n ]\n }\n if (viz.points) {\n combined.points = [\n ...(combined.points || []),\n ...viz.points.map((p) => ({ ...p, step: i })),\n ]\n }\n if (viz.circles) {\n combined.circles = [\n ...(combined.circles || []),\n ...viz.circles.map((c) => ({ ...c, step: i })),\n ]\n }\n if (viz.rects) {\n combined.rects = [\n ...(combined.rects || []),\n ...viz.rects.map((r) => ({ ...r, step: i })),\n ]\n }\n })\n\n return combined\n}\n","import type { GraphicsObject } from \"graphics-debug\"\n\nexport class BaseSolver {\n MAX_ITERATIONS = 1000\n solved = false\n failed = false\n iterations = 0\n progress = 0\n error: string | null = null\n activeSubSolver?: BaseSolver | null\n failedSubSolvers?: BaseSolver[]\n timeToSolve?: number\n\n /** DO NOT OVERRIDE! Override _step() instead */\n step() {\n if (this.solved) return\n if (this.failed) return\n this.iterations++\n try {\n this._step()\n } catch (e) {\n this.error = `${this.constructor.name} error: ${e}`\n console.error(this.error)\n this.failed = true\n throw e\n }\n if (!this.solved && this.iterations > this.MAX_ITERATIONS) {\n this.error = `${this.constructor.name} did not converge`\n console.error(this.error)\n this.failed = true\n }\n }\n\n _step() {}\n\n solve() {\n const startTime = Date.now()\n while (!this.solved && !this.failed) {\n this.step()\n }\n const endTime = Date.now()\n this.timeToSolve = endTime - startTime\n }\n\n visualize(): GraphicsObject {\n return {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n }\n}\n","import type { Point } from \"./common\"\n\n/**\n * Returns true if the two lines intersect.\n */\nexport function doesLineIntersectLine(\n [a1, a2]: [Point, Point],\n [b1, b2]: [Point, Point],\n {\n lineThickness = 0,\n }: {\n lineThickness?: number\n } = {},\n): boolean {\n if (lineThickness === 0) {\n return doSegmentsIntersect(a1, a2, b1, b2)\n }\n const minDist = segmentsDistance(a1, a2, b1, b2)\n return minDist <= lineThickness\n}\n\n/**\n * Returns true if the two segments intersect.\n */\nexport function doSegmentsIntersect(\n p1: Point,\n q1: Point,\n p2: Point,\n q2: Point,\n): boolean {\n const o1 = orientation(p1, q1, p2)\n const o2 = orientation(p1, q1, q2)\n const o3 = orientation(p2, q2, p1)\n const o4 = orientation(p2, q2, q1)\n\n // General case\n if (o1 !== o2 && o3 !== o4) {\n return true\n }\n\n // Special Cases\n if (o1 === 0 && onSegment(p1, p2, q1)) return true\n if (o2 === 0 && onSegment(p1, q2, q1)) return true\n if (o3 === 0 && onSegment(p2, p1, q2)) return true\n if (o4 === 0 && onSegment(p2, q1, q2)) return true\n\n return false\n}\n\n/**\n * Returns 0 if the points are colinear, 1 if they are clockwise, and 2 if they are counterclockwise.\n */\nexport function orientation(p: Point, q: Point, r: Point): number {\n const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y)\n if (val === 0) return 0 // colinear\n return val > 0 ? 1 : 2 // clock or counterclock wise\n}\n\n/**\n * Returns true if q is on the segment p->r.\n */\nexport function onSegment(p: Point, q: Point, r: Point): boolean {\n return (\n q.x <= Math.max(p.x, r.x) &&\n q.x >= Math.min(p.x, r.x) &&\n q.y <= Math.max(p.y, r.y) &&\n q.y >= Math.min(p.y, r.y)\n )\n}\n\n/**\n * Returns the minimum distance between two segments.\n */\nfunction segmentsDistance(a1: Point, a2: Point, b1: Point, b2: Point): number {\n // Handle degenerate cases: segments of zero length\n if (a1.x === a2.x && a1.y === a2.y) {\n return pointToSegmentDistance(a1, b1, b2)\n }\n if (b1.x === b2.x && b1.y === b2.y) {\n return pointToSegmentDistance(b1, a1, a2)\n }\n\n // Check if segments intersect\n if (doSegmentsIntersect(a1, a2, b1, b2)) {\n return 0\n }\n\n // Compute the minimum distance between the segments\n const distances = [\n pointToSegmentDistance(a1, b1, b2),\n pointToSegmentDistance(a2, b1, b2),\n pointToSegmentDistance(b1, a1, a2),\n pointToSegmentDistance(b2, a1, a2),\n ]\n\n return Math.min(...distances)\n}\n\n/**\n * Returns the minimum distance between a point and a segment.\n */\nexport function pointToSegmentDistance(p: Point, v: Point, w: Point): number {\n const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2\n if (l2 === 0) return distance(p, v)\n\n let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2\n t = Math.max(0, Math.min(1, t))\n\n const projection = {\n x: v.x + t * (w.x - v.x),\n y: v.y + t * (w.y - v.y),\n }\n\n return distance(p, projection)\n}\n\n/**\n * Returns the distance between two points.\n */\nexport function distance(p1: Point, p2: Point): number {\n const dx = p1.x - p2.x\n const dy = p1.y - p2.y\n return Math.sqrt(dx * dx + dy * dy)\n}\n","import { CapacityMeshNode } from \"../types\"\n\nexport function areNodesBordering(\n node1: CapacityMeshNode,\n node2: CapacityMeshNode,\n): boolean {\n const n1Left = node1.center.x - node1.width / 2\n const n1Right = node1.center.x + node1.width / 2\n const n1Top = node1.center.y - node1.height / 2\n const n1Bottom = node1.center.y + node1.height / 2\n\n const n2Left = node2.center.x - node2.width / 2\n const n2Right = node2.center.x + node2.width / 2\n const n2Top = node2.center.y - node2.height / 2\n const n2Bottom = node2.center.y + node2.height / 2\n\n const epsilon = 0.001\n\n const shareVerticalBorder =\n (Math.abs(n1Right - n2Left) < epsilon ||\n Math.abs(n1Left - n2Right) < epsilon) &&\n Math.min(n1Bottom, n2Bottom) - Math.max(n1Top, n2Top) >= epsilon\n\n const shareHorizontalBorder =\n (Math.abs(n1Bottom - n2Top) < epsilon ||\n Math.abs(n1Top - n2Bottom) < epsilon) &&\n Math.min(n1Right, n2Right) - Math.max(n1Left, n2Left) >= epsilon\n\n return shareVerticalBorder || shareHorizontalBorder\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n} from \"../../types/capacity-mesh-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { distance } from \"@tscircuit/math-utils\"\nimport { areNodesBordering } from \"lib/utils/areNodesBordering\"\n\nexport class CapacityMeshEdgeSolver extends BaseSolver {\n public edges: Array<CapacityMeshEdge>\n\n constructor(public nodes: CapacityMeshNode[]) {\n super()\n this.edges = []\n }\n\n getNextCapacityMeshEdgeId() {\n return `ce${this.edges.length}`\n }\n\n step() {\n this.edges = []\n for (let i = 0; i < this.nodes.length; i++) {\n for (let j = i + 1; j < this.nodes.length; j++) {\n if (\n !(this.nodes[i]._strawNode && this.nodes[j]._strawNode) &&\n areNodesBordering(this.nodes[i], this.nodes[j]) &&\n this.doNodesHaveSharedLayer(this.nodes[i], this.nodes[j])\n ) {\n this.edges.push({\n capacityMeshEdgeId: this.getNextCapacityMeshEdgeId(),\n nodeIds: [\n this.nodes[i].capacityMeshNodeId,\n this.nodes[j].capacityMeshNodeId,\n ],\n })\n }\n }\n }\n\n // If a target node is not connected to any other node, then it is \"inside\n // an obstacle\" (this is the case almost 100% of the time when we place\n // targets inside of PCB pads)\n // To fix this we connect it to the nearest nodes without obstacles\n const targetNodes = this.nodes.filter((node) => node._containsTarget)\n for (const targetNode of targetNodes) {\n const hasEdge = this.edges.some((edge) =>\n edge.nodeIds.includes(targetNode.capacityMeshNodeId),\n )\n if (hasEdge) continue\n\n let nearestNode: CapacityMeshNode | null = null\n let nearestDistance = Infinity\n for (const node of this.nodes) {\n if (node._containsObstacle) continue\n if (node._containsTarget) continue\n const dist = distance(targetNode.center, node.center)\n if (dist < nearestDistance) {\n nearestDistance = dist\n nearestNode = node\n }\n }\n if (nearestNode) {\n this.edges.push({\n capacityMeshEdgeId: this.getNextCapacityMeshEdgeId(),\n nodeIds: [\n targetNode.capacityMeshNodeId,\n nearestNode.capacityMeshNodeId,\n ],\n })\n }\n }\n\n this.solved = true\n }\n\n private doNodesHaveSharedLayer(\n node1: CapacityMeshNode,\n node2: CapacityMeshNode,\n ): boolean {\n return node1.availableZ.some((z) => node2.availableZ.includes(z))\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: this.nodes.map((node) => {\n const lowestZ = Math.min(...node.availableZ)\n return {\n width: Math.max(node.width - 2, node.width * 0.8),\n height: Math.max(node.height - 2, node.height * 0.8),\n center: {\n x: node.center.x + lowestZ * node.width * 0.05,\n y: node.center.y - lowestZ * node.width * 0.05,\n },\n fill: node._containsObstacle\n ? \"rgba(255,0,0,0.1)\"\n : ({\n \"0,1\": \"rgba(0,0,0,0.1)\",\n \"0\": \"rgba(0,200,200, 0.1)\",\n \"1\": \"rgba(0,0,200, 0.1)\",\n }[node.availableZ.join(\",\")] ?? \"rgba(0,200,200,0.1)\"),\n label: [\n node.capacityMeshNodeId,\n `availableZ: ${node.availableZ.join(\",\")}`,\n `target? ${node._containsTarget ?? false}`,\n `obs? ${node._containsObstacle ?? false}`,\n ].join(\"\\n\"),\n }\n }),\n circles: [],\n }\n for (const edge of this.edges) {\n const node1 = this.nodes.find(\n (node) => node.capacityMeshNodeId === edge.nodeIds[0],\n )\n const node2 = this.nodes.find(\n (node) => node.capacityMeshNodeId === edge.nodeIds[1],\n )\n if (node1?.center && node2?.center) {\n const lowestZ1 = Math.min(...node1.availableZ)\n const lowestZ2 = Math.min(...node2.availableZ)\n const nodeCenter1Adj = {\n x: node1.center.x + lowestZ1 * node1.width * 0.05,\n y: node1.center.y - lowestZ1 * node1.width * 0.05,\n }\n const nodeCenter2Adj = {\n x: node2.center.x + lowestZ2 * node2.width * 0.05,\n y: node2.center.y - lowestZ2 * node2.width * 0.05,\n }\n graphics.lines!.push({\n points: [nodeCenter1Adj, nodeCenter2Adj],\n strokeDash:\n node1.availableZ.join(\",\") === node2.availableZ.join(\",\")\n ? undefined\n : \"10 5\",\n })\n }\n }\n return graphics\n }\n}\n","function _extends() {\n return _extends = Object.assign ? Object.assign.bind() : function (n) {\n for (var e = 1; e < arguments.length; e++) {\n var t = arguments[e];\n for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);\n }\n return n;\n }, _extends.apply(null, arguments);\n}\nexport { _extends as default };","function _assertThisInitialized(e) {\n if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n return e;\n}\nexport { _assertThisInitialized as default };","function _setPrototypeOf(t, e) {\n return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {\n return t.__proto__ = e, t;\n }, _setPrototypeOf(t, e);\n}\nexport { _setPrototypeOf as default };","import setPrototypeOf from \"./setPrototypeOf.js\";\nfunction _inheritsLoose(t, o) {\n t.prototype = Object.create(o.prototype), t.prototype.constructor = t, setPrototypeOf(t, o);\n}\nexport { _inheritsLoose as default };","function _getPrototypeOf(t) {\n return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {\n return t.__proto__ || Object.getPrototypeOf(t);\n }, _getPrototypeOf(t);\n}\nexport { _getPrototypeOf as default };","function _isNativeFunction(t) {\n try {\n return -1 !== Function.toString.call(t).indexOf(\"[native code]\");\n } catch (n) {\n return \"function\" == typeof t;\n }\n}\nexport { _isNativeFunction as default };","function _isNativeReflectConstruct() {\n try {\n var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n } catch (t) {}\n return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {\n return !!t;\n })();\n}\nexport { _isNativeReflectConstruct as default };","import isNativeReflectConstruct from \"./isNativeReflectConstruct.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nfunction _construct(t, e, r) {\n if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);\n var o = [null];\n o.push.apply(o, e);\n var p = new (t.bind.apply(t, o))();\n return r && setPrototypeOf(p, r.prototype), p;\n}\nexport { _construct as default };","import getPrototypeOf from \"./getPrototypeOf.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeFunction from \"./isNativeFunction.js\";\nimport construct from \"./construct.js\";\nfunction _wrapNativeSuper(t) {\n var r = \"function\" == typeof Map ? new Map() : void 0;\n return _wrapNativeSuper = function _wrapNativeSuper(t) {\n if (null === t || !isNativeFunction(t)) return t;\n if (\"function\" != typeof t) throw new TypeError(\"Super expression must either be null or a function\");\n if (void 0 !== r) {\n if (r.has(t)) return r.get(t);\n r.set(t, Wrapper);\n }\n function Wrapper() {\n return construct(t, arguments, getPrototypeOf(this).constructor);\n }\n return Wrapper.prototype = Object.create(t.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: !1,\n writable: !0,\n configurable: !0\n }\n }), setPrototypeOf(Wrapper, t);\n }, _wrapNativeSuper(t);\n}\nexport { _wrapNativeSuper as default };","import _extends from '@babel/runtime/helpers/esm/extends';\nimport _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized';\nimport _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';\nimport _wrapNativeSuper from '@babel/runtime/helpers/esm/wrapNativeSuper';\nimport _taggedTemplateLiteralLoose from '@babel/runtime/helpers/esm/taggedTemplateLiteralLoose';\n\nfunction last() {\n var _ref;\n return _ref = arguments.length - 1, _ref < 0 || arguments.length <= _ref ? undefined : arguments[_ref];\n}\nfunction negation(a) {\n return -a;\n}\nfunction addition(a, b) {\n return a + b;\n}\nfunction subtraction(a, b) {\n return a - b;\n}\nfunction multiplication(a, b) {\n return a * b;\n}\nfunction division(a, b) {\n return a / b;\n}\nfunction max() {\n return Math.max.apply(Math, arguments);\n}\nfunction min() {\n return Math.min.apply(Math, arguments);\n}\nfunction comma() {\n return Array.of.apply(Array, arguments);\n}\nvar defaultSymbols = {\n symbols: {\n '*': {\n infix: {\n symbol: '*',\n f: multiplication,\n notation: 'infix',\n precedence: 4,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: '*',\n regSymbol: '\\\\*'\n },\n '/': {\n infix: {\n symbol: '/',\n f: division,\n notation: 'infix',\n precedence: 4,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: '/',\n regSymbol: '/'\n },\n '+': {\n infix: {\n symbol: '+',\n f: addition,\n notation: 'infix',\n precedence: 2,\n rightToLeft: 0,\n argCount: 2\n },\n prefix: {\n symbol: '+',\n f: last,\n notation: 'prefix',\n precedence: 3,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '+',\n regSymbol: '\\\\+'\n },\n '-': {\n infix: {\n symbol: '-',\n f: subtraction,\n notation: 'infix',\n precedence: 2,\n rightToLeft: 0,\n argCount: 2\n },\n prefix: {\n symbol: '-',\n f: negation,\n notation: 'prefix',\n precedence: 3,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '-',\n regSymbol: '-'\n },\n ',': {\n infix: {\n symbol: ',',\n f: comma,\n notation: 'infix',\n precedence: 1,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: ',',\n regSymbol: ','\n },\n '(': {\n prefix: {\n symbol: '(',\n f: last,\n notation: 'prefix',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '(',\n regSymbol: '\\\\('\n },\n ')': {\n postfix: {\n symbol: ')',\n f: undefined,\n notation: 'postfix',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: ')',\n regSymbol: '\\\\)'\n },\n min: {\n func: {\n symbol: 'min',\n f: min,\n notation: 'func',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: 'min',\n regSymbol: 'min\\\\b'\n },\n max: {\n func: {\n symbol: 'max',\n f: max,\n notation: 'func',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: 'max',\n regSymbol: 'max\\\\b'\n }\n }\n};\nvar defaultSymbolMap = defaultSymbols;\n\n// based on https://github.com/styled-components/styled-components/blob/fcf6f3804c57a14dd7984dfab7bc06ee2edca044/src/utils/error.js\n/**\n * Parse errors.md and turn it into a simple hash of code: message\n * @private\n */\nvar ERRORS = {\n \"1\": \"Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\\n\\n\",\n \"2\": \"Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\\n\\n\",\n \"3\": \"Passed an incorrect argument to a color function, please pass a string representation of a color.\\n\\n\",\n \"4\": \"Couldn't generate valid rgb string from %s, it returned %s.\\n\\n\",\n \"5\": \"Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\\n\\n\",\n \"6\": \"Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\\n\\n\",\n \"7\": \"Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\\n\\n\",\n \"8\": \"Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\\n\\n\",\n \"9\": \"Please provide a number of steps to the modularScale helper.\\n\\n\",\n \"10\": \"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\\n\\n\",\n \"11\": \"Invalid value passed as base to modularScale, expected number or em string but got \\\"%s\\\"\\n\\n\",\n \"12\": \"Expected a string ending in \\\"px\\\" or a number passed as the first argument to %s(), got \\\"%s\\\" instead.\\n\\n\",\n \"13\": \"Expected a string ending in \\\"px\\\" or a number passed as the second argument to %s(), got \\\"%s\\\" instead.\\n\\n\",\n \"14\": \"Passed invalid pixel value (\\\"%s\\\") to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"15\": \"Passed invalid base value (\\\"%s\\\") to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"16\": \"You must provide a template to this method.\\n\\n\",\n \"17\": \"You passed an unsupported selector state to this method.\\n\\n\",\n \"18\": \"minScreen and maxScreen must be provided as stringified numbers with the same units.\\n\\n\",\n \"19\": \"fromSize and toSize must be provided as stringified numbers with the same units.\\n\\n\",\n \"20\": \"expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\\n\\n\",\n \"21\": \"expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\\n\\n\",\n \"22\": \"expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\\n\\n\",\n \"23\": \"fontFace expects a name of a font-family.\\n\\n\",\n \"24\": \"fontFace expects either the path to the font file(s) or a name of a local copy.\\n\\n\",\n \"25\": \"fontFace expects localFonts to be an array.\\n\\n\",\n \"26\": \"fontFace expects fileFormats to be an array.\\n\\n\",\n \"27\": \"radialGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"28\": \"Please supply a filename to retinaImage() as the first argument.\\n\\n\",\n \"29\": \"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\\n\\n\",\n \"30\": \"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\\n\\n\",\n \"31\": \"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\\n\\n\",\n \"32\": \"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\\n\\n\",\n \"33\": \"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\\n\\n\",\n \"34\": \"borderRadius expects a radius value as a string or number as the second argument.\\n\\n\",\n \"35\": \"borderRadius expects one of \\\"top\\\", \\\"bottom\\\", \\\"left\\\" or \\\"right\\\" as the first argument.\\n\\n\",\n \"36\": \"Property must be a string value.\\n\\n\",\n \"37\": \"Syntax Error at %s.\\n\\n\",\n \"38\": \"Formula contains a function that needs parentheses at %s.\\n\\n\",\n \"39\": \"Formula is missing closing parenthesis at %s.\\n\\n\",\n \"40\": \"Formula has too many closing parentheses at %s.\\n\\n\",\n \"41\": \"All values in a formula must have the same unit or be unitless.\\n\\n\",\n \"42\": \"Please provide a number of steps to the modularScale helper.\\n\\n\",\n \"43\": \"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\\n\\n\",\n \"44\": \"Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\\n\\n\",\n \"45\": \"Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\\n\\n\",\n \"46\": \"Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\\n\\n\",\n \"47\": \"minScreen and maxScreen must be provided as stringified numbers with the same units.\\n\\n\",\n \"48\": \"fromSize and toSize must be provided as stringified numbers with the same units.\\n\\n\",\n \"49\": \"Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\\n\\n\",\n \"50\": \"Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\\n\\n\",\n \"51\": \"Expects the first argument object to have the properties prop, fromSize, and toSize.\\n\\n\",\n \"52\": \"fontFace expects either the path to the font file(s) or a name of a local copy.\\n\\n\",\n \"53\": \"fontFace expects localFonts to be an array.\\n\\n\",\n \"54\": \"fontFace expects fileFormats to be an array.\\n\\n\",\n \"55\": \"fontFace expects a name of a font-family.\\n\\n\",\n \"56\": \"linearGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"57\": \"radialGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"58\": \"Please supply a filename to retinaImage() as the first argument.\\n\\n\",\n \"59\": \"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\\n\\n\",\n \"60\": \"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\\n\\n\",\n \"61\": \"Property must be a string value.\\n\\n\",\n \"62\": \"borderRadius expects a radius value as a string or number as the second argument.\\n\\n\",\n \"63\": \"borderRadius expects one of \\\"top\\\", \\\"bottom\\\", \\\"left\\\" or \\\"right\\\" as the first argument.\\n\\n\",\n \"64\": \"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\\n\\n\",\n \"65\": \"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\\n\\n\",\n \"66\": \"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\\n\\n\",\n \"67\": \"You must provide a template to this method.\\n\\n\",\n \"68\": \"You passed an unsupported selector state to this method.\\n\\n\",\n \"69\": \"Expected a string ending in \\\"px\\\" or a number passed as the first argument to %s(), got %s instead.\\n\\n\",\n \"70\": \"Expected a string ending in \\\"px\\\" or a number passed as the second argument to %s(), got %s instead.\\n\\n\",\n \"71\": \"Passed invalid pixel value %s to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"72\": \"Passed invalid base value %s to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"73\": \"Please provide a valid CSS variable.\\n\\n\",\n \"74\": \"CSS variable not found and no default was provided.\\n\\n\",\n \"75\": \"important requires a valid style object, got a %s instead.\\n\\n\",\n \"76\": \"fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\\n\\n\",\n \"77\": \"remToPx expects a value in \\\"rem\\\" but you provided it in \\\"%s\\\".\\n\\n\",\n \"78\": \"base must be set in \\\"px\\\" or \\\"%\\\" but you set it in \\\"%s\\\".\\n\"\n};\n\n/**\n * super basic version of sprintf\n * @private\n */\nfunction format() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n var a = args[0];\n var b = [];\n var c;\n for (c = 1; c < args.length; c += 1) {\n b.push(args[c]);\n }\n b.forEach(function (d) {\n a = a.replace(/%[a-z]/, d);\n });\n return a;\n}\n\n/**\n * Create an error file out of errors.md for development and a simple web link to the full errors\n * in production mode.\n * @private\n */\nvar PolishedError = /*#__PURE__*/function (_Error) {\n _inheritsLoose(PolishedError, _Error);\n function PolishedError(code) {\n var _this;\n if (process.env.NODE_ENV === 'production') {\n _this = _Error.call(this, \"An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#\" + code + \" for more information.\") || this;\n } else {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n _this = _Error.call(this, format.apply(void 0, [ERRORS[code]].concat(args))) || this;\n }\n return _assertThisInitialized(_this);\n }\n return PolishedError;\n}( /*#__PURE__*/_wrapNativeSuper(Error));\n\nvar unitRegExp = /((?!\\w)a|na|hc|mc|dg|me[r]?|xe|ni(?![a-zA-Z])|mm|cp|tp|xp|q(?!s)|hv|xamv|nimv|wv|sm|s(?!\\D|$)|ged|darg?|nrut)/g;\n\n// Merges additional math functionality into the defaults.\nfunction mergeSymbolMaps(additionalSymbols) {\n var symbolMap = {};\n symbolMap.symbols = additionalSymbols ? _extends({}, defaultSymbolMap.symbols, additionalSymbols.symbols) : _extends({}, defaultSymbolMap.symbols);\n return symbolMap;\n}\nfunction exec(operators, values) {\n var _ref;\n var op = operators.pop();\n values.push(op.f.apply(op, (_ref = []).concat.apply(_ref, values.splice(-op.argCount))));\n return op.precedence;\n}\nfunction calculate(expression, additionalSymbols) {\n var symbolMap = mergeSymbolMaps(additionalSymbols);\n var match;\n var operators = [symbolMap.symbols['('].prefix];\n var values = [];\n var pattern = new RegExp( // Pattern for numbers\n \"\\\\d+(?:\\\\.\\\\d+)?|\" +\n // ...and patterns for individual operators/function names\n Object.keys(symbolMap.symbols).map(function (key) {\n return symbolMap.symbols[key];\n })\n // longer symbols should be listed first\n // $FlowFixMe\n .sort(function (a, b) {\n return b.symbol.length - a.symbol.length;\n })\n // $FlowFixMe\n .map(function (val) {\n return val.regSymbol;\n }).join('|') + \"|(\\\\S)\", 'g');\n pattern.lastIndex = 0; // Reset regular expression object\n\n var afterValue = false;\n do {\n match = pattern.exec(expression);\n var _ref2 = match || [')', undefined],\n token = _ref2[0],\n bad = _ref2[1];\n var notNumber = symbolMap.symbols[token];\n var notNewValue = notNumber && !notNumber.prefix && !notNumber.func;\n var notAfterValue = !notNumber || !notNumber.postfix && !notNumber.infix;\n\n // Check for syntax errors:\n if (bad || (afterValue ? notAfterValue : notNewValue)) {\n throw new PolishedError(37, match ? match.index : expression.length, expression);\n }\n if (afterValue) {\n // We either have an infix or postfix operator (they should be mutually exclusive)\n var curr = notNumber.postfix || notNumber.infix;\n do {\n var prev = operators[operators.length - 1];\n if ((curr.precedence - prev.precedence || prev.rightToLeft) > 0) break;\n // Apply previous operator, since it has precedence over current one\n } while (exec(operators, values)); // Exit loop after executing an opening parenthesis or function\n afterValue = curr.notation === 'postfix';\n if (curr.symbol !== ')') {\n operators.push(curr);\n // Postfix always has precedence over any operator that follows after it\n if (afterValue) exec(operators, values);\n }\n } else if (notNumber) {\n // prefix operator or function\n operators.push(notNumber.prefix || notNumber.func);\n if (notNumber.func) {\n // Require an opening parenthesis\n match = pattern.exec(expression);\n if (!match || match[0] !== '(') {\n throw new PolishedError(38, match ? match.index : expression.length, expression);\n }\n }\n } else {\n // number\n values.push(+token);\n afterValue = true;\n }\n } while (match && operators.length);\n if (operators.length) {\n throw new PolishedError(39, match ? match.index : expression.length, expression);\n } else if (match) {\n throw new PolishedError(40, match ? match.index : expression.length, expression);\n } else {\n return values.pop();\n }\n}\nfunction reverseString(str) {\n return str.split('').reverse().join('');\n}\n\n/**\n * Helper for doing math with CSS Units. Accepts a formula as a string. All values in the formula must have the same unit (or be unitless). Supports complex formulas utliziing addition, subtraction, multiplication, division, square root, powers, factorial, min, max, as well as parentheses for order of operation.\n *\n *In cases where you need to do calculations with mixed units where one unit is a [relative length unit](https://developer.mozilla.org/en-US/docs/Web/CSS/length#Relative_length_units), you will want to use [CSS Calc](https://developer.mozilla.org/en-US/docs/Web/CSS/calc).\n *\n * *warning* While we've done everything possible to ensure math safely evalutes formulas expressed as strings, you should always use extreme caution when passing `math` user provided values.\n * @example\n * // Styles as object usage\n * const styles = {\n * fontSize: math('12rem + 8rem'),\n * fontSize: math('(12px + 2px) * 3'),\n * fontSize: math('3px^2 + sqrt(4)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * fontSize: ${math('12rem + 8rem')};\n * fontSize: ${math('(12px + 2px) * 3')};\n * fontSize: ${math('3px^2 + sqrt(4)')};\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * fontSize: '20rem',\n * fontSize: '42px',\n * fontSize: '11px',\n * }\n */\nfunction math(formula, additionalSymbols) {\n var reversedFormula = reverseString(formula);\n var formulaMatch = reversedFormula.match(unitRegExp);\n\n // Check that all units are the same\n if (formulaMatch && !formulaMatch.every(function (unit) {\n return unit === formulaMatch[0];\n })) {\n throw new PolishedError(41);\n }\n var cleanFormula = reverseString(reversedFormula.replace(unitRegExp, ''));\n return \"\" + calculate(cleanFormula, additionalSymbols) + (formulaMatch ? reverseString(formulaMatch[0]) : '');\n}\n\nvar cssVariableRegex = /--[\\S]*/g;\n\n/**\n * Fetches the value of a passed CSS Variable in the :root scope, or otherwise returns a defaultValue if provided.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'background': cssVar('--background-color'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${cssVar('--background-color')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'background': 'red'\n * }\n */\nfunction cssVar(cssVariable, defaultValue) {\n if (!cssVariable || !cssVariable.match(cssVariableRegex)) {\n throw new PolishedError(73);\n }\n var variableValue;\n\n /* eslint-disable */\n /* istanbul ignore next */\n if (typeof document !== 'undefined' && document.documentElement !== null) {\n variableValue = getComputedStyle(document.documentElement).getPropertyValue(cssVariable);\n }\n /* eslint-enable */\n\n if (variableValue) {\n return variableValue.trim();\n } else if (defaultValue) {\n return defaultValue;\n }\n throw new PolishedError(74);\n}\n\n// @private\nfunction capitalizeString(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nvar positionMap$1 = ['Top', 'Right', 'Bottom', 'Left'];\nfunction generateProperty(property, position) {\n if (!property) return position.toLowerCase();\n var splitProperty = property.split('-');\n if (splitProperty.length > 1) {\n splitProperty.splice(1, 0, position);\n return splitProperty.reduce(function (acc, val) {\n return \"\" + acc + capitalizeString(val);\n });\n }\n var joinedProperty = property.replace(/([a-z])([A-Z])/g, \"$1\" + position + \"$2\");\n return property === joinedProperty ? \"\" + property + position : joinedProperty;\n}\nfunction generateStyles(property, valuesWithDefaults) {\n var styles = {};\n for (var i = 0; i < valuesWithDefaults.length; i += 1) {\n if (valuesWithDefaults[i] || valuesWithDefaults[i] === 0) {\n styles[generateProperty(property, positionMap$1[i])] = valuesWithDefaults[i];\n }\n }\n return styles;\n}\n\n/**\n * Enables shorthand for direction-based properties. It accepts a property (hyphenated or camelCased) and up to four values that map to top, right, bottom, and left, respectively. You can optionally pass an empty string to get only the directional values as properties. You can also optionally pass a null argument for a directional value to ignore it.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...directionalProperty('padding', '12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${directionalProperty('padding', '12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'paddingTop': '12px',\n * 'paddingRight': '24px',\n * 'paddingBottom': '36px',\n * 'paddingLeft': '48px'\n * }\n */\nfunction directionalProperty(property) {\n for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n values[_key - 1] = arguments[_key];\n }\n // prettier-ignore\n var firstValue = values[0],\n _values$ = values[1],\n secondValue = _values$ === void 0 ? firstValue : _values$,\n _values$2 = values[2],\n thirdValue = _values$2 === void 0 ? firstValue : _values$2,\n _values$3 = values[3],\n fourthValue = _values$3 === void 0 ? secondValue : _values$3;\n var valuesWithDefaults = [firstValue, secondValue, thirdValue, fourthValue];\n return generateStyles(property, valuesWithDefaults);\n}\n\n/**\n * Check if a string ends with something\n * @private\n */\nfunction endsWith(string, suffix) {\n return string.substr(-suffix.length) === suffix;\n}\n\nvar cssRegex$1 = /^([+-]?(?:\\d+|\\d*\\.\\d+))([a-z]*|%)$/;\n\n/**\n * Returns a given CSS value minus its unit of measure.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * '--dimension': stripUnit('100px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * --dimension: ${stripUnit('100px')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * '--dimension': 100\n * }\n */\nfunction stripUnit(value) {\n if (typeof value !== 'string') return value;\n var matchedValue = value.match(cssRegex$1);\n return matchedValue ? parseFloat(value) : value;\n}\n\n/**\n * Factory function that creates pixel-to-x converters\n * @private\n */\nvar pxtoFactory = function pxtoFactory(to) {\n return function (pxval, base) {\n if (base === void 0) {\n base = '16px';\n }\n var newPxval = pxval;\n var newBase = base;\n if (typeof pxval === 'string') {\n if (!endsWith(pxval, 'px')) {\n throw new PolishedError(69, to, pxval);\n }\n newPxval = stripUnit(pxval);\n }\n if (typeof base === 'string') {\n if (!endsWith(base, 'px')) {\n throw new PolishedError(70, to, base);\n }\n newBase = stripUnit(base);\n }\n if (typeof newPxval === 'string') {\n throw new PolishedError(71, pxval, to);\n }\n if (typeof newBase === 'string') {\n throw new PolishedError(72, base, to);\n }\n return \"\" + newPxval / newBase + to;\n };\n};\nvar pixelsto = pxtoFactory;\n\n/**\n * Convert pixel value to ems. The default base value is 16px, but can be changed by passing a\n * second argument to the function.\n * @function\n * @param {string|number} pxval\n * @param {string|number} [base='16px']\n * @example\n * // Styles as object usage\n * const styles = {\n * 'height': em('16px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * height: ${em('16px')}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'height': '1em'\n * }\n */\nvar em = pixelsto('em');\nvar em$1 = em;\n\nvar cssRegex = /^([+-]?(?:\\d+|\\d*\\.\\d+))([a-z]*|%)$/;\n\n/**\n * Returns a given CSS value and its unit as elements of an array.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * '--dimension': getValueAndUnit('100px')[0],\n * '--unit': getValueAndUnit('100px')[1],\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * --dimension: ${getValueAndUnit('100px')[0]};\n * --unit: ${getValueAndUnit('100px')[1]};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * '--dimension': 100,\n * '--unit': 'px',\n * }\n */\nfunction getValueAndUnit(value) {\n if (typeof value !== 'string') return [value, ''];\n var matchedValue = value.match(cssRegex);\n if (matchedValue) return [parseFloat(value), matchedValue[2]];\n return [value, undefined];\n}\n\n/**\n * Helper for targeting rules in a style block generated by polished modules that need !important-level specificity. Can optionally specify a rule (or rules) to target specific rules.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...important(cover())\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${important(cover())}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * 'position': 'absolute !important',\n * 'top': '0 !important',\n * 'right: '0 !important',\n * 'bottom': '0 !important',\n * 'left: '0 !important'\n * }\n */\nfunction important(styleBlock, rules) {\n if (typeof styleBlock !== 'object' || styleBlock === null) {\n throw new PolishedError(75, typeof styleBlock);\n }\n var newStyleBlock = {};\n Object.keys(styleBlock).forEach(function (key) {\n if (typeof styleBlock[key] === 'object' && styleBlock[key] !== null) {\n newStyleBlock[key] = important(styleBlock[key], rules);\n } else if (!rules || rules && (rules === key || rules.indexOf(key) >= 0)) {\n newStyleBlock[key] = styleBlock[key] + \" !important\";\n } else {\n newStyleBlock[key] = styleBlock[key];\n }\n });\n return newStyleBlock;\n}\n\nvar ratioNames = {\n minorSecond: 1.067,\n majorSecond: 1.125,\n minorThird: 1.2,\n majorThird: 1.25,\n perfectFourth: 1.333,\n augFourth: 1.414,\n perfectFifth: 1.5,\n minorSixth: 1.6,\n goldenSection: 1.618,\n majorSixth: 1.667,\n minorSeventh: 1.778,\n majorSeventh: 1.875,\n octave: 2,\n majorTenth: 2.5,\n majorEleventh: 2.667,\n majorTwelfth: 3,\n doubleOctave: 4\n};\nfunction getRatio(ratioName) {\n return ratioNames[ratioName];\n}\n\n/**\n * Establish consistent measurements and spacial relationships throughout your projects by incrementing an em or rem value up or down a defined scale. We provide a list of commonly used scales as pre-defined variables.\n * @example\n * // Styles as object usage\n * const styles = {\n * // Increment two steps up the default scale\n * 'fontSize': modularScale(2)\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * // Increment two steps up the default scale\n * fontSize: ${modularScale(2)}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'fontSize': '1.77689em'\n * }\n */\nfunction modularScale(steps, base, ratio) {\n if (base === void 0) {\n base = '1em';\n }\n if (ratio === void 0) {\n ratio = 1.333;\n }\n if (typeof steps !== 'number') {\n throw new PolishedError(42);\n }\n if (typeof ratio === 'string' && !ratioNames[ratio]) {\n throw new PolishedError(43);\n }\n var _ref = typeof base === 'string' ? getValueAndUnit(base) : [base, ''],\n realBase = _ref[0],\n unit = _ref[1];\n var realRatio = typeof ratio === 'string' ? getRatio(ratio) : ratio;\n if (typeof realBase === 'string') {\n throw new PolishedError(44, base);\n }\n return \"\" + realBase * Math.pow(realRatio, steps) + (unit || '');\n}\n\n/**\n * Convert pixel value to rems. The default base value is 16px, but can be changed by passing a\n * second argument to the function.\n * @function\n * @param {string|number} pxval\n * @param {string|number} [base='16px']\n * @example\n * // Styles as object usage\n * const styles = {\n * 'height': rem('16px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * height: ${rem('16px')}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'height': '1rem'\n * }\n */\nvar rem = pixelsto('rem');\nvar rem$1 = rem;\n\nvar defaultFontSize = 16;\nfunction convertBase(base) {\n var deconstructedValue = getValueAndUnit(base);\n if (deconstructedValue[1] === 'px') {\n return parseFloat(base);\n }\n if (deconstructedValue[1] === '%') {\n return parseFloat(base) / 100 * defaultFontSize;\n }\n throw new PolishedError(78, deconstructedValue[1]);\n}\nfunction getBaseFromDoc() {\n /* eslint-disable */\n /* istanbul ignore next */\n if (typeof document !== 'undefined' && document.documentElement !== null) {\n var rootFontSize = getComputedStyle(document.documentElement).fontSize;\n return rootFontSize ? convertBase(rootFontSize) : defaultFontSize;\n }\n /* eslint-enable */\n /* istanbul ignore next */\n return defaultFontSize;\n}\n\n/**\n * Convert rem values to px. By default, the base value is pulled from the font-size property on the root element (if it is set in % or px). It defaults to 16px if not found on the root. You can also override the base value by providing your own base in % or px.\n * @example\n * // Styles as object usage\n * const styles = {\n * 'height': remToPx('1.6rem')\n * 'height': remToPx('1.6rem', '10px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * height: ${remToPx('1.6rem')}\n * height: ${remToPx('1.6rem', '10px')}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'height': '25.6px',\n * 'height': '16px',\n * }\n */\nfunction remToPx(value, base) {\n var deconstructedValue = getValueAndUnit(value);\n if (deconstructedValue[1] !== 'rem' && deconstructedValue[1] !== '') {\n throw new PolishedError(77, deconstructedValue[1]);\n }\n var newBase = base ? convertBase(base) : getBaseFromDoc();\n return deconstructedValue[0] * newBase + \"px\";\n}\n\nvar functionsMap$3 = {\n back: 'cubic-bezier(0.600, -0.280, 0.735, 0.045)',\n circ: 'cubic-bezier(0.600, 0.040, 0.980, 0.335)',\n cubic: 'cubic-bezier(0.550, 0.055, 0.675, 0.190)',\n expo: 'cubic-bezier(0.950, 0.050, 0.795, 0.035)',\n quad: 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n quart: 'cubic-bezier(0.895, 0.030, 0.685, 0.220)',\n quint: 'cubic-bezier(0.755, 0.050, 0.855, 0.060)',\n sine: 'cubic-bezier(0.470, 0.000, 0.745, 0.715)'\n};\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': easeIn('quad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${easeIn('quad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n * }\n */\nfunction easeIn(functionName) {\n return functionsMap$3[functionName.toLowerCase().trim()];\n}\n\nvar functionsMap$2 = {\n back: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)',\n circ: 'cubic-bezier(0.785, 0.135, 0.150, 0.860)',\n cubic: 'cubic-bezier(0.645, 0.045, 0.355, 1.000)',\n expo: 'cubic-bezier(1.000, 0.000, 0.000, 1.000)',\n quad: 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',\n quart: 'cubic-bezier(0.770, 0.000, 0.175, 1.000)',\n quint: 'cubic-bezier(0.860, 0.000, 0.070, 1.000)',\n sine: 'cubic-bezier(0.445, 0.050, 0.550, 0.950)'\n};\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': easeInOut('quad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${easeInOut('quad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',\n * }\n */\nfunction easeInOut(functionName) {\n return functionsMap$2[functionName.toLowerCase().trim()];\n}\n\nvar functionsMap$1 = {\n back: 'cubic-bezier(0.175, 0.885, 0.320, 1.275)',\n cubic: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',\n circ: 'cubic-bezier(0.075, 0.820, 0.165, 1.000)',\n expo: 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',\n quad: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',\n quart: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)',\n quint: 'cubic-bezier(0.230, 1.000, 0.320, 1.000)',\n sine: 'cubic-bezier(0.390, 0.575, 0.565, 1.000)'\n};\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': easeOut('quad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${easeOut('quad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',\n * }\n */\nfunction easeOut(functionName) {\n return functionsMap$1[functionName.toLowerCase().trim()];\n}\n\n/**\n * Returns a CSS calc formula for linear interpolation of a property between two values. Accepts optional minScreen (defaults to '320px') and maxScreen (defaults to '1200px').\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * fontSize: between('20px', '100px', '400px', '1000px'),\n * fontSize: between('20px', '100px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * fontSize: ${between('20px', '100px', '400px', '1000px')};\n * fontSize: ${between('20px', '100px')}\n * `\n *\n * // CSS as JS Output\n *\n * h1: {\n * 'fontSize': 'calc(-33.33333333333334px + 13.333333333333334vw)',\n * 'fontSize': 'calc(-9.090909090909093px + 9.090909090909092vw)'\n * }\n */\nfunction between(fromSize, toSize, minScreen, maxScreen) {\n if (minScreen === void 0) {\n minScreen = '320px';\n }\n if (maxScreen === void 0) {\n maxScreen = '1200px';\n }\n var _getValueAndUnit = getValueAndUnit(fromSize),\n unitlessFromSize = _getValueAndUnit[0],\n fromSizeUnit = _getValueAndUnit[1];\n var _getValueAndUnit2 = getValueAndUnit(toSize),\n unitlessToSize = _getValueAndUnit2[0],\n toSizeUnit = _getValueAndUnit2[1];\n var _getValueAndUnit3 = getValueAndUnit(minScreen),\n unitlessMinScreen = _getValueAndUnit3[0],\n minScreenUnit = _getValueAndUnit3[1];\n var _getValueAndUnit4 = getValueAndUnit(maxScreen),\n unitlessMaxScreen = _getValueAndUnit4[0],\n maxScreenUnit = _getValueAndUnit4[1];\n if (typeof unitlessMinScreen !== 'number' || typeof unitlessMaxScreen !== 'number' || !minScreenUnit || !maxScreenUnit || minScreenUnit !== maxScreenUnit) {\n throw new PolishedError(47);\n }\n if (typeof unitlessFromSize !== 'number' || typeof unitlessToSize !== 'number' || fromSizeUnit !== toSizeUnit) {\n throw new PolishedError(48);\n }\n if (fromSizeUnit !== minScreenUnit || toSizeUnit !== maxScreenUnit) {\n throw new PolishedError(76);\n }\n var slope = (unitlessFromSize - unitlessToSize) / (unitlessMinScreen - unitlessMaxScreen);\n var base = unitlessToSize - slope * unitlessMaxScreen;\n return \"calc(\" + base.toFixed(2) + (fromSizeUnit || '') + \" + \" + (100 * slope).toFixed(2) + \"vw)\";\n}\n\n/**\n * CSS to contain a float (credit to CSSMojo).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...clearFix(),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${clearFix()}\n * `\n *\n * // CSS as JS Output\n *\n * '&::after': {\n * 'clear': 'both',\n * 'content': '\"\"',\n * 'display': 'table'\n * }\n */\nfunction clearFix(parent) {\n var _ref;\n if (parent === void 0) {\n parent = '&';\n }\n var pseudoSelector = parent + \"::after\";\n return _ref = {}, _ref[pseudoSelector] = {\n clear: 'both',\n content: '\"\"',\n display: 'table'\n }, _ref;\n}\n\n/**\n * CSS to fully cover an area. Can optionally be passed an offset to act as a \"padding\".\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...cover()\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${cover()}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * 'position': 'absolute',\n * 'top': '0',\n * 'right: '0',\n * 'bottom': '0',\n * 'left: '0'\n * }\n */\nfunction cover(offset) {\n if (offset === void 0) {\n offset = 0;\n }\n return {\n position: 'absolute',\n top: offset,\n right: offset,\n bottom: offset,\n left: offset\n };\n}\n\n/**\n * CSS to represent truncated text with an ellipsis. You can optionally pass a max-width and number of lines before truncating.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...ellipsis('250px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${ellipsis('250px')}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * 'display': 'inline-block',\n * 'maxWidth': '250px',\n * 'overflow': 'hidden',\n * 'textOverflow': 'ellipsis',\n * 'whiteSpace': 'nowrap',\n * 'wordWrap': 'normal'\n * }\n */\nfunction ellipsis(width, lines) {\n if (lines === void 0) {\n lines = 1;\n }\n var styles = {\n display: 'inline-block',\n maxWidth: width || '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n wordWrap: 'normal'\n };\n return lines > 1 ? _extends({}, styles, {\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: lines,\n display: '-webkit-box',\n whiteSpace: 'normal'\n }) : styles;\n}\n\nfunction _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\n/**\n * Returns a set of media queries that resizes a property (or set of properties) between a provided fromSize and toSize. Accepts optional minScreen (defaults to '320px') and maxScreen (defaults to '1200px') to constrain the interpolation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...fluidRange(\n * {\n * prop: 'padding',\n * fromSize: '20px',\n * toSize: '100px',\n * },\n * '400px',\n * '1000px',\n * )\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${fluidRange(\n * {\n * prop: 'padding',\n * fromSize: '20px',\n * toSize: '100px',\n * },\n * '400px',\n * '1000px',\n * )}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * \"@media (min-width: 1000px)\": Object {\n * \"padding\": \"100px\",\n * },\n * \"@media (min-width: 400px)\": Object {\n * \"padding\": \"calc(-33.33333333333334px + 13.333333333333334vw)\",\n * },\n * \"padding\": \"20px\",\n * }\n */\nfunction fluidRange(cssProp, minScreen, maxScreen) {\n if (minScreen === void 0) {\n minScreen = '320px';\n }\n if (maxScreen === void 0) {\n maxScreen = '1200px';\n }\n if (!Array.isArray(cssProp) && typeof cssProp !== 'object' || cssProp === null) {\n throw new PolishedError(49);\n }\n if (Array.isArray(cssProp)) {\n var mediaQueries = {};\n var fallbacks = {};\n for (var _iterator = _createForOfIteratorHelperLoose(cssProp), _step; !(_step = _iterator()).done;) {\n var _extends2, _extends3;\n var obj = _step.value;\n if (!obj.prop || !obj.fromSize || !obj.toSize) {\n throw new PolishedError(50);\n }\n fallbacks[obj.prop] = obj.fromSize;\n mediaQueries[\"@media (min-width: \" + minScreen + \")\"] = _extends({}, mediaQueries[\"@media (min-width: \" + minScreen + \")\"], (_extends2 = {}, _extends2[obj.prop] = between(obj.fromSize, obj.toSize, minScreen, maxScreen), _extends2));\n mediaQueries[\"@media (min-width: \" + maxScreen + \")\"] = _extends({}, mediaQueries[\"@media (min-width: \" + maxScreen + \")\"], (_extends3 = {}, _extends3[obj.prop] = obj.toSize, _extends3));\n }\n return _extends({}, fallbacks, mediaQueries);\n } else {\n var _ref, _ref2, _ref3;\n if (!cssProp.prop || !cssProp.fromSize || !cssProp.toSize) {\n throw new PolishedError(51);\n }\n return _ref3 = {}, _ref3[cssProp.prop] = cssProp.fromSize, _ref3[\"@media (min-width: \" + minScreen + \")\"] = (_ref = {}, _ref[cssProp.prop] = between(cssProp.fromSize, cssProp.toSize, minScreen, maxScreen), _ref), _ref3[\"@media (min-width: \" + maxScreen + \")\"] = (_ref2 = {}, _ref2[cssProp.prop] = cssProp.toSize, _ref2), _ref3;\n }\n}\n\nvar dataURIRegex = /^\\s*data:([a-z]+\\/[a-z-]+(;[a-z-]+=[a-z-]+)?)?(;charset=[a-z0-9-]+)?(;base64)?,[a-z0-9!$&',()*+,;=\\-._~:@/?%\\s]*\\s*$/i;\nvar formatHintMap = {\n woff: 'woff',\n woff2: 'woff2',\n ttf: 'truetype',\n otf: 'opentype',\n eot: 'embedded-opentype',\n svg: 'svg',\n svgz: 'svg'\n};\nfunction generateFormatHint(format, formatHint) {\n if (!formatHint) return '';\n return \" format(\\\"\" + formatHintMap[format] + \"\\\")\";\n}\nfunction isDataURI(fontFilePath) {\n return !!fontFilePath.replace(/\\s+/g, ' ').match(dataURIRegex);\n}\nfunction generateFileReferences(fontFilePath, fileFormats, formatHint) {\n if (isDataURI(fontFilePath)) {\n return \"url(\\\"\" + fontFilePath + \"\\\")\" + generateFormatHint(fileFormats[0], formatHint);\n }\n var fileFontReferences = fileFormats.map(function (format) {\n return \"url(\\\"\" + fontFilePath + \".\" + format + \"\\\")\" + generateFormatHint(format, formatHint);\n });\n return fileFontReferences.join(', ');\n}\nfunction generateLocalReferences(localFonts) {\n var localFontReferences = localFonts.map(function (font) {\n return \"local(\\\"\" + font + \"\\\")\";\n });\n return localFontReferences.join(', ');\n}\nfunction generateSources(fontFilePath, localFonts, fileFormats, formatHint) {\n var fontReferences = [];\n if (localFonts) fontReferences.push(generateLocalReferences(localFonts));\n if (fontFilePath) {\n fontReferences.push(generateFileReferences(fontFilePath, fileFormats, formatHint));\n }\n return fontReferences.join(', ');\n}\n\n/**\n * CSS for a @font-face declaration. Defaults to check for local copies of the font on the user's machine. You can disable this by passing `null` to localFonts.\n *\n * @example\n * // Styles as object basic usage\n * const styles = {\n * ...fontFace({\n * 'fontFamily': 'Sans-Pro',\n * 'fontFilePath': 'path/to/file'\n * })\n * }\n *\n * // styled-components basic usage\n * const GlobalStyle = createGlobalStyle`${\n * fontFace({\n * 'fontFamily': 'Sans-Pro',\n * 'fontFilePath': 'path/to/file'\n * }\n * )}`\n *\n * // CSS as JS Output\n *\n * '@font-face': {\n * 'fontFamily': 'Sans-Pro',\n * 'src': 'url(\"path/to/file.eot\"), url(\"path/to/file.woff2\"), url(\"path/to/file.woff\"), url(\"path/to/file.ttf\"), url(\"path/to/file.svg\")',\n * }\n */\n\nfunction fontFace(_ref) {\n var fontFamily = _ref.fontFamily,\n fontFilePath = _ref.fontFilePath,\n fontStretch = _ref.fontStretch,\n fontStyle = _ref.fontStyle,\n fontVariant = _ref.fontVariant,\n fontWeight = _ref.fontWeight,\n _ref$fileFormats = _ref.fileFormats,\n fileFormats = _ref$fileFormats === void 0 ? ['eot', 'woff2', 'woff', 'ttf', 'svg'] : _ref$fileFormats,\n _ref$formatHint = _ref.formatHint,\n formatHint = _ref$formatHint === void 0 ? false : _ref$formatHint,\n _ref$localFonts = _ref.localFonts,\n localFonts = _ref$localFonts === void 0 ? [fontFamily] : _ref$localFonts,\n unicodeRange = _ref.unicodeRange,\n fontDisplay = _ref.fontDisplay,\n fontVariationSettings = _ref.fontVariationSettings,\n fontFeatureSettings = _ref.fontFeatureSettings;\n // Error Handling\n if (!fontFamily) throw new PolishedError(55);\n if (!fontFilePath && !localFonts) {\n throw new PolishedError(52);\n }\n if (localFonts && !Array.isArray(localFonts)) {\n throw new PolishedError(53);\n }\n if (!Array.isArray(fileFormats)) {\n throw new PolishedError(54);\n }\n var fontFaceDeclaration = {\n '@font-face': {\n fontFamily: fontFamily,\n src: generateSources(fontFilePath, localFonts, fileFormats, formatHint),\n unicodeRange: unicodeRange,\n fontStretch: fontStretch,\n fontStyle: fontStyle,\n fontVariant: fontVariant,\n fontWeight: fontWeight,\n fontDisplay: fontDisplay,\n fontVariationSettings: fontVariationSettings,\n fontFeatureSettings: fontFeatureSettings\n }\n };\n\n // Removes undefined fields for cleaner css object.\n return JSON.parse(JSON.stringify(fontFaceDeclaration));\n}\n\n/**\n * CSS to hide text to show a background image in a SEO-friendly way.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'backgroundImage': 'url(logo.png)',\n * ...hideText(),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * backgroundImage: url(logo.png);\n * ${hideText()};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'backgroundImage': 'url(logo.png)',\n * 'textIndent': '101%',\n * 'overflow': 'hidden',\n * 'whiteSpace': 'nowrap',\n * }\n */\nfunction hideText() {\n return {\n textIndent: '101%',\n overflow: 'hidden',\n whiteSpace: 'nowrap'\n };\n}\n\n/**\n * CSS to hide content visually but remain accessible to screen readers.\n * from [HTML5 Boilerplate](https://github.com/h5bp/html5-boilerplate/blob/9a176f57af1cfe8ec70300da4621fb9b07e5fa31/src/css/main.css#L121)\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...hideVisually(),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${hideVisually()};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'border': '0',\n * 'clip': 'rect(0 0 0 0)',\n * 'height': '1px',\n * 'margin': '-1px',\n * 'overflow': 'hidden',\n * 'padding': '0',\n * 'position': 'absolute',\n * 'whiteSpace': 'nowrap',\n * 'width': '1px',\n * }\n */\nfunction hideVisually() {\n return {\n border: '0',\n clip: 'rect(0 0 0 0)',\n height: '1px',\n margin: '-1px',\n overflow: 'hidden',\n padding: '0',\n position: 'absolute',\n whiteSpace: 'nowrap',\n width: '1px'\n };\n}\n\n/**\n * Generates a media query to target HiDPI devices.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * [hiDPI(1.5)]: {\n * width: 200px;\n * }\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${hiDPI(1.5)} {\n * width: 200px;\n * }\n * `\n *\n * // CSS as JS Output\n *\n * '@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n * only screen and (min--moz-device-pixel-ratio: 1.5),\n * only screen and (-o-min-device-pixel-ratio: 1.5/1),\n * only screen and (min-resolution: 144dpi),\n * only screen and (min-resolution: 1.5dppx)': {\n * 'width': '200px',\n * }\n */\nfunction hiDPI(ratio) {\n if (ratio === void 0) {\n ratio = 1.3;\n }\n return \"\\n @media only screen and (-webkit-min-device-pixel-ratio: \" + ratio + \"),\\n only screen and (min--moz-device-pixel-ratio: \" + ratio + \"),\\n only screen and (-o-min-device-pixel-ratio: \" + ratio + \"/1),\\n only screen and (min-resolution: \" + Math.round(ratio * 96) + \"dpi),\\n only screen and (min-resolution: \" + ratio + \"dppx)\\n \";\n}\n\nfunction constructGradientValue(literals) {\n var template = '';\n for (var _len = arguments.length, substitutions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n substitutions[_key - 1] = arguments[_key];\n }\n for (var i = 0; i < literals.length; i += 1) {\n template += literals[i];\n if (i === substitutions.length - 1 && substitutions[i]) {\n var definedValues = substitutions.filter(function (substitute) {\n return !!substitute;\n });\n // Adds leading coma if properties preceed color-stops\n if (definedValues.length > 1) {\n template = template.slice(0, -1);\n template += \", \" + substitutions[i];\n // No trailing space if color-stops is the only param provided\n } else if (definedValues.length === 1) {\n template += \"\" + substitutions[i];\n }\n } else if (substitutions[i]) {\n template += substitutions[i] + \" \";\n }\n }\n return template.trim();\n}\n\nvar _templateObject$1;\n/**\n * CSS for declaring a linear gradient, including a fallback background-color. The fallback is either the first color-stop or an explicitly passed fallback color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...linearGradient({\n colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n toDirection: 'to top right',\n fallback: '#FFF',\n })\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${linearGradient({\n colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n toDirection: 'to top right',\n fallback: '#FFF',\n })}\n *`\n *\n * // CSS as JS Output\n *\n * div: {\n * 'backgroundColor': '#FFF',\n * 'backgroundImage': 'linear-gradient(to top right, #00FFFF 0%, rgba(0, 0, 255, 0) 50%, #0000FF 95%)',\n * }\n */\nfunction linearGradient(_ref) {\n var colorStops = _ref.colorStops,\n fallback = _ref.fallback,\n _ref$toDirection = _ref.toDirection,\n toDirection = _ref$toDirection === void 0 ? '' : _ref$toDirection;\n if (!colorStops || colorStops.length < 2) {\n throw new PolishedError(56);\n }\n return {\n backgroundColor: fallback || colorStops[0].replace(/,\\s+/g, ',').split(' ')[0].replace(/,(?=\\S)/g, ', '),\n backgroundImage: constructGradientValue(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteralLoose([\"linear-gradient(\", \"\", \")\"])), toDirection, colorStops.join(', ').replace(/,(?=\\S)/g, ', '))\n };\n}\n\n/**\n * CSS to normalize abnormalities across browsers (normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css)\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...normalize(),\n * }\n *\n * // styled-components usage\n * const GlobalStyle = createGlobalStyle`${normalize()}`\n *\n * // CSS as JS Output\n *\n * html {\n * lineHeight: 1.15,\n * textSizeAdjust: 100%,\n * } ...\n */\nfunction normalize() {\n var _ref;\n return [(_ref = {\n html: {\n lineHeight: '1.15',\n textSizeAdjust: '100%'\n },\n body: {\n margin: '0'\n },\n main: {\n display: 'block'\n },\n h1: {\n fontSize: '2em',\n margin: '0.67em 0'\n },\n hr: {\n boxSizing: 'content-box',\n height: '0',\n overflow: 'visible'\n },\n pre: {\n fontFamily: 'monospace, monospace',\n fontSize: '1em'\n },\n a: {\n backgroundColor: 'transparent'\n },\n 'abbr[title]': {\n borderBottom: 'none',\n textDecoration: 'underline'\n }\n }, _ref[\"b,\\n strong\"] = {\n fontWeight: 'bolder'\n }, _ref[\"code,\\n kbd,\\n samp\"] = {\n fontFamily: 'monospace, monospace',\n fontSize: '1em'\n }, _ref.small = {\n fontSize: '80%'\n }, _ref[\"sub,\\n sup\"] = {\n fontSize: '75%',\n lineHeight: '0',\n position: 'relative',\n verticalAlign: 'baseline'\n }, _ref.sub = {\n bottom: '-0.25em'\n }, _ref.sup = {\n top: '-0.5em'\n }, _ref.img = {\n borderStyle: 'none'\n }, _ref[\"button,\\n input,\\n optgroup,\\n select,\\n textarea\"] = {\n fontFamily: 'inherit',\n fontSize: '100%',\n lineHeight: '1.15',\n margin: '0'\n }, _ref[\"button,\\n input\"] = {\n overflow: 'visible'\n }, _ref[\"button,\\n select\"] = {\n textTransform: 'none'\n }, _ref[\"button,\\n html [type=\\\"button\\\"],\\n [type=\\\"reset\\\"],\\n [type=\\\"submit\\\"]\"] = {\n WebkitAppearance: 'button'\n }, _ref[\"button::-moz-focus-inner,\\n [type=\\\"button\\\"]::-moz-focus-inner,\\n [type=\\\"reset\\\"]::-moz-focus-inner,\\n [type=\\\"submit\\\"]::-moz-focus-inner\"] = {\n borderStyle: 'none',\n padding: '0'\n }, _ref[\"button:-moz-focusring,\\n [type=\\\"button\\\"]:-moz-focusring,\\n [type=\\\"reset\\\"]:-moz-focusring,\\n [type=\\\"submit\\\"]:-moz-focusring\"] = {\n outline: '1px dotted ButtonText'\n }, _ref.fieldset = {\n padding: '0.35em 0.625em 0.75em'\n }, _ref.legend = {\n boxSizing: 'border-box',\n color: 'inherit',\n display: 'table',\n maxWidth: '100%',\n padding: '0',\n whiteSpace: 'normal'\n }, _ref.progress = {\n verticalAlign: 'baseline'\n }, _ref.textarea = {\n overflow: 'auto'\n }, _ref[\"[type=\\\"checkbox\\\"],\\n [type=\\\"radio\\\"]\"] = {\n boxSizing: 'border-box',\n padding: '0'\n }, _ref[\"[type=\\\"number\\\"]::-webkit-inner-spin-button,\\n [type=\\\"number\\\"]::-webkit-outer-spin-button\"] = {\n height: 'auto'\n }, _ref['[type=\"search\"]'] = {\n WebkitAppearance: 'textfield',\n outlineOffset: '-2px'\n }, _ref['[type=\"search\"]::-webkit-search-decoration'] = {\n WebkitAppearance: 'none'\n }, _ref['::-webkit-file-upload-button'] = {\n WebkitAppearance: 'button',\n font: 'inherit'\n }, _ref.details = {\n display: 'block'\n }, _ref.summary = {\n display: 'list-item'\n }, _ref.template = {\n display: 'none'\n }, _ref['[hidden]'] = {\n display: 'none'\n }, _ref), {\n 'abbr[title]': {\n textDecoration: 'underline dotted'\n }\n }];\n}\n\nvar _templateObject;\n/**\n * CSS for declaring a radial gradient, including a fallback background-color. The fallback is either the first color-stop or an explicitly passed fallback color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...radialGradient({\n * colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n * extent: 'farthest-corner at 45px 45px',\n * position: 'center',\n * shape: 'ellipse',\n * })\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${radialGradient({\n * colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n * extent: 'farthest-corner at 45px 45px',\n * position: 'center',\n * shape: 'ellipse',\n * })}\n *`\n *\n * // CSS as JS Output\n *\n * div: {\n * 'backgroundColor': '#00FFFF',\n * 'backgroundImage': 'radial-gradient(center ellipse farthest-corner at 45px 45px, #00FFFF 0%, rgba(0, 0, 255, 0) 50%, #0000FF 95%)',\n * }\n */\nfunction radialGradient(_ref) {\n var colorStops = _ref.colorStops,\n _ref$extent = _ref.extent,\n extent = _ref$extent === void 0 ? '' : _ref$extent,\n fallback = _ref.fallback,\n _ref$position = _ref.position,\n position = _ref$position === void 0 ? '' : _ref$position,\n _ref$shape = _ref.shape,\n shape = _ref$shape === void 0 ? '' : _ref$shape;\n if (!colorStops || colorStops.length < 2) {\n throw new PolishedError(57);\n }\n return {\n backgroundColor: fallback || colorStops[0].split(' ')[0],\n backgroundImage: constructGradientValue(_templateObject || (_templateObject = _taggedTemplateLiteralLoose([\"radial-gradient(\", \"\", \"\", \"\", \")\"])), position, shape, extent, colorStops.join(', '))\n };\n}\n\n/**\n * A helper to generate a retina background image and non-retina\n * background image. The retina background image will output to a HiDPI media query. The mixin uses\n * a _2x.png filename suffix by default.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...retinaImage('my-img')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${retinaImage('my-img')}\n * `\n *\n * // CSS as JS Output\n * div {\n * backgroundImage: 'url(my-img.png)',\n * '@media only screen and (-webkit-min-device-pixel-ratio: 1.3),\n * only screen and (min--moz-device-pixel-ratio: 1.3),\n * only screen and (-o-min-device-pixel-ratio: 1.3/1),\n * only screen and (min-resolution: 144dpi),\n * only screen and (min-resolution: 1.5dppx)': {\n * backgroundImage: 'url(my-img_2x.png)',\n * }\n * }\n */\nfunction retinaImage(filename, backgroundSize, extension, retinaFilename, retinaSuffix) {\n var _ref;\n if (extension === void 0) {\n extension = 'png';\n }\n if (retinaSuffix === void 0) {\n retinaSuffix = '_2x';\n }\n if (!filename) {\n throw new PolishedError(58);\n }\n // Replace the dot at the beginning of the passed extension if one exists\n var ext = extension.replace(/^\\./, '');\n var rFilename = retinaFilename ? retinaFilename + \".\" + ext : \"\" + filename + retinaSuffix + \".\" + ext;\n return _ref = {\n backgroundImage: \"url(\" + filename + \".\" + ext + \")\"\n }, _ref[hiDPI()] = _extends({\n backgroundImage: \"url(\" + rFilename + \")\"\n }, backgroundSize ? {\n backgroundSize: backgroundSize\n } : {}), _ref;\n}\n\n/* eslint-disable key-spacing */\nvar functionsMap = {\n easeInBack: 'cubic-bezier(0.600, -0.280, 0.735, 0.045)',\n easeInCirc: 'cubic-bezier(0.600, 0.040, 0.980, 0.335)',\n easeInCubic: 'cubic-bezier(0.550, 0.055, 0.675, 0.190)',\n easeInExpo: 'cubic-bezier(0.950, 0.050, 0.795, 0.035)',\n easeInQuad: 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n easeInQuart: 'cubic-bezier(0.895, 0.030, 0.685, 0.220)',\n easeInQuint: 'cubic-bezier(0.755, 0.050, 0.855, 0.060)',\n easeInSine: 'cubic-bezier(0.470, 0.000, 0.745, 0.715)',\n easeOutBack: 'cubic-bezier(0.175, 0.885, 0.320, 1.275)',\n easeOutCubic: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',\n easeOutCirc: 'cubic-bezier(0.075, 0.820, 0.165, 1.000)',\n easeOutExpo: 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',\n easeOutQuad: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',\n easeOutQuart: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)',\n easeOutQuint: 'cubic-bezier(0.230, 1.000, 0.320, 1.000)',\n easeOutSine: 'cubic-bezier(0.390, 0.575, 0.565, 1.000)',\n easeInOutBack: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)',\n easeInOutCirc: 'cubic-bezier(0.785, 0.135, 0.150, 0.860)',\n easeInOutCubic: 'cubic-bezier(0.645, 0.045, 0.355, 1.000)',\n easeInOutExpo: 'cubic-bezier(1.000, 0.000, 0.000, 1.000)',\n easeInOutQuad: 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',\n easeInOutQuart: 'cubic-bezier(0.770, 0.000, 0.175, 1.000)',\n easeInOutQuint: 'cubic-bezier(0.860, 0.000, 0.070, 1.000)',\n easeInOutSine: 'cubic-bezier(0.445, 0.050, 0.550, 0.950)'\n};\n/* eslint-enable key-spacing */\n\nfunction getTimingFunction(functionName) {\n return functionsMap[functionName];\n}\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @deprecated - This will be deprecated in v5 in favor of `easeIn`, `easeOut`, `easeInOut`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': timingFunctions('easeInQuad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${timingFunctions('easeInQuad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n * }\n */\n\nfunction timingFunctions(timingFunction) {\n return getTimingFunction(timingFunction);\n}\n\nvar getBorderWidth = function getBorderWidth(pointingDirection, height, width) {\n var fullWidth = \"\" + width[0] + (width[1] || '');\n var halfWidth = \"\" + width[0] / 2 + (width[1] || '');\n var fullHeight = \"\" + height[0] + (height[1] || '');\n var halfHeight = \"\" + height[0] / 2 + (height[1] || '');\n switch (pointingDirection) {\n case 'top':\n return \"0 \" + halfWidth + \" \" + fullHeight + \" \" + halfWidth;\n case 'topLeft':\n return fullWidth + \" \" + fullHeight + \" 0 0\";\n case 'left':\n return halfHeight + \" \" + fullWidth + \" \" + halfHeight + \" 0\";\n case 'bottomLeft':\n return fullWidth + \" 0 0 \" + fullHeight;\n case 'bottom':\n return fullHeight + \" \" + halfWidth + \" 0 \" + halfWidth;\n case 'bottomRight':\n return \"0 0 \" + fullWidth + \" \" + fullHeight;\n case 'right':\n return halfHeight + \" 0 \" + halfHeight + \" \" + fullWidth;\n case 'topRight':\n default:\n return \"0 \" + fullWidth + \" \" + fullHeight + \" 0\";\n }\n};\nvar getBorderColor = function getBorderColor(pointingDirection, foregroundColor) {\n switch (pointingDirection) {\n case 'top':\n case 'bottomRight':\n return {\n borderBottomColor: foregroundColor\n };\n case 'right':\n case 'bottomLeft':\n return {\n borderLeftColor: foregroundColor\n };\n case 'bottom':\n case 'topLeft':\n return {\n borderTopColor: foregroundColor\n };\n case 'left':\n case 'topRight':\n return {\n borderRightColor: foregroundColor\n };\n default:\n throw new PolishedError(59);\n }\n};\n\n/**\n * CSS to represent triangle with any pointing direction with an optional background color.\n *\n * @example\n * // Styles as object usage\n *\n * const styles = {\n * ...triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' })\n * }\n *\n *\n * // styled-components usage\n * const div = styled.div`\n * ${triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' })}\n *\n *\n * // CSS as JS Output\n *\n * div: {\n * 'borderColor': 'transparent transparent transparent red',\n * 'borderStyle': 'solid',\n * 'borderWidth': '50px 0 50px 100px',\n * 'height': '0',\n * 'width': '0',\n * }\n */\nfunction triangle(_ref) {\n var pointingDirection = _ref.pointingDirection,\n height = _ref.height,\n width = _ref.width,\n foregroundColor = _ref.foregroundColor,\n _ref$backgroundColor = _ref.backgroundColor,\n backgroundColor = _ref$backgroundColor === void 0 ? 'transparent' : _ref$backgroundColor;\n var widthAndUnit = getValueAndUnit(width);\n var heightAndUnit = getValueAndUnit(height);\n if (isNaN(heightAndUnit[0]) || isNaN(widthAndUnit[0])) {\n throw new PolishedError(60);\n }\n return _extends({\n width: '0',\n height: '0',\n borderColor: backgroundColor\n }, getBorderColor(pointingDirection, foregroundColor), {\n borderStyle: 'solid',\n borderWidth: getBorderWidth(pointingDirection, heightAndUnit, widthAndUnit)\n });\n}\n\n/**\n * Provides an easy way to change the `wordWrap` property.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...wordWrap('break-word')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${wordWrap('break-word')}\n * `\n *\n * // CSS as JS Output\n *\n * const styles = {\n * overflowWrap: 'break-word',\n * wordWrap: 'break-word',\n * wordBreak: 'break-all',\n * }\n */\nfunction wordWrap(wrap) {\n if (wrap === void 0) {\n wrap = 'break-word';\n }\n var wordBreak = wrap === 'break-word' ? 'break-all' : wrap;\n return {\n overflowWrap: wrap,\n wordWrap: wrap,\n wordBreak: wordBreak\n };\n}\n\nfunction colorToInt(color) {\n return Math.round(color * 255);\n}\nfunction convertToInt(red, green, blue) {\n return colorToInt(red) + \",\" + colorToInt(green) + \",\" + colorToInt(blue);\n}\nfunction hslToRgb(hue, saturation, lightness, convert) {\n if (convert === void 0) {\n convert = convertToInt;\n }\n if (saturation === 0) {\n // achromatic\n return convert(lightness, lightness, lightness);\n }\n\n // formulae from https://en.wikipedia.org/wiki/HSL_and_HSV\n var huePrime = (hue % 360 + 360) % 360 / 60;\n var chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;\n var secondComponent = chroma * (1 - Math.abs(huePrime % 2 - 1));\n var red = 0;\n var green = 0;\n var blue = 0;\n if (huePrime >= 0 && huePrime < 1) {\n red = chroma;\n green = secondComponent;\n } else if (huePrime >= 1 && huePrime < 2) {\n red = secondComponent;\n green = chroma;\n } else if (huePrime >= 2 && huePrime < 3) {\n green = chroma;\n blue = secondComponent;\n } else if (huePrime >= 3 && huePrime < 4) {\n green = secondComponent;\n blue = chroma;\n } else if (huePrime >= 4 && huePrime < 5) {\n red = secondComponent;\n blue = chroma;\n } else if (huePrime >= 5 && huePrime < 6) {\n red = chroma;\n blue = secondComponent;\n }\n var lightnessModification = lightness - chroma / 2;\n var finalRed = red + lightnessModification;\n var finalGreen = green + lightnessModification;\n var finalBlue = blue + lightnessModification;\n return convert(finalRed, finalGreen, finalBlue);\n}\n\nvar namedColorMap = {\n aliceblue: 'f0f8ff',\n antiquewhite: 'faebd7',\n aqua: '00ffff',\n aquamarine: '7fffd4',\n azure: 'f0ffff',\n beige: 'f5f5dc',\n bisque: 'ffe4c4',\n black: '000',\n blanchedalmond: 'ffebcd',\n blue: '0000ff',\n blueviolet: '8a2be2',\n brown: 'a52a2a',\n burlywood: 'deb887',\n cadetblue: '5f9ea0',\n chartreuse: '7fff00',\n chocolate: 'd2691e',\n coral: 'ff7f50',\n cornflowerblue: '6495ed',\n cornsilk: 'fff8dc',\n crimson: 'dc143c',\n cyan: '00ffff',\n darkblue: '00008b',\n darkcyan: '008b8b',\n darkgoldenrod: 'b8860b',\n darkgray: 'a9a9a9',\n darkgreen: '006400',\n darkgrey: 'a9a9a9',\n darkkhaki: 'bdb76b',\n darkmagenta: '8b008b',\n darkolivegreen: '556b2f',\n darkorange: 'ff8c00',\n darkorchid: '9932cc',\n darkred: '8b0000',\n darksalmon: 'e9967a',\n darkseagreen: '8fbc8f',\n darkslateblue: '483d8b',\n darkslategray: '2f4f4f',\n darkslategrey: '2f4f4f',\n darkturquoise: '00ced1',\n darkviolet: '9400d3',\n deeppink: 'ff1493',\n deepskyblue: '00bfff',\n dimgray: '696969',\n dimgrey: '696969',\n dodgerblue: '1e90ff',\n firebrick: 'b22222',\n floralwhite: 'fffaf0',\n forestgreen: '228b22',\n fuchsia: 'ff00ff',\n gainsboro: 'dcdcdc',\n ghostwhite: 'f8f8ff',\n gold: 'ffd700',\n goldenrod: 'daa520',\n gray: '808080',\n green: '008000',\n greenyellow: 'adff2f',\n grey: '808080',\n honeydew: 'f0fff0',\n hotpink: 'ff69b4',\n indianred: 'cd5c5c',\n indigo: '4b0082',\n ivory: 'fffff0',\n khaki: 'f0e68c',\n lavender: 'e6e6fa',\n lavenderblush: 'fff0f5',\n lawngreen: '7cfc00',\n lemonchiffon: 'fffacd',\n lightblue: 'add8e6',\n lightcoral: 'f08080',\n lightcyan: 'e0ffff',\n lightgoldenrodyellow: 'fafad2',\n lightgray: 'd3d3d3',\n lightgreen: '90ee90',\n lightgrey: 'd3d3d3',\n lightpink: 'ffb6c1',\n lightsalmon: 'ffa07a',\n lightseagreen: '20b2aa',\n lightskyblue: '87cefa',\n lightslategray: '789',\n lightslategrey: '789',\n lightsteelblue: 'b0c4de',\n lightyellow: 'ffffe0',\n lime: '0f0',\n limegreen: '32cd32',\n linen: 'faf0e6',\n magenta: 'f0f',\n maroon: '800000',\n mediumaquamarine: '66cdaa',\n mediumblue: '0000cd',\n mediumorchid: 'ba55d3',\n mediumpurple: '9370db',\n mediumseagreen: '3cb371',\n mediumslateblue: '7b68ee',\n mediumspringgreen: '00fa9a',\n mediumturquoise: '48d1cc',\n mediumvioletred: 'c71585',\n midnightblue: '191970',\n mintcream: 'f5fffa',\n mistyrose: 'ffe4e1',\n moccasin: 'ffe4b5',\n navajowhite: 'ffdead',\n navy: '000080',\n oldlace: 'fdf5e6',\n olive: '808000',\n olivedrab: '6b8e23',\n orange: 'ffa500',\n orangered: 'ff4500',\n orchid: 'da70d6',\n palegoldenrod: 'eee8aa',\n palegreen: '98fb98',\n paleturquoise: 'afeeee',\n palevioletred: 'db7093',\n papayawhip: 'ffefd5',\n peachpuff: 'ffdab9',\n peru: 'cd853f',\n pink: 'ffc0cb',\n plum: 'dda0dd',\n powderblue: 'b0e0e6',\n purple: '800080',\n rebeccapurple: '639',\n red: 'f00',\n rosybrown: 'bc8f8f',\n royalblue: '4169e1',\n saddlebrown: '8b4513',\n salmon: 'fa8072',\n sandybrown: 'f4a460',\n seagreen: '2e8b57',\n seashell: 'fff5ee',\n sienna: 'a0522d',\n silver: 'c0c0c0',\n skyblue: '87ceeb',\n slateblue: '6a5acd',\n slategray: '708090',\n slategrey: '708090',\n snow: 'fffafa',\n springgreen: '00ff7f',\n steelblue: '4682b4',\n tan: 'd2b48c',\n teal: '008080',\n thistle: 'd8bfd8',\n tomato: 'ff6347',\n turquoise: '40e0d0',\n violet: 'ee82ee',\n wheat: 'f5deb3',\n white: 'fff',\n whitesmoke: 'f5f5f5',\n yellow: 'ff0',\n yellowgreen: '9acd32'\n};\n\n/**\n * Checks if a string is a CSS named color and returns its equivalent hex value, otherwise returns the original color.\n * @private\n */\nfunction nameToHex(color) {\n if (typeof color !== 'string') return color;\n var normalizedColorName = color.toLowerCase();\n return namedColorMap[normalizedColorName] ? \"#\" + namedColorMap[normalizedColorName] : color;\n}\n\nvar hexRegex = /^#[a-fA-F0-9]{6}$/;\nvar hexRgbaRegex = /^#[a-fA-F0-9]{8}$/;\nvar reducedHexRegex = /^#[a-fA-F0-9]{3}$/;\nvar reducedRgbaHexRegex = /^#[a-fA-F0-9]{4}$/;\nvar rgbRegex = /^rgb\\(\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*\\)$/i;\nvar rgbaRegex = /^rgb(?:a)?\\(\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*(?:,|\\/)\\s*([-+]?\\d*[.]?\\d+[%]?)\\s*\\)$/i;\nvar hslRegex = /^hsl\\(\\s*(\\d{0,3}[.]?[0-9]+(?:deg)?)\\s*(?:,)?\\s*(\\d{1,3}[.]?[0-9]?)%\\s*(?:,)?\\s*(\\d{1,3}[.]?[0-9]?)%\\s*\\)$/i;\nvar hslaRegex = /^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;\n\n/**\n * Returns an RgbColor or RgbaColor object. This utility function is only useful\n * if want to extract a color component. With the color util `toColorString` you\n * can convert a RgbColor or RgbaColor object back to a string.\n *\n * @example\n * // Assigns `{ red: 255, green: 0, blue: 0 }` to color1\n * const color1 = parseToRgb('rgb(255, 0, 0)');\n * // Assigns `{ red: 92, green: 102, blue: 112, alpha: 0.75 }` to color2\n * const color2 = parseToRgb('hsla(210, 10%, 40%, 0.75)');\n */\nfunction parseToRgb(color) {\n if (typeof color !== 'string') {\n throw new PolishedError(3);\n }\n var normalizedColor = nameToHex(color);\n if (normalizedColor.match(hexRegex)) {\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[2], 16),\n green: parseInt(\"\" + normalizedColor[3] + normalizedColor[4], 16),\n blue: parseInt(\"\" + normalizedColor[5] + normalizedColor[6], 16)\n };\n }\n if (normalizedColor.match(hexRgbaRegex)) {\n var alpha = parseFloat((parseInt(\"\" + normalizedColor[7] + normalizedColor[8], 16) / 255).toFixed(2));\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[2], 16),\n green: parseInt(\"\" + normalizedColor[3] + normalizedColor[4], 16),\n blue: parseInt(\"\" + normalizedColor[5] + normalizedColor[6], 16),\n alpha: alpha\n };\n }\n if (normalizedColor.match(reducedHexRegex)) {\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[1], 16),\n green: parseInt(\"\" + normalizedColor[2] + normalizedColor[2], 16),\n blue: parseInt(\"\" + normalizedColor[3] + normalizedColor[3], 16)\n };\n }\n if (normalizedColor.match(reducedRgbaHexRegex)) {\n var _alpha = parseFloat((parseInt(\"\" + normalizedColor[4] + normalizedColor[4], 16) / 255).toFixed(2));\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[1], 16),\n green: parseInt(\"\" + normalizedColor[2] + normalizedColor[2], 16),\n blue: parseInt(\"\" + normalizedColor[3] + normalizedColor[3], 16),\n alpha: _alpha\n };\n }\n var rgbMatched = rgbRegex.exec(normalizedColor);\n if (rgbMatched) {\n return {\n red: parseInt(\"\" + rgbMatched[1], 10),\n green: parseInt(\"\" + rgbMatched[2], 10),\n blue: parseInt(\"\" + rgbMatched[3], 10)\n };\n }\n var rgbaMatched = rgbaRegex.exec(normalizedColor.substring(0, 50));\n if (rgbaMatched) {\n return {\n red: parseInt(\"\" + rgbaMatched[1], 10),\n green: parseInt(\"\" + rgbaMatched[2], 10),\n blue: parseInt(\"\" + rgbaMatched[3], 10),\n alpha: parseFloat(\"\" + rgbaMatched[4]) > 1 ? parseFloat(\"\" + rgbaMatched[4]) / 100 : parseFloat(\"\" + rgbaMatched[4])\n };\n }\n var hslMatched = hslRegex.exec(normalizedColor);\n if (hslMatched) {\n var hue = parseInt(\"\" + hslMatched[1], 10);\n var saturation = parseInt(\"\" + hslMatched[2], 10) / 100;\n var lightness = parseInt(\"\" + hslMatched[3], 10) / 100;\n var rgbColorString = \"rgb(\" + hslToRgb(hue, saturation, lightness) + \")\";\n var hslRgbMatched = rgbRegex.exec(rgbColorString);\n if (!hslRgbMatched) {\n throw new PolishedError(4, normalizedColor, rgbColorString);\n }\n return {\n red: parseInt(\"\" + hslRgbMatched[1], 10),\n green: parseInt(\"\" + hslRgbMatched[2], 10),\n blue: parseInt(\"\" + hslRgbMatched[3], 10)\n };\n }\n var hslaMatched = hslaRegex.exec(normalizedColor.substring(0, 50));\n if (hslaMatched) {\n var _hue = parseInt(\"\" + hslaMatched[1], 10);\n var _saturation = parseInt(\"\" + hslaMatched[2], 10) / 100;\n var _lightness = parseInt(\"\" + hslaMatched[3], 10) / 100;\n var _rgbColorString = \"rgb(\" + hslToRgb(_hue, _saturation, _lightness) + \")\";\n var _hslRgbMatched = rgbRegex.exec(_rgbColorString);\n if (!_hslRgbMatched) {\n throw new PolishedError(4, normalizedColor, _rgbColorString);\n }\n return {\n red: parseInt(\"\" + _hslRgbMatched[1], 10),\n green: parseInt(\"\" + _hslRgbMatched[2], 10),\n blue: parseInt(\"\" + _hslRgbMatched[3], 10),\n alpha: parseFloat(\"\" + hslaMatched[4]) > 1 ? parseFloat(\"\" + hslaMatched[4]) / 100 : parseFloat(\"\" + hslaMatched[4])\n };\n }\n throw new PolishedError(5);\n}\n\nfunction rgbToHsl(color) {\n // make sure rgb are contained in a set of [0, 255]\n var red = color.red / 255;\n var green = color.green / 255;\n var blue = color.blue / 255;\n var max = Math.max(red, green, blue);\n var min = Math.min(red, green, blue);\n var lightness = (max + min) / 2;\n if (max === min) {\n // achromatic\n if (color.alpha !== undefined) {\n return {\n hue: 0,\n saturation: 0,\n lightness: lightness,\n alpha: color.alpha\n };\n } else {\n return {\n hue: 0,\n saturation: 0,\n lightness: lightness\n };\n }\n }\n var hue;\n var delta = max - min;\n var saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n switch (max) {\n case red:\n hue = (green - blue) / delta + (green < blue ? 6 : 0);\n break;\n case green:\n hue = (blue - red) / delta + 2;\n break;\n default:\n // blue case\n hue = (red - green) / delta + 4;\n break;\n }\n hue *= 60;\n if (color.alpha !== undefined) {\n return {\n hue: hue,\n saturation: saturation,\n lightness: lightness,\n alpha: color.alpha\n };\n }\n return {\n hue: hue,\n saturation: saturation,\n lightness: lightness\n };\n}\n\n/**\n * Returns an HslColor or HslaColor object. This utility function is only useful\n * if want to extract a color component. With the color util `toColorString` you\n * can convert a HslColor or HslaColor object back to a string.\n *\n * @example\n * // Assigns `{ hue: 0, saturation: 1, lightness: 0.5 }` to color1\n * const color1 = parseToHsl('rgb(255, 0, 0)');\n * // Assigns `{ hue: 128, saturation: 1, lightness: 0.5, alpha: 0.75 }` to color2\n * const color2 = parseToHsl('hsla(128, 100%, 50%, 0.75)');\n */\nfunction parseToHsl(color) {\n // Note: At a later stage we can optimize this function as right now a hsl\n // color would be parsed converted to rgb values and converted back to hsl.\n return rgbToHsl(parseToRgb(color));\n}\n\n/**\n * Reduces hex values if possible e.g. #ff8866 to #f86\n * @private\n */\nvar reduceHexValue = function reduceHexValue(value) {\n if (value.length === 7 && value[1] === value[2] && value[3] === value[4] && value[5] === value[6]) {\n return \"#\" + value[1] + value[3] + value[5];\n }\n return value;\n};\nvar reduceHexValue$1 = reduceHexValue;\n\nfunction numberToHex(value) {\n var hex = value.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n}\n\nfunction colorToHex(color) {\n return numberToHex(Math.round(color * 255));\n}\nfunction convertToHex(red, green, blue) {\n return reduceHexValue$1(\"#\" + colorToHex(red) + colorToHex(green) + colorToHex(blue));\n}\nfunction hslToHex(hue, saturation, lightness) {\n return hslToRgb(hue, saturation, lightness, convertToHex);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible hex notation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: hsl(359, 0.75, 0.4),\n * background: hsl({ hue: 360, saturation: 0.75, lightness: 0.4 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${hsl(359, 0.75, 0.4)};\n * background: ${hsl({ hue: 360, saturation: 0.75, lightness: 0.4 })};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#b3191c\";\n * background: \"#b3191c\";\n * }\n */\nfunction hsl(value, saturation, lightness) {\n if (typeof value === 'number' && typeof saturation === 'number' && typeof lightness === 'number') {\n return hslToHex(value, saturation, lightness);\n } else if (typeof value === 'object' && saturation === undefined && lightness === undefined) {\n return hslToHex(value.hue, value.saturation, value.lightness);\n }\n throw new PolishedError(1);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible rgba or hex notation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: hsla(359, 0.75, 0.4, 0.7),\n * background: hsla({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0,7 }),\n * background: hsla(359, 0.75, 0.4, 1),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${hsla(359, 0.75, 0.4, 0.7)};\n * background: ${hsla({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0,7 })};\n * background: ${hsla(359, 0.75, 0.4, 1)};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"rgba(179,25,28,0.7)\";\n * background: \"rgba(179,25,28,0.7)\";\n * background: \"#b3191c\";\n * }\n */\nfunction hsla(value, saturation, lightness, alpha) {\n if (typeof value === 'number' && typeof saturation === 'number' && typeof lightness === 'number' && typeof alpha === 'number') {\n return alpha >= 1 ? hslToHex(value, saturation, lightness) : \"rgba(\" + hslToRgb(value, saturation, lightness) + \",\" + alpha + \")\";\n } else if (typeof value === 'object' && saturation === undefined && lightness === undefined && alpha === undefined) {\n return value.alpha >= 1 ? hslToHex(value.hue, value.saturation, value.lightness) : \"rgba(\" + hslToRgb(value.hue, value.saturation, value.lightness) + \",\" + value.alpha + \")\";\n }\n throw new PolishedError(2);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible hex notation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: rgb(255, 205, 100),\n * background: rgb({ red: 255, green: 205, blue: 100 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${rgb(255, 205, 100)};\n * background: ${rgb({ red: 255, green: 205, blue: 100 })};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#ffcd64\";\n * background: \"#ffcd64\";\n * }\n */\nfunction rgb(value, green, blue) {\n if (typeof value === 'number' && typeof green === 'number' && typeof blue === 'number') {\n return reduceHexValue$1(\"#\" + numberToHex(value) + numberToHex(green) + numberToHex(blue));\n } else if (typeof value === 'object' && green === undefined && blue === undefined) {\n return reduceHexValue$1(\"#\" + numberToHex(value.red) + numberToHex(value.green) + numberToHex(value.blue));\n }\n throw new PolishedError(6);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible rgba or hex notation.\n *\n * Can also be used to fade a color by passing a hex value or named CSS color along with an alpha value.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: rgba(255, 205, 100, 0.7),\n * background: rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 }),\n * background: rgba(255, 205, 100, 1),\n * background: rgba('#ffffff', 0.4),\n * background: rgba('black', 0.7),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${rgba(255, 205, 100, 0.7)};\n * background: ${rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 })};\n * background: ${rgba(255, 205, 100, 1)};\n * background: ${rgba('#ffffff', 0.4)};\n * background: ${rgba('black', 0.7)};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"rgba(255,205,100,0.7)\";\n * background: \"rgba(255,205,100,0.7)\";\n * background: \"#ffcd64\";\n * background: \"rgba(255,255,255,0.4)\";\n * background: \"rgba(0,0,0,0.7)\";\n * }\n */\nfunction rgba(firstValue, secondValue, thirdValue, fourthValue) {\n if (typeof firstValue === 'string' && typeof secondValue === 'number') {\n var rgbValue = parseToRgb(firstValue);\n return \"rgba(\" + rgbValue.red + \",\" + rgbValue.green + \",\" + rgbValue.blue + \",\" + secondValue + \")\";\n } else if (typeof firstValue === 'number' && typeof secondValue === 'number' && typeof thirdValue === 'number' && typeof fourthValue === 'number') {\n return fourthValue >= 1 ? rgb(firstValue, secondValue, thirdValue) : \"rgba(\" + firstValue + \",\" + secondValue + \",\" + thirdValue + \",\" + fourthValue + \")\";\n } else if (typeof firstValue === 'object' && secondValue === undefined && thirdValue === undefined && fourthValue === undefined) {\n return firstValue.alpha >= 1 ? rgb(firstValue.red, firstValue.green, firstValue.blue) : \"rgba(\" + firstValue.red + \",\" + firstValue.green + \",\" + firstValue.blue + \",\" + firstValue.alpha + \")\";\n }\n throw new PolishedError(7);\n}\n\nvar isRgb = function isRgb(color) {\n return typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number' && (typeof color.alpha !== 'number' || typeof color.alpha === 'undefined');\n};\nvar isRgba = function isRgba(color) {\n return typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number' && typeof color.alpha === 'number';\n};\nvar isHsl = function isHsl(color) {\n return typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number' && (typeof color.alpha !== 'number' || typeof color.alpha === 'undefined');\n};\nvar isHsla = function isHsla(color) {\n return typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number' && typeof color.alpha === 'number';\n};\n\n/**\n * Converts a RgbColor, RgbaColor, HslColor or HslaColor object to a color string.\n * This util is useful in case you only know on runtime which color object is\n * used. Otherwise we recommend to rely on `rgb`, `rgba`, `hsl` or `hsla`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: toColorString({ red: 255, green: 205, blue: 100 }),\n * background: toColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 }),\n * background: toColorString({ hue: 240, saturation: 1, lightness: 0.5 }),\n * background: toColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${toColorString({ red: 255, green: 205, blue: 100 })};\n * background: ${toColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 })};\n * background: ${toColorString({ hue: 240, saturation: 1, lightness: 0.5 })};\n * background: ${toColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 })};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#ffcd64\";\n * background: \"rgba(255,205,100,0.72)\";\n * background: \"#00f\";\n * background: \"rgba(179,25,25,0.72)\";\n * }\n */\n\nfunction toColorString(color) {\n if (typeof color !== 'object') throw new PolishedError(8);\n if (isRgba(color)) return rgba(color);\n if (isRgb(color)) return rgb(color);\n if (isHsla(color)) return hsla(color);\n if (isHsl(color)) return hsl(color);\n throw new PolishedError(8);\n}\n\n// Type definitions taken from https://github.com/gcanti/flow-static-land/blob/master/src/Fun.js\n// eslint-disable-next-line no-unused-vars\n// eslint-disable-next-line no-unused-vars\n// eslint-disable-next-line no-redeclare\nfunction curried(f, length, acc) {\n return function fn() {\n // eslint-disable-next-line prefer-rest-params\n var combined = acc.concat(Array.prototype.slice.call(arguments));\n return combined.length >= length ? f.apply(this, combined) : curried(f, length, combined);\n };\n}\n\n// eslint-disable-next-line no-redeclare\nfunction curry(f) {\n // eslint-disable-line no-redeclare\n return curried(f, f.length, []);\n}\n\n/**\n * Changes the hue of the color. Hue is a number between 0 to 360. The first\n * argument for adjustHue is the amount of degrees the color is rotated around\n * the color wheel, always producing a positive hue value.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: adjustHue(180, '#448'),\n * background: adjustHue('180', 'rgba(101,100,205,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${adjustHue(180, '#448')};\n * background: ${adjustHue('180', 'rgba(101,100,205,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#888844\";\n * background: \"rgba(136,136,68,0.7)\";\n * }\n */\nfunction adjustHue(degree, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n hue: hslColor.hue + parseFloat(degree)\n }));\n}\n\n// prettier-ignore\nvar curriedAdjustHue = curry /* ::<number | string, string, string> */(adjustHue);\nvar curriedAdjustHue$1 = curriedAdjustHue;\n\n/**\n * Returns the complement of the provided color. This is identical to adjustHue(180, <color>).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: complement('#448'),\n * background: complement('rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${complement('#448')};\n * background: ${complement('rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#884\";\n * background: \"rgba(153,153,153,0.7)\";\n * }\n */\nfunction complement(color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n hue: (hslColor.hue + 180) % 360\n }));\n}\n\nfunction guard(lowerBoundary, upperBoundary, value) {\n return Math.max(lowerBoundary, Math.min(upperBoundary, value));\n}\n\n/**\n * Returns a string value for the darkened color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: darken(0.2, '#FFCD64'),\n * background: darken('0.2', 'rgba(255,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${darken(0.2, '#FFCD64')};\n * background: ${darken('0.2', 'rgba(255,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#ffbd31\";\n * background: \"rgba(255,189,49,0.7)\";\n * }\n */\nfunction darken(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n lightness: guard(0, 1, hslColor.lightness - parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedDarken = curry /* ::<number | string, string, string> */(darken);\nvar curriedDarken$1 = curriedDarken;\n\n/**\n * Decreases the intensity of a color. Its range is between 0 to 1. The first\n * argument of the desaturate function is the amount by how much the color\n * intensity should be decreased.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: desaturate(0.2, '#CCCD64'),\n * background: desaturate('0.2', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${desaturate(0.2, '#CCCD64')};\n * background: ${desaturate('0.2', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#b8b979\";\n * background: \"rgba(184,185,121,0.7)\";\n * }\n */\nfunction desaturate(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n saturation: guard(0, 1, hslColor.saturation - parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedDesaturate = curry /* ::<number | string, string, string> */(desaturate);\nvar curriedDesaturate$1 = curriedDesaturate;\n\n/**\n * Returns a number (float) representing the luminance of a color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: getLuminance('#CCCD64') >= getLuminance('#0000ff') ? '#CCCD64' : '#0000ff',\n * background: getLuminance('rgba(58, 133, 255, 1)') >= getLuminance('rgba(255, 57, 149, 1)') ?\n * 'rgba(58, 133, 255, 1)' :\n * 'rgba(255, 57, 149, 1)',\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${getLuminance('#CCCD64') >= getLuminance('#0000ff') ? '#CCCD64' : '#0000ff'};\n * background: ${getLuminance('rgba(58, 133, 255, 1)') >= getLuminance('rgba(255, 57, 149, 1)') ?\n * 'rgba(58, 133, 255, 1)' :\n * 'rgba(255, 57, 149, 1)'};\n *\n * // CSS in JS Output\n *\n * div {\n * background: \"#CCCD64\";\n * background: \"rgba(58, 133, 255, 1)\";\n * }\n */\nfunction getLuminance(color) {\n if (color === 'transparent') return 0;\n var rgbColor = parseToRgb(color);\n var _Object$keys$map = Object.keys(rgbColor).map(function (key) {\n var channel = rgbColor[key] / 255;\n return channel <= 0.03928 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);\n }),\n r = _Object$keys$map[0],\n g = _Object$keys$map[1],\n b = _Object$keys$map[2];\n return parseFloat((0.2126 * r + 0.7152 * g + 0.0722 * b).toFixed(3));\n}\n\n/**\n * Returns the contrast ratio between two colors based on\n * [W3's recommended equation for calculating contrast](http://www.w3.org/TR/WCAG20/#contrast-ratiodef).\n *\n * @example\n * const contrastRatio = getContrast('#444', '#fff');\n */\nfunction getContrast(color1, color2) {\n var luminance1 = getLuminance(color1);\n var luminance2 = getLuminance(color2);\n return parseFloat((luminance1 > luminance2 ? (luminance1 + 0.05) / (luminance2 + 0.05) : (luminance2 + 0.05) / (luminance1 + 0.05)).toFixed(2));\n}\n\n/**\n * Converts the color to a grayscale, by reducing its saturation to 0.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: grayscale('#CCCD64'),\n * background: grayscale('rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${grayscale('#CCCD64')};\n * background: ${grayscale('rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#999\";\n * background: \"rgba(153,153,153,0.7)\";\n * }\n */\nfunction grayscale(color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n saturation: 0\n }));\n}\n\n/**\n * Converts a HslColor or HslaColor object to a color string.\n * This util is useful in case you only know on runtime which color object is\n * used. Otherwise we recommend to rely on `hsl` or `hsla`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: hslToColorString({ hue: 240, saturation: 1, lightness: 0.5 }),\n * background: hslToColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${hslToColorString({ hue: 240, saturation: 1, lightness: 0.5 })};\n * background: ${hslToColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 })};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#00f\";\n * background: \"rgba(179,25,25,0.72)\";\n * }\n */\nfunction hslToColorString(color) {\n if (typeof color === 'object' && typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number') {\n if (color.alpha && typeof color.alpha === 'number') {\n return hsla({\n hue: color.hue,\n saturation: color.saturation,\n lightness: color.lightness,\n alpha: color.alpha\n });\n }\n return hsl({\n hue: color.hue,\n saturation: color.saturation,\n lightness: color.lightness\n });\n }\n throw new PolishedError(45);\n}\n\n/**\n * Inverts the red, green and blue values of a color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: invert('#CCCD64'),\n * background: invert('rgba(101,100,205,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${invert('#CCCD64')};\n * background: ${invert('rgba(101,100,205,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#33329b\";\n * background: \"rgba(154,155,50,0.7)\";\n * }\n */\nfunction invert(color) {\n if (color === 'transparent') return color;\n // parse color string to rgb\n var value = parseToRgb(color);\n return toColorString(_extends({}, value, {\n red: 255 - value.red,\n green: 255 - value.green,\n blue: 255 - value.blue\n }));\n}\n\n/**\n * Returns a string value for the lightened color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: lighten(0.2, '#CCCD64'),\n * background: lighten('0.2', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${lighten(0.2, '#FFCD64')};\n * background: ${lighten('0.2', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#e5e6b1\";\n * background: \"rgba(229,230,177,0.7)\";\n * }\n */\nfunction lighten(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n lightness: guard(0, 1, hslColor.lightness + parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedLighten = curry /* ::<number | string, string, string> */(lighten);\nvar curriedLighten$1 = curriedLighten;\n\n/**\n * Determines which contrast guidelines have been met for two colors.\n * Based on the [contrast calculations recommended by W3](https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced.html).\n *\n * @example\n * const scores = meetsContrastGuidelines('#444', '#fff');\n */\nfunction meetsContrastGuidelines(color1, color2) {\n var contrastRatio = getContrast(color1, color2);\n return {\n AA: contrastRatio >= 4.5,\n AALarge: contrastRatio >= 3,\n AAA: contrastRatio >= 7,\n AAALarge: contrastRatio >= 4.5\n };\n}\n\n/**\n * Mixes the two provided colors together by calculating the average of each of the RGB components weighted to the first color by the provided weight.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: mix(0.5, '#f00', '#00f')\n * background: mix(0.25, '#f00', '#00f')\n * background: mix('0.5', 'rgba(255, 0, 0, 0.5)', '#00f')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${mix(0.5, '#f00', '#00f')};\n * background: ${mix(0.25, '#f00', '#00f')};\n * background: ${mix('0.5', 'rgba(255, 0, 0, 0.5)', '#00f')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#7f007f\";\n * background: \"#3f00bf\";\n * background: \"rgba(63, 0, 191, 0.75)\";\n * }\n */\nfunction mix(weight, color, otherColor) {\n if (color === 'transparent') return otherColor;\n if (otherColor === 'transparent') return color;\n if (weight === 0) return otherColor;\n var parsedColor1 = parseToRgb(color);\n var color1 = _extends({}, parsedColor1, {\n alpha: typeof parsedColor1.alpha === 'number' ? parsedColor1.alpha : 1\n });\n var parsedColor2 = parseToRgb(otherColor);\n var color2 = _extends({}, parsedColor2, {\n alpha: typeof parsedColor2.alpha === 'number' ? parsedColor2.alpha : 1\n });\n\n // The formula is copied from the original Sass implementation:\n // http://sass-lang.com/documentation/Sass/Script/Functions.html#mix-instance_method\n var alphaDelta = color1.alpha - color2.alpha;\n var x = parseFloat(weight) * 2 - 1;\n var y = x * alphaDelta === -1 ? x : x + alphaDelta;\n var z = 1 + x * alphaDelta;\n var weight1 = (y / z + 1) / 2.0;\n var weight2 = 1 - weight1;\n var mixedColor = {\n red: Math.floor(color1.red * weight1 + color2.red * weight2),\n green: Math.floor(color1.green * weight1 + color2.green * weight2),\n blue: Math.floor(color1.blue * weight1 + color2.blue * weight2),\n alpha: color1.alpha * parseFloat(weight) + color2.alpha * (1 - parseFloat(weight))\n };\n return rgba(mixedColor);\n}\n\n// prettier-ignore\nvar curriedMix = curry /* ::<number | string, string, string, string> */(mix);\nvar mix$1 = curriedMix;\n\n/**\n * Increases the opacity of a color. Its range for the amount is between 0 to 1.\n *\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: opacify(0.1, 'rgba(255, 255, 255, 0.9)');\n * background: opacify(0.2, 'hsla(0, 0%, 100%, 0.5)'),\n * background: opacify('0.5', 'rgba(255, 0, 0, 0.2)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${opacify(0.1, 'rgba(255, 255, 255, 0.9)')};\n * background: ${opacify(0.2, 'hsla(0, 0%, 100%, 0.5)')},\n * background: ${opacify('0.5', 'rgba(255, 0, 0, 0.2)')},\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#fff\";\n * background: \"rgba(255,255,255,0.7)\";\n * background: \"rgba(255,0,0,0.7)\";\n * }\n */\nfunction opacify(amount, color) {\n if (color === 'transparent') return color;\n var parsedColor = parseToRgb(color);\n var alpha = typeof parsedColor.alpha === 'number' ? parsedColor.alpha : 1;\n var colorWithAlpha = _extends({}, parsedColor, {\n alpha: guard(0, 1, (alpha * 100 + parseFloat(amount) * 100) / 100)\n });\n return rgba(colorWithAlpha);\n}\n\n// prettier-ignore\nvar curriedOpacify = curry /* ::<number | string, string, string> */(opacify);\nvar curriedOpacify$1 = curriedOpacify;\n\nvar defaultReturnIfLightColor = '#000';\nvar defaultReturnIfDarkColor = '#fff';\n\n/**\n * Returns black or white (or optional passed colors) for best\n * contrast depending on the luminosity of the given color.\n * When passing custom return colors, strict mode ensures that the\n * return color always meets or exceeds WCAG level AA or greater. If this test\n * fails, the default return color (black or white) is returned in place of the\n * custom return color. You can optionally turn off strict mode.\n *\n * Follows [W3C specs for readability](https://www.w3.org/TR/WCAG20-TECHS/G18.html).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * color: readableColor('#000'),\n * color: readableColor('black', '#001', '#ff8'),\n * color: readableColor('white', '#001', '#ff8'),\n * color: readableColor('red', '#333', '#ddd', true)\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * color: ${readableColor('#000')};\n * color: ${readableColor('black', '#001', '#ff8')};\n * color: ${readableColor('white', '#001', '#ff8')};\n * color: ${readableColor('red', '#333', '#ddd', true)};\n * `\n *\n * // CSS in JS Output\n * element {\n * color: \"#fff\";\n * color: \"#ff8\";\n * color: \"#001\";\n * color: \"#000\";\n * }\n */\nfunction readableColor(color, returnIfLightColor, returnIfDarkColor, strict) {\n if (returnIfLightColor === void 0) {\n returnIfLightColor = defaultReturnIfLightColor;\n }\n if (returnIfDarkColor === void 0) {\n returnIfDarkColor = defaultReturnIfDarkColor;\n }\n if (strict === void 0) {\n strict = true;\n }\n var isColorLight = getLuminance(color) > 0.179;\n var preferredReturnColor = isColorLight ? returnIfLightColor : returnIfDarkColor;\n if (!strict || getContrast(color, preferredReturnColor) >= 4.5) {\n return preferredReturnColor;\n }\n return isColorLight ? defaultReturnIfLightColor : defaultReturnIfDarkColor;\n}\n\n/**\n * Converts a RgbColor or RgbaColor object to a color string.\n * This util is useful in case you only know on runtime which color object is\n * used. Otherwise we recommend to rely on `rgb` or `rgba`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: rgbToColorString({ red: 255, green: 205, blue: 100 }),\n * background: rgbToColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${rgbToColorString({ red: 255, green: 205, blue: 100 })};\n * background: ${rgbToColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 })};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#ffcd64\";\n * background: \"rgba(255,205,100,0.72)\";\n * }\n */\nfunction rgbToColorString(color) {\n if (typeof color === 'object' && typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number') {\n if (typeof color.alpha === 'number') {\n return rgba({\n red: color.red,\n green: color.green,\n blue: color.blue,\n alpha: color.alpha\n });\n }\n return rgb({\n red: color.red,\n green: color.green,\n blue: color.blue\n });\n }\n throw new PolishedError(46);\n}\n\n/**\n * Increases the intensity of a color. Its range is between 0 to 1. The first\n * argument of the saturate function is the amount by how much the color\n * intensity should be increased.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: saturate(0.2, '#CCCD64'),\n * background: saturate('0.2', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${saturate(0.2, '#FFCD64')};\n * background: ${saturate('0.2', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#e0e250\";\n * background: \"rgba(224,226,80,0.7)\";\n * }\n */\nfunction saturate(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n saturation: guard(0, 1, hslColor.saturation + parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedSaturate = curry /* ::<number | string, string, string> */(saturate);\nvar curriedSaturate$1 = curriedSaturate;\n\n/**\n * Sets the hue of a color to the provided value. The hue range can be\n * from 0 and 359.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: setHue(42, '#CCCD64'),\n * background: setHue('244', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${setHue(42, '#CCCD64')};\n * background: ${setHue('244', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#cdae64\";\n * background: \"rgba(107,100,205,0.7)\";\n * }\n */\nfunction setHue(hue, color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n hue: parseFloat(hue)\n }));\n}\n\n// prettier-ignore\nvar curriedSetHue = curry /* ::<number | string, string, string> */(setHue);\nvar curriedSetHue$1 = curriedSetHue;\n\n/**\n * Sets the lightness of a color to the provided value. The lightness range can be\n * from 0 and 1.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: setLightness(0.2, '#CCCD64'),\n * background: setLightness('0.75', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${setLightness(0.2, '#CCCD64')};\n * background: ${setLightness('0.75', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#4d4d19\";\n * background: \"rgba(223,224,159,0.7)\";\n * }\n */\nfunction setLightness(lightness, color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n lightness: parseFloat(lightness)\n }));\n}\n\n// prettier-ignore\nvar curriedSetLightness = curry /* ::<number | string, string, string> */(setLightness);\nvar curriedSetLightness$1 = curriedSetLightness;\n\n/**\n * Sets the saturation of a color to the provided value. The saturation range can be\n * from 0 and 1.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: setSaturation(0.2, '#CCCD64'),\n * background: setSaturation('0.75', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${setSaturation(0.2, '#CCCD64')};\n * background: ${setSaturation('0.75', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#adad84\";\n * background: \"rgba(228,229,76,0.7)\";\n * }\n */\nfunction setSaturation(saturation, color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n saturation: parseFloat(saturation)\n }));\n}\n\n// prettier-ignore\nvar curriedSetSaturation = curry /* ::<number | string, string, string> */(setSaturation);\nvar curriedSetSaturation$1 = curriedSetSaturation;\n\n/**\n * Shades a color by mixing it with black. `shade` can produce\n * hue shifts, where as `darken` manipulates the luminance channel and therefore\n * doesn't produce hue shifts.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: shade(0.25, '#00f')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${shade(0.25, '#00f')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#00003f\";\n * }\n */\n\nfunction shade(percentage, color) {\n if (color === 'transparent') return color;\n return mix$1(parseFloat(percentage), 'rgb(0, 0, 0)', color);\n}\n\n// prettier-ignore\nvar curriedShade = curry /* ::<number | string, string, string> */(shade);\nvar curriedShade$1 = curriedShade;\n\n/**\n * Tints a color by mixing it with white. `tint` can produce\n * hue shifts, where as `lighten` manipulates the luminance channel and therefore\n * doesn't produce hue shifts.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: tint(0.25, '#00f')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${tint(0.25, '#00f')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#bfbfff\";\n * }\n */\n\nfunction tint(percentage, color) {\n if (color === 'transparent') return color;\n return mix$1(parseFloat(percentage), 'rgb(255, 255, 255)', color);\n}\n\n// prettier-ignore\nvar curriedTint = curry /* ::<number | string, string, string> */(tint);\nvar curriedTint$1 = curriedTint;\n\n/**\n * Decreases the opacity of a color. Its range for the amount is between 0 to 1.\n *\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: transparentize(0.1, '#fff'),\n * background: transparentize(0.2, 'hsl(0, 0%, 100%)'),\n * background: transparentize('0.5', 'rgba(255, 0, 0, 0.8)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${transparentize(0.1, '#fff')};\n * background: ${transparentize(0.2, 'hsl(0, 0%, 100%)')};\n * background: ${transparentize('0.5', 'rgba(255, 0, 0, 0.8)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"rgba(255,255,255,0.9)\";\n * background: \"rgba(255,255,255,0.8)\";\n * background: \"rgba(255,0,0,0.3)\";\n * }\n */\nfunction transparentize(amount, color) {\n if (color === 'transparent') return color;\n var parsedColor = parseToRgb(color);\n var alpha = typeof parsedColor.alpha === 'number' ? parsedColor.alpha : 1;\n var colorWithAlpha = _extends({}, parsedColor, {\n alpha: guard(0, 1, +(alpha * 100 - parseFloat(amount) * 100).toFixed(2) / 100)\n });\n return rgba(colorWithAlpha);\n}\n\n// prettier-ignore\nvar curriedTransparentize = curry /* ::<number | string, string, string> */(transparentize);\nvar curriedTransparentize$1 = curriedTransparentize;\n\n/**\n * Shorthand for easily setting the animation property. Allows either multiple arrays with animations\n * or a single animation spread over the arguments.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...animation(['rotate', '1s', 'ease-in-out'], ['colorchange', '2s'])\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${animation(['rotate', '1s', 'ease-in-out'], ['colorchange', '2s'])}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'animation': 'rotate 1s ease-in-out, colorchange 2s'\n * }\n * @example\n * // Styles as object usage\n * const styles = {\n * ...animation('rotate', '1s', 'ease-in-out')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${animation('rotate', '1s', 'ease-in-out')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'animation': 'rotate 1s ease-in-out'\n * }\n */\nfunction animation() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n // Allow single or multiple animations passed\n var multiMode = Array.isArray(args[0]);\n if (!multiMode && args.length > 8) {\n throw new PolishedError(64);\n }\n var code = args.map(function (arg) {\n if (multiMode && !Array.isArray(arg) || !multiMode && Array.isArray(arg)) {\n throw new PolishedError(65);\n }\n if (Array.isArray(arg) && arg.length > 8) {\n throw new PolishedError(66);\n }\n return Array.isArray(arg) ? arg.join(' ') : arg;\n }).join(', ');\n return {\n animation: code\n };\n}\n\n/**\n * Shorthand that accepts any number of backgroundImage values as parameters for creating a single background statement.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...backgroundImages('url(\"/image/background.jpg\")', 'linear-gradient(red, green)')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${backgroundImages('url(\"/image/background.jpg\")', 'linear-gradient(red, green)')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'backgroundImage': 'url(\"/image/background.jpg\"), linear-gradient(red, green)'\n * }\n */\nfunction backgroundImages() {\n for (var _len = arguments.length, properties = new Array(_len), _key = 0; _key < _len; _key++) {\n properties[_key] = arguments[_key];\n }\n return {\n backgroundImage: properties.join(', ')\n };\n}\n\n/**\n * Shorthand that accepts any number of background values as parameters for creating a single background statement.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...backgrounds('url(\"/image/background.jpg\")', 'linear-gradient(red, green)', 'center no-repeat')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${backgrounds('url(\"/image/background.jpg\")', 'linear-gradient(red, green)', 'center no-repeat')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'background': 'url(\"/image/background.jpg\"), linear-gradient(red, green), center no-repeat'\n * }\n */\nfunction backgrounds() {\n for (var _len = arguments.length, properties = new Array(_len), _key = 0; _key < _len; _key++) {\n properties[_key] = arguments[_key];\n }\n return {\n background: properties.join(', ')\n };\n}\n\nvar sideMap = ['top', 'right', 'bottom', 'left'];\n\n/**\n * Shorthand for the border property that splits out individual properties for use with tools like Fela and Styletron. A side keyword can optionally be passed to target only one side's border properties.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...border('1px', 'solid', 'red')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${border('1px', 'solid', 'red')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderColor': 'red',\n * 'borderStyle': 'solid',\n * 'borderWidth': `1px`,\n * }\n *\n * // Styles as object usage\n * const styles = {\n * ...border('top', '1px', 'solid', 'red')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${border('top', '1px', 'solid', 'red')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopColor': 'red',\n * 'borderTopStyle': 'solid',\n * 'borderTopWidth': `1px`,\n * }\n */\n\nfunction border(sideKeyword) {\n for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n values[_key - 1] = arguments[_key];\n }\n if (typeof sideKeyword === 'string' && sideMap.indexOf(sideKeyword) >= 0) {\n var _ref;\n return _ref = {}, _ref[\"border\" + capitalizeString(sideKeyword) + \"Width\"] = values[0], _ref[\"border\" + capitalizeString(sideKeyword) + \"Style\"] = values[1], _ref[\"border\" + capitalizeString(sideKeyword) + \"Color\"] = values[2], _ref;\n } else {\n values.unshift(sideKeyword);\n return {\n borderWidth: values[0],\n borderStyle: values[1],\n borderColor: values[2]\n };\n }\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderColor('red', 'green', 'blue', 'yellow')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderColor('red', 'green', 'blue', 'yellow')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopColor': 'red',\n * 'borderRightColor': 'green',\n * 'borderBottomColor': 'blue',\n * 'borderLeftColor': 'yellow'\n * }\n */\nfunction borderColor() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['borderColor'].concat(values));\n}\n\n/**\n * Shorthand that accepts a value for side and a value for radius and applies the radius value to both corners of the side.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderRadius('top', '5px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderRadius('top', '5px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopRightRadius': '5px',\n * 'borderTopLeftRadius': '5px',\n * }\n */\nfunction borderRadius(side, radius) {\n var uppercaseSide = capitalizeString(side);\n if (!radius && radius !== 0) {\n throw new PolishedError(62);\n }\n if (uppercaseSide === 'Top' || uppercaseSide === 'Bottom') {\n var _ref;\n return _ref = {}, _ref[\"border\" + uppercaseSide + \"RightRadius\"] = radius, _ref[\"border\" + uppercaseSide + \"LeftRadius\"] = radius, _ref;\n }\n if (uppercaseSide === 'Left' || uppercaseSide === 'Right') {\n var _ref2;\n return _ref2 = {}, _ref2[\"borderTop\" + uppercaseSide + \"Radius\"] = radius, _ref2[\"borderBottom\" + uppercaseSide + \"Radius\"] = radius, _ref2;\n }\n throw new PolishedError(63);\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderStyle('solid', 'dashed', 'dotted', 'double')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderStyle('solid', 'dashed', 'dotted', 'double')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopStyle': 'solid',\n * 'borderRightStyle': 'dashed',\n * 'borderBottomStyle': 'dotted',\n * 'borderLeftStyle': 'double'\n * }\n */\nfunction borderStyle() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['borderStyle'].concat(values));\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderWidth('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderWidth('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopWidth': '12px',\n * 'borderRightWidth': '24px',\n * 'borderBottomWidth': '36px',\n * 'borderLeftWidth': '48px'\n * }\n */\nfunction borderWidth() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['borderWidth'].concat(values));\n}\n\nfunction generateSelectors(template, state) {\n var stateSuffix = state ? \":\" + state : '';\n return template(stateSuffix);\n}\n\n/**\n * Function helper that adds an array of states to a template of selectors. Used in textInputs and buttons.\n * @private\n */\nfunction statefulSelectors(states, template, stateMap) {\n if (!template) throw new PolishedError(67);\n if (states.length === 0) return generateSelectors(template, null);\n var selectors = [];\n for (var i = 0; i < states.length; i += 1) {\n if (stateMap && stateMap.indexOf(states[i]) < 0) {\n throw new PolishedError(68);\n }\n selectors.push(generateSelectors(template, states[i]));\n }\n selectors = selectors.join(',');\n return selectors;\n}\n\nvar stateMap$1 = [undefined, null, 'active', 'focus', 'hover'];\nfunction template$1(state) {\n return \"button\" + state + \",\\n input[type=\\\"button\\\"]\" + state + \",\\n input[type=\\\"reset\\\"]\" + state + \",\\n input[type=\\\"submit\\\"]\" + state;\n}\n\n/**\n * Populates selectors that target all buttons. You can pass optional states to append to the selectors.\n * @example\n * // Styles as object usage\n * const styles = {\n * [buttons('active')]: {\n * 'border': 'none'\n * }\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * > ${buttons('active')} {\n * border: none;\n * }\n * `\n *\n * // CSS in JS Output\n *\n * 'button:active,\n * 'input[type=\"button\"]:active,\n * 'input[type=\\\"reset\\\"]:active,\n * 'input[type=\\\"submit\\\"]:active: {\n * 'border': 'none'\n * }\n */\nfunction buttons() {\n for (var _len = arguments.length, states = new Array(_len), _key = 0; _key < _len; _key++) {\n states[_key] = arguments[_key];\n }\n return statefulSelectors(states, template$1, stateMap$1);\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...margin('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${margin('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'marginTop': '12px',\n * 'marginRight': '24px',\n * 'marginBottom': '36px',\n * 'marginLeft': '48px'\n * }\n */\nfunction margin() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['margin'].concat(values));\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...padding('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${padding('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'paddingTop': '12px',\n * 'paddingRight': '24px',\n * 'paddingBottom': '36px',\n * 'paddingLeft': '48px'\n * }\n */\nfunction padding() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['padding'].concat(values));\n}\n\nvar positionMap = ['absolute', 'fixed', 'relative', 'static', 'sticky'];\n\n/**\n * Shorthand accepts up to five values, including null to skip a value, and maps them to their respective directions. The first value can optionally be a position keyword.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...position('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${position('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'top': '12px',\n * 'right': '24px',\n * 'bottom': '36px',\n * 'left': '48px'\n * }\n *\n * // Styles as object usage\n * const styles = {\n * ...position('absolute', '12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${position('absolute', '12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'position': 'absolute',\n * 'top': '12px',\n * 'right': '24px',\n * 'bottom': '36px',\n * 'left': '48px'\n * }\n */\nfunction position(firstValue) {\n for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n values[_key - 1] = arguments[_key];\n }\n if (positionMap.indexOf(firstValue) >= 0 && firstValue) {\n return _extends({}, directionalProperty.apply(void 0, [''].concat(values)), {\n position: firstValue\n });\n } else {\n return directionalProperty.apply(void 0, ['', firstValue].concat(values));\n }\n}\n\n/**\n * Shorthand to set the height and width properties in a single statement.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...size('300px', '250px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${size('300px', '250px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'height': '300px',\n * 'width': '250px',\n * }\n */\nfunction size(height, width) {\n if (width === void 0) {\n width = height;\n }\n return {\n height: height,\n width: width\n };\n}\n\nvar stateMap = [undefined, null, 'active', 'focus', 'hover'];\nfunction template(state) {\n return \"input[type=\\\"color\\\"]\" + state + \",\\n input[type=\\\"date\\\"]\" + state + \",\\n input[type=\\\"datetime\\\"]\" + state + \",\\n input[type=\\\"datetime-local\\\"]\" + state + \",\\n input[type=\\\"email\\\"]\" + state + \",\\n input[type=\\\"month\\\"]\" + state + \",\\n input[type=\\\"number\\\"]\" + state + \",\\n input[type=\\\"password\\\"]\" + state + \",\\n input[type=\\\"search\\\"]\" + state + \",\\n input[type=\\\"tel\\\"]\" + state + \",\\n input[type=\\\"text\\\"]\" + state + \",\\n input[type=\\\"time\\\"]\" + state + \",\\n input[type=\\\"url\\\"]\" + state + \",\\n input[type=\\\"week\\\"]\" + state + \",\\n input:not([type])\" + state + \",\\n textarea\" + state;\n}\n\n/**\n * Populates selectors that target all text inputs. You can pass optional states to append to the selectors.\n * @example\n * // Styles as object usage\n * const styles = {\n * [textInputs('active')]: {\n * 'border': 'none'\n * }\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * > ${textInputs('active')} {\n * border: none;\n * }\n * `\n *\n * // CSS in JS Output\n *\n * 'input[type=\"color\"]:active,\n * input[type=\"date\"]:active,\n * input[type=\"datetime\"]:active,\n * input[type=\"datetime-local\"]:active,\n * input[type=\"email\"]:active,\n * input[type=\"month\"]:active,\n * input[type=\"number\"]:active,\n * input[type=\"password\"]:active,\n * input[type=\"search\"]:active,\n * input[type=\"tel\"]:active,\n * input[type=\"text\"]:active,\n * input[type=\"time\"]:active,\n * input[type=\"url\"]:active,\n * input[type=\"week\"]:active,\n * input:not([type]):active,\n * textarea:active': {\n * 'border': 'none'\n * }\n */\nfunction textInputs() {\n for (var _len = arguments.length, states = new Array(_len), _key = 0; _key < _len; _key++) {\n states[_key] = arguments[_key];\n }\n return statefulSelectors(states, template, stateMap);\n}\n\n/**\n * Accepts any number of transition values as parameters for creating a single transition statement. You may also pass an array of properties as the first parameter that you would like to apply the same transition values to (second parameter).\n * @example\n * // Styles as object usage\n * const styles = {\n * ...transitions('opacity 1.0s ease-in 0s', 'width 2.0s ease-in 2s'),\n * ...transitions(['color', 'background-color'], '2.0s ease-in 2s')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${transitions('opacity 1.0s ease-in 0s', 'width 2.0s ease-in 2s')};\n * ${transitions(['color', 'background-color'], '2.0s ease-in 2s'),};\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'transition': 'opacity 1.0s ease-in 0s, width 2.0s ease-in 2s'\n * 'transition': 'color 2.0s ease-in 2s, background-color 2.0s ease-in 2s',\n * }\n */\nfunction transitions() {\n for (var _len = arguments.length, properties = new Array(_len), _key = 0; _key < _len; _key++) {\n properties[_key] = arguments[_key];\n }\n if (Array.isArray(properties[0]) && properties.length === 2) {\n var value = properties[1];\n if (typeof value !== 'string') {\n throw new PolishedError(61);\n }\n var transitionsString = properties[0].map(function (property) {\n return property + \" \" + value;\n }).join(', ');\n return {\n transition: transitionsString\n };\n } else {\n return {\n transition: properties.join(', ')\n };\n }\n}\n\nexport { curriedAdjustHue$1 as adjustHue, animation, backgroundImages, backgrounds, between, border, borderColor, borderRadius, borderStyle, borderWidth, buttons, clearFix, complement, cover, cssVar, curriedDarken$1 as darken, curriedDesaturate$1 as desaturate, directionalProperty, easeIn, easeInOut, easeOut, ellipsis, em$1 as em, fluidRange, fontFace, getContrast, getLuminance, getValueAndUnit, grayscale, hiDPI, hideText, hideVisually, hsl, hslToColorString, hsla, important, invert, curriedLighten$1 as lighten, linearGradient, margin, math, meetsContrastGuidelines, mix$1 as mix, modularScale, normalize, curriedOpacify$1 as opacify, padding, parseToHsl, parseToRgb, position, radialGradient, readableColor, rem$1 as rem, remToPx, retinaImage, rgb, rgbToColorString, rgba, curriedSaturate$1 as saturate, curriedSetHue$1 as setHue, curriedSetLightness$1 as setLightness, curriedSetSaturation$1 as setSaturation, curriedShade$1 as shade, size, stripUnit, textInputs, timingFunctions, curriedTint$1 as tint, toColorString, transitions, curriedTransparentize$1 as transparentize, triangle, wordWrap };\n","import { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport type { SimpleRouteJson } from \"../types\"\nimport { transparentize } from \"polished\"\n\nexport const COLORS = [\n \"blue\",\n \"orange\",\n \"purple\",\n \"cyan\",\n \"magenta\",\n \"yellowgreen\",\n \"darkgoldenrod\",\n \"deeppink\",\n]\n\nexport const getColorMap = (\n srj: SimpleRouteJson,\n connMap?: ConnectivityMap,\n) => {\n const colorMap: Record<string, string> = {}\n for (let i = 0; i < srj.connections.length; i++) {\n const connection = srj.connections[i]\n const netName = connMap?.getNetConnectedToId(connection.name)\n\n if (netName && !colorMap[netName]) {\n colorMap[netName] =\n `hsl(${(i * 300) / srj.connections.length}, 100%, 50%)`\n }\n\n colorMap[connection.name] =\n (netName ? colorMap[netName] : null) ??\n `hsl(${(i * 340) / srj.connections.length}, 100%, 50%)`\n }\n return colorMap\n}\n\nexport const safeTransparentize = (color: string, amount: number) => {\n try {\n return transparentize(amount, color)\n } catch (e) {\n console.error(e)\n return color\n }\n}\n","export function isPointInRect(\n point: { x: number; y: number },\n rect: { center: { x: number; y: number }; width: number; height: number },\n) {\n return (\n point.x >= rect.center.x - rect.width / 2 &&\n point.x <= rect.center.x + rect.width / 2 &&\n point.y >= rect.center.y - rect.height / 2 &&\n point.y <= rect.center.y + rect.height / 2\n )\n}\n","export function doRectsOverlap(\n rect1: { center: { x: number; y: number }; width: number; height: number },\n rect2: { center: { x: number; y: number }; width: number; height: number },\n) {\n const rect1Left = rect1.center.x - rect1.width / 2\n const rect1Right = rect1.center.x + rect1.width / 2\n const rect1Top = rect1.center.y - rect1.height / 2\n const rect1Bottom = rect1.center.y + rect1.height / 2\n\n const rect2Left = rect2.center.x - rect2.width / 2\n const rect2Right = rect2.center.x + rect2.width / 2\n const rect2Top = rect2.center.y - rect2.height / 2\n const rect2Bottom = rect2.center.y + rect2.height / 2\n\n return (\n rect1Left <= rect2Right &&\n rect1Right >= rect2Left &&\n rect1Top <= rect2Bottom &&\n rect1Bottom >= rect2Top\n )\n}\n","export const mapLayerNameToZ = (layerName: string, layerCount: number) => {\n if (layerName === \"top\") return 0\n if (layerName === \"bottom\") return layerCount - 1\n return parseInt(layerName.slice(5))\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n Obstacle,\n SimpleRouteJson,\n} from \"../../types\"\nimport { COLORS } from \"../colors\"\nimport { isPointInRect } from \"lib/utils/isPointInRect\"\nimport { doRectsOverlap } from \"lib/utils/doRectsOverlap\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\n\ninterface CapacityMeshNodeSolverOptions {\n capacityDepth?: number\n}\n\ninterface Target {\n x: number\n y: number\n connectionName: string\n availableZ: number[]\n}\n\nexport class CapacityMeshNodeSolver extends BaseSolver {\n unfinishedNodes: CapacityMeshNode[]\n finishedNodes: CapacityMeshNode[]\n\n nodeToXYOverlappingObstaclesMap: Map<CapacityMeshNodeId, Obstacle[]>\n layerCount: number\n\n // targetObstacleMap: Record<string, { obstacle: Obstacle, node: CapacityMeshNode }>\n\n MAX_DEPTH = 4\n\n targets: Target[]\n\n constructor(\n public srj: SimpleRouteJson,\n public opts: CapacityMeshNodeSolverOptions = {},\n ) {\n super()\n this.MAX_DEPTH = opts?.capacityDepth ?? this.MAX_DEPTH\n this.MAX_ITERATIONS = 100_000\n this.layerCount = srj.layerCount ?? 2\n\n for (const obstacle of srj.obstacles) {\n if (!obstacle.zLayers) {\n const zLayers: number[] = []\n for (const layer of obstacle.layers) {\n zLayers.push(mapLayerNameToZ(layer, srj.layerCount))\n }\n obstacle.zLayers = zLayers\n }\n }\n\n const boundsCenter = {\n x: (srj.bounds.minX + srj.bounds.maxX) / 2,\n y: (srj.bounds.minY + srj.bounds.maxY) / 2,\n }\n const boundsSize = {\n width: srj.bounds.maxX - srj.bounds.minX,\n height: srj.bounds.maxY - srj.bounds.minY,\n }\n const maxWidthHeight = Math.max(boundsSize.width, boundsSize.height)\n this.unfinishedNodes = [\n {\n capacityMeshNodeId: this.getNextNodeId(),\n center: boundsCenter,\n width: maxWidthHeight,\n height: maxWidthHeight,\n layer: \"top\",\n availableZ: [0, 1],\n _depth: 0,\n _containsTarget: true,\n _containsObstacle: true,\n _completelyInsideObstacle: false,\n },\n ]\n this.finishedNodes = []\n this.nodeToXYOverlappingObstaclesMap = new Map()\n this.targets = this.srj.connections.flatMap((c) =>\n c.pointsToConnect.map((p) => ({\n ...p,\n connectionName: c.name,\n availableZ: p.layer === \"top\" ? [0] : [1],\n })),\n )\n }\n\n _nextNodeCounter = 0\n getNextNodeId(): string {\n return `cn${this._nextNodeCounter++}`\n }\n\n getCapacityFromDepth(depth: number): number {\n return (this.MAX_DEPTH - depth + 1) ** 2\n }\n\n getTargetIfNodeContainsTarget(node: CapacityMeshNode): Target | null {\n const overlappingObstacles = this.getXYOverlappingObstacles(node)\n for (const target of this.targets) {\n // if (target.layer !== node.layer) continue\n if (!target.availableZ.some((z) => node.availableZ.includes(z))) continue\n\n const targetObstacle = overlappingObstacles.find((o) =>\n isPointInRect(target, o),\n )\n\n if (targetObstacle) {\n if (doRectsOverlap(node, targetObstacle)) {\n return target\n }\n }\n\n if (\n target.x >= node.center.x - node.width / 2 &&\n target.x <= node.center.x + node.width / 2 &&\n target.y >= node.center.y - node.height / 2 &&\n target.y <= node.center.y + node.height / 2\n ) {\n return target\n }\n }\n return null\n }\n\n getXYOverlappingObstacles(node: CapacityMeshNode): Obstacle[] {\n const cachedObstacles = this.nodeToXYOverlappingObstaclesMap.get(\n node.capacityMeshNodeId,\n )\n if (cachedObstacles) {\n return cachedObstacles\n }\n const overlappingObstacles: Obstacle[] = []\n\n // Compute node bounds\n const nodeLeft = node.center.x - node.width / 2\n const nodeRight = node.center.x + node.width / 2\n const nodeTop = node.center.y - node.height / 2\n const nodeBottom = node.center.y + node.height / 2\n\n const obstacles = node._parent\n ? this.getXYOverlappingObstacles(node._parent)\n : this.srj.obstacles\n for (const obstacle of obstacles) {\n const obsLeft = obstacle.center.x - obstacle.width / 2\n const obsRight = obstacle.center.x + obstacle.width / 2\n const obsTop = obstacle.center.y - obstacle.height / 2\n const obsBottom = obstacle.center.y + obstacle.height / 2\n\n // Check for intersection.\n if (\n nodeRight >= obsLeft &&\n nodeLeft <= obsRight &&\n nodeBottom >= obsTop &&\n nodeTop <= obsBottom\n ) {\n overlappingObstacles.push(obstacle)\n continue\n }\n\n // Check if the node is completely within the obstacle\n if (\n nodeLeft >= obsLeft &&\n nodeRight <= obsRight &&\n nodeTop >= obsTop &&\n nodeBottom <= obsBottom\n ) {\n // Node is completely inside the obstacle\n overlappingObstacles.push(obstacle)\n continue\n }\n\n // Check if obstacle is completely within node\n if (\n obsLeft >= nodeLeft &&\n obsRight <= nodeRight &&\n obsTop >= nodeTop &&\n obsBottom <= nodeBottom\n ) {\n overlappingObstacles.push(obstacle)\n }\n }\n\n this.nodeToXYOverlappingObstaclesMap.set(\n node.capacityMeshNodeId,\n overlappingObstacles,\n )\n\n return overlappingObstacles\n }\n\n getXYZOverlappingObstacles(node: CapacityMeshNode): Obstacle[] {\n const xyOverlappingObstacles = this.getXYOverlappingObstacles(node)\n\n // For each obstacle, check if it has any overlap in the z-axis\n const xyzOverlappingObstacles: Obstacle[] = []\n for (const obstacle of xyOverlappingObstacles) {\n if (node.availableZ.some((z) => obstacle.zLayers!.includes(z))) {\n xyzOverlappingObstacles.push(obstacle)\n }\n }\n\n return xyzOverlappingObstacles\n }\n\n /**\n * Checks if the given mesh node overlaps with any obstacle.\n * We treat both obstacles and nodes as axis‐aligned rectangles.\n */\n doesNodeOverlapObstacle(node: CapacityMeshNode): boolean {\n const overlappingObstacles = this.getXYZOverlappingObstacles(node)\n\n if (overlappingObstacles.length > 0) {\n return true\n }\n\n // Compute node bounds\n const nodeLeft = node.center.x - node.width / 2\n const nodeRight = node.center.x + node.width / 2\n const nodeTop = node.center.y - node.height / 2\n const nodeBottom = node.center.y + node.height / 2\n\n // If node is outside the bounds, we consider it to contain an obstacle\n if (\n nodeLeft < this.srj.bounds.minX ||\n nodeRight > this.srj.bounds.maxX ||\n nodeTop < this.srj.bounds.minY ||\n nodeBottom > this.srj.bounds.maxY\n ) {\n return true\n }\n return false\n }\n\n /**\n * Checks if the entire node is contained within any obstacle.\n */\n isNodeCompletelyInsideObstacle(node: CapacityMeshNode): boolean {\n const overlappingObstacles = this.getXYZOverlappingObstacles(node)\n\n // Compute node bounds\n const nodeLeft = node.center.x - node.width / 2\n const nodeRight = node.center.x + node.width / 2\n const nodeTop = node.center.y - node.height / 2\n const nodeBottom = node.center.y + node.height / 2\n\n for (const obstacle of overlappingObstacles) {\n const obsLeft = obstacle.center.x - obstacle.width / 2\n const obsRight = obstacle.center.x + obstacle.width / 2\n const obsTop = obstacle.center.y - obstacle.height / 2\n const obsBottom = obstacle.center.y + obstacle.height / 2\n\n // Check if the node's bounds are completely inside the obstacle's bounds.\n if (\n nodeLeft >= obsLeft &&\n nodeRight <= obsRight &&\n nodeTop >= obsTop &&\n nodeBottom <= obsBottom\n ) {\n return true\n }\n }\n\n // if (\n // nodeRight < this.srj.bounds.minX ||\n // nodeLeft > this.srj.bounds.maxX ||\n // nodeBottom < this.srj.bounds.minY ||\n // nodeTop > this.srj.bounds.maxY\n // ) {\n // return true\n // }\n\n return false\n }\n\n getChildNodes(parent: CapacityMeshNode): CapacityMeshNode[] {\n if (parent._depth === this.MAX_DEPTH) return []\n const childNodes: CapacityMeshNode[] = []\n\n const childNodeSize = { width: parent.width / 2, height: parent.height / 2 }\n\n const childNodePositions = [\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n ]\n\n for (const position of childNodePositions) {\n const childNode: CapacityMeshNode = {\n capacityMeshNodeId: this.getNextNodeId(),\n center: position,\n width: childNodeSize.width,\n height: childNodeSize.height,\n layer: parent.layer,\n availableZ: [0, 1],\n _depth: (parent._depth ?? 0) + 1,\n _parent: parent,\n }\n childNode._containsObstacle = this.doesNodeOverlapObstacle(childNode)\n\n const target = this.getTargetIfNodeContainsTarget(childNode)\n\n if (target) {\n childNode._targetConnectionName = target.connectionName\n childNode.availableZ = target.availableZ\n childNode._containsTarget = true\n }\n\n if (childNode._containsObstacle) {\n childNode._completelyInsideObstacle =\n this.isNodeCompletelyInsideObstacle(childNode)\n }\n if (childNode._completelyInsideObstacle && !childNode._containsTarget)\n continue\n childNodes.push(childNode)\n }\n\n return childNodes\n }\n\n shouldNodeBeXYSubdivided(node: CapacityMeshNode) {\n if (node._depth! >= this.MAX_DEPTH) return false\n if (node._containsTarget) return true\n if (node._containsObstacle && !node._completelyInsideObstacle) return true\n return false\n }\n\n _step() {\n const nextNode = this.unfinishedNodes.pop()\n if (!nextNode) {\n this.solved = true\n return\n }\n\n const newNodes = this.getChildNodes(nextNode)\n\n const finishedNewNodes: CapacityMeshNode[] = []\n const unfinishedNewNodes: CapacityMeshNode[] = []\n\n for (const newNode of newNodes) {\n const shouldBeSubdivided = this.shouldNodeBeXYSubdivided(newNode)\n if (shouldBeSubdivided) {\n unfinishedNewNodes.push(newNode)\n } else if (!shouldBeSubdivided && !newNode._containsObstacle) {\n finishedNewNodes.push(newNode)\n } else if (!shouldBeSubdivided && newNode._containsTarget) {\n finishedNewNodes.push(newNode)\n }\n }\n\n this.unfinishedNodes.push(...unfinishedNewNodes)\n this.finishedNodes.push(...finishedNewNodes)\n }\n\n /**\n * Creates a GraphicsObject to visualize the mesh, its nodes, obstacles, and connection points.\n *\n * - Mesh nodes are rendered as rectangles.\n * - Nodes that have an obstacle intersection are outlined in red.\n * - Other nodes are outlined in green.\n * - Lines are drawn from a node to its parent.\n * - Obstacles are drawn as semi-transparent red rectangles.\n * - Points for each connection’s pointsToConnect are drawn in a unique color.\n */\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Capacity Mesh Visualization\",\n }\n\n // Draw obstacles\n for (const obstacle of this.srj.obstacles) {\n graphics.rects!.push({\n center: obstacle.center,\n width: obstacle.width,\n height: obstacle.height,\n fill:\n obstacle.zLayers?.length === 1 && obstacle.zLayers?.includes(1)\n ? \"rgba(0,0,255,0.3)\"\n : \"rgba(255,0,0,0.3)\",\n stroke: \"red\",\n label: [\"obstacle\", `z: ${obstacle.zLayers!.join(\",\")}`].join(\"\\n\"),\n })\n }\n\n // Draw mesh nodes (both finished and unfinished)\n const allNodes = [...this.finishedNodes, ...this.unfinishedNodes]\n for (const node of allNodes) {\n const lowestZ = Math.min(...node.availableZ)\n const isNextToBeProcessed =\n this.unfinishedNodes.length > 0 &&\n node === this.unfinishedNodes[this.unfinishedNodes.length - 1]\n\n graphics.rects!.push({\n center: {\n x: node.center.x + lowestZ * node.width * 0.05,\n y: node.center.y - lowestZ * node.width * 0.05,\n },\n width: Math.max(node.width - 2, node.width * 0.8),\n height: Math.max(node.height - 2, node.height * 0.8),\n fill: node._containsObstacle\n ? \"rgba(255,0,0,0.1)\"\n : ({\n \"0,1\": \"rgba(0,0,0,0.1)\",\n \"0\": \"rgba(0,200,200, 0.1)\",\n \"1\": \"rgba(0,0,200, 0.1)\",\n }[node.availableZ.join(\",\")] ?? \"rgba(0,200,200,0.1)\"),\n stroke: isNextToBeProcessed ? \"rgba(255,165,0,0.5)\" : undefined,\n label: [\n node.capacityMeshNodeId,\n `availableZ: ${node.availableZ.join(\",\")}`,\n `target? ${node._containsTarget ?? false}`,\n `obs? ${node._containsObstacle ?? false}`,\n ].join(\"\\n\"),\n })\n }\n graphics.rects!.sort((a, b) => a.center.y - b.center.y)\n\n // Draw connection points (each connection gets a unique color).\n this.srj.connections.forEach((connection, index) => {\n const color = COLORS[index % COLORS.length]\n for (const pt of connection.pointsToConnect) {\n graphics.points!.push({\n x: pt.x,\n y: pt.y,\n label: `conn-${index} (${pt.layer})`,\n color,\n })\n }\n })\n\n return graphics\n }\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n Obstacle,\n SimpleRouteJson,\n} from \"../../types\"\nimport { COLORS } from \"../colors\"\nimport { isPointInRect } from \"lib/utils/isPointInRect\"\nimport { doRectsOverlap } from \"lib/utils/doRectsOverlap\"\nimport { CapacityMeshNodeSolver } from \"./CapacityMeshNodeSolver1\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\n\ninterface CapacityMeshNodeSolverOptions {\n capacityDepth?: number\n}\n\ninterface Target {\n x: number\n y: number\n connectionName: string\n availableZ: number[]\n}\n\nexport class CapacityMeshNodeSolver2_NodeUnderObstacle extends CapacityMeshNodeSolver {\n constructor(\n public srj: SimpleRouteJson,\n public opts: CapacityMeshNodeSolverOptions = {},\n ) {\n super(srj, opts)\n }\n\n isNodeCompletelyOutsideBounds(node: CapacityMeshNode): boolean {\n return (\n node.center.x + node.width / 2 < this.srj.bounds.minX ||\n node.center.x - node.width / 2 > this.srj.bounds.maxX ||\n node.center.y + node.height / 2 < this.srj.bounds.minY ||\n node.center.y - node.height / 2 > this.srj.bounds.maxY\n )\n }\n\n isNodePartiallyOutsideBounds(node: CapacityMeshNode): boolean {\n return (\n node.center.x - node.width / 2 < this.srj.bounds.minX ||\n node.center.x + node.width / 2 > this.srj.bounds.maxX ||\n node.center.y - node.height / 2 < this.srj.bounds.minY ||\n node.center.y + node.height / 2 > this.srj.bounds.maxY\n )\n }\n createChildNodeAtPosition(\n parent: CapacityMeshNode,\n opts: {\n center: { x: number; y: number }\n width: number\n height: number\n availableZ: number[]\n _depth?: number\n },\n ): CapacityMeshNode {\n const childNode: CapacityMeshNode = {\n capacityMeshNodeId: this.getNextNodeId(),\n center: opts.center,\n width: opts.width,\n height: opts.height,\n layer: parent.layer,\n availableZ: opts.availableZ,\n _depth: opts._depth ?? (parent._depth ?? 0) + 1,\n _parent: parent,\n }\n\n const overlappingObstacles = this.getXYZOverlappingObstacles(childNode)\n\n childNode._containsObstacle =\n overlappingObstacles.length > 0 ||\n this.isNodePartiallyOutsideBounds(childNode)\n\n const target = this.getTargetIfNodeContainsTarget(childNode)\n\n if (target) {\n childNode._targetConnectionName = target.connectionName\n childNode._containsTarget = true\n }\n\n if (childNode._containsObstacle) {\n childNode._completelyInsideObstacle =\n this.isNodeCompletelyInsideObstacle(childNode)\n }\n // childNode._shouldBeInGraph =\n // (!isOutsideBounds && !childNode._completelyInsideObstacle) || childNode._\n\n return childNode\n }\n\n getZSubdivisionChildNodes(node: CapacityMeshNode): CapacityMeshNode[] {\n if (node.availableZ.length === 1) return []\n\n const childNodes: CapacityMeshNode[] = []\n\n // TODO when we have more than 2 layers, we need to handle other\n // variations, you always want to prioritize having larger contiguous\n // z-blocks\n const otherZBlocks = [[0], [1]]\n\n for (const zBlock of otherZBlocks) {\n const childNode = this.createChildNodeAtPosition(node, {\n center: { ...node.center },\n width: node.width,\n height: node.height,\n availableZ: zBlock,\n // z-subdivision doesn't count towards depth, should be same as parent\n _depth: node._depth!,\n })\n\n if (this.isNodeCompletelyOutsideBounds(childNode)) {\n continue\n }\n\n childNodes.push(childNode)\n }\n\n return childNodes\n }\n\n getChildNodes(parent: CapacityMeshNode): CapacityMeshNode[] {\n if (parent._depth! >= this.MAX_DEPTH) return []\n const childNodes: CapacityMeshNode[] = []\n\n const childNodeSize = { width: parent.width / 2, height: parent.height / 2 }\n\n const childNodePositions = [\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n ]\n\n for (const position of childNodePositions) {\n const childNode = this.createChildNodeAtPosition(parent, {\n center: position,\n width: childNodeSize.width,\n height: childNodeSize.height,\n availableZ: parent.availableZ,\n })\n if (this.isNodeCompletelyOutsideBounds(childNode)) {\n continue\n }\n childNodes.push(childNode)\n }\n\n return childNodes\n }\n\n shouldNodeBeXYSubdivided(node: CapacityMeshNode) {\n if (node._depth! >= this.MAX_DEPTH) return false\n if (node._containsTarget) return true\n if (node.availableZ.length === 1 && node._depth! <= this.MAX_DEPTH)\n return true\n if (node._containsObstacle && !node._completelyInsideObstacle) return true\n return false\n }\n\n _step() {\n const nextNode = this.unfinishedNodes.pop()\n if (!nextNode) {\n this.solved = true\n return\n }\n\n const childNodes = this.getChildNodes(nextNode)\n\n const finishedNewNodes: CapacityMeshNode[] = []\n const unfinishedNewNodes: CapacityMeshNode[] = []\n\n for (const childNode of childNodes) {\n const shouldBeXYSubdivided = this.shouldNodeBeXYSubdivided(childNode)\n const shouldBeZSubdivided =\n childNode.availableZ.length > 1 &&\n !shouldBeXYSubdivided &&\n childNode._containsObstacle\n if (shouldBeXYSubdivided) {\n unfinishedNewNodes.push(childNode)\n } else if (!shouldBeXYSubdivided && !childNode._containsObstacle) {\n finishedNewNodes.push(childNode)\n } else if (!shouldBeXYSubdivided && childNode._containsTarget) {\n if (shouldBeZSubdivided) {\n const zSubNodes = this.getZSubdivisionChildNodes(childNode)\n finishedNewNodes.push(\n ...zSubNodes.filter(\n (n) => n._containsTarget || !n._containsObstacle,\n ),\n )\n } else {\n finishedNewNodes.push(childNode)\n }\n } else if (shouldBeZSubdivided) {\n finishedNewNodes.push(\n ...this.getZSubdivisionChildNodes(childNode).filter(\n (zSubNode) => !zSubNode._containsObstacle,\n ),\n )\n }\n }\n\n this.unfinishedNodes.push(...unfinishedNewNodes)\n this.finishedNodes.push(...finishedNewNodes)\n }\n}\n","import type { CapacityMeshEdge, CapacityMeshNodeId } from \"../../types\"\n\nexport function getNodeEdgeMap(\n edges: CapacityMeshEdge[],\n): Map<CapacityMeshNodeId, CapacityMeshEdge[]> {\n const nodeEdgeMap = new Map<CapacityMeshNodeId, CapacityMeshEdge[]>()\n\n for (const edge of edges) {\n for (const nodeId of edge.nodeIds) {\n nodeEdgeMap.set(nodeId, [...(nodeEdgeMap.get(nodeId) ?? []), edge])\n }\n }\n\n return nodeEdgeMap\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n CapacityPath,\n} from \"../../types\"\nimport type { NodePortSegment } from \"../../types/capacity-edges-to-port-segments-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { getNodeEdgeMap } from \"./getNodeEdgeMap\"\nimport { safeTransparentize } from \"../colors\"\n\n/**\n * Each Node is a square. The capacity paths indicate the nodes the trace will\n * travel through. We want to find the \"Port Segment\" that each capacity path\n * will take for each node.\n */\nexport class CapacityEdgeToPortSegmentSolver extends BaseSolver {\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n capacityPaths: CapacityPath[]\n\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n nodeEdgeMap: Map<CapacityMeshNodeId, CapacityMeshEdge[]>\n\n unprocessedNodeIds: CapacityMeshNodeId[]\n\n nodePortSegments: Map<CapacityMeshNodeId, NodePortSegment[]>\n colorMap: Record<string, string>\n\n constructor({\n nodes,\n edges,\n capacityPaths,\n colorMap,\n }: {\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n capacityPaths: CapacityPath[]\n colorMap?: Record<string, string>\n }) {\n super()\n this.nodes = nodes\n this.edges = edges\n this.nodeMap = new Map(nodes.map((node) => [node.capacityMeshNodeId, node]))\n this.nodeEdgeMap = getNodeEdgeMap(edges)\n this.capacityPaths = capacityPaths\n this.colorMap = colorMap ?? {}\n\n // We will be evaluating capacity paths\n this.unprocessedNodeIds = [\n ...new Set(capacityPaths.flatMap((path) => path.nodeIds)),\n ]\n this.nodePortSegments = new Map()\n }\n\n step() {\n const nodeId = this.unprocessedNodeIds.pop()\n if (!nodeId) {\n this.solved = true\n return\n }\n\n const pathsGoingThroughNode: Array<{\n path: CapacityPath\n indexOfNodeInPath: number\n }> = []\n for (const path of this.capacityPaths) {\n const indexOfNodeInPath = path.nodeIds.indexOf(nodeId)\n if (indexOfNodeInPath !== -1) {\n pathsGoingThroughNode.push({ path, indexOfNodeInPath })\n }\n }\n\n const node = this.nodeMap.get(nodeId)!\n const nodePortSegments: NodePortSegment[] = []\n\n for (const { path, indexOfNodeInPath } of pathsGoingThroughNode) {\n const entryNodeId = path.nodeIds[indexOfNodeInPath - 1]\n const exitNodeId = path.nodeIds[indexOfNodeInPath + 1]\n\n for (const adjNodeId of [entryNodeId, exitNodeId]) {\n const adjNode = this.nodeMap.get(adjNodeId)!\n if (!adjNode) continue\n const segment = findOverlappingSegment(node, adjNode)\n\n const mutuallyAvailableZ = adjNode.availableZ.filter((z) =>\n node.availableZ.includes(z),\n )\n\n if (mutuallyAvailableZ.length === 0) continue\n\n const portSegment: NodePortSegment = {\n capacityMeshNodeId: nodeId,\n start: segment.start,\n end: segment.end,\n connectionNames: [path.connectionName],\n availableZ: mutuallyAvailableZ,\n }\n\n nodePortSegments.push(portSegment)\n }\n }\n\n // Combine overlapping or adjacent segments on the same edge.\n const combinedSegments = combineSegments(nodePortSegments)\n this.nodePortSegments.set(nodeId, combinedSegments)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n this.nodePortSegments.forEach((segments, nodeId) => {\n const node = this.nodeMap.get(nodeId)!\n segments.forEach((segment) => {\n const isVertical = segment.start.x === segment.end.x\n const THICKNESS = 0.1 / segment.connectionNames.length\n for (let i = 0; i < segment.connectionNames.length; i++) {\n const offsetAmount =\n (i / (segment.connectionNames.length - 1 + 0.000001) - 0.5) *\n THICKNESS\n const offset = {\n x: isVertical ? offsetAmount : 0,\n y: isVertical ? 0 : offsetAmount,\n }\n const trueSegmentCenter = {\n x: (segment.start.x + segment.end.x) / 2 + offset.x,\n y: (segment.start.y + segment.end.y) / 2 + offset.y,\n }\n graphics.rects!.push({\n center: {\n x: (trueSegmentCenter.x * 6 + node.center.x) / 7,\n y: (trueSegmentCenter.y * 6 + node.center.y) / 7,\n },\n width: isVertical\n ? THICKNESS\n : Math.abs(segment.end.x - segment.start.x),\n height: isVertical\n ? Math.abs(segment.end.y - segment.start.y)\n : THICKNESS,\n fill: safeTransparentize(\n this.colorMap[segment.connectionNames[i]],\n 0.6,\n ),\n label: `${nodeId}: ${segment.connectionNames.join(\", \")}\\navailableZ: ${segment.availableZ.join(\",\")}`,\n })\n }\n })\n })\n return graphics\n }\n}\n\nfunction findOverlappingSegment(\n node: CapacityMeshNode,\n adjNode: CapacityMeshNode,\n): { start: { x: number; y: number }; end: { x: number; y: number } } {\n // Find overlapping ranges in x and y dimensions\n const xOverlap = {\n start: Math.max(\n node.center.x - node.width / 2,\n adjNode.center.x - adjNode.width / 2,\n ),\n end: Math.min(\n node.center.x + node.width / 2,\n adjNode.center.x + adjNode.width / 2,\n ),\n }\n\n const yOverlap = {\n start: Math.max(\n node.center.y - node.height / 2,\n adjNode.center.y - adjNode.height / 2,\n ),\n end: Math.min(\n node.center.y + node.height / 2,\n adjNode.center.y + adjNode.height / 2,\n ),\n }\n\n const xRange = xOverlap.end - xOverlap.start\n const yRange = yOverlap.end - yOverlap.start\n\n // If the x-range is smaller then the nodes touch vertically (common vertical edge).\n if (xRange < yRange) {\n // They are horizontally adjacent: shared vertical edge.\n const x = (xOverlap.start + xOverlap.end) / 2\n return {\n start: { x, y: yOverlap.start },\n end: { x, y: yOverlap.end },\n }\n } else {\n // Otherwise, they are vertically adjacent: shared horizontal edge.\n const y = (yOverlap.start + yOverlap.end) / 2\n return {\n start: { x: xOverlap.start, y },\n end: { x: xOverlap.end, y },\n }\n }\n}\n\n/**\n * Given a list of segments on a node, merge segments that are overlapping\n */\nfunction combineSegments(segments: NodePortSegment[]): NodePortSegment[] {\n const mergedSegments: NodePortSegment[] = []\n const remainingSegments = [...segments]\n while (remainingSegments.length > 0) {\n const segmentUnderTest = remainingSegments.pop()!\n const overlappingMergedSegment = mergedSegments.find((segment) => {\n return (\n segment.start.x === segmentUnderTest.start.x &&\n segment.start.y === segmentUnderTest.start.y &&\n segment.end.x === segmentUnderTest.end.x &&\n segment.end.y === segmentUnderTest.end.y\n )\n })\n if (overlappingMergedSegment) {\n overlappingMergedSegment.connectionNames.push(\n ...segmentUnderTest.connectionNames,\n )\n } else {\n mergedSegments.push(segmentUnderTest)\n }\n }\n return mergedSegments\n}\n","import { BaseSolver } from \"../BaseSolver\"\nimport type { NodePortSegment } from \"../../types/capacity-edges-to-port-segments-types\"\nimport type { GraphicsObject, Line } from \"graphics-debug\"\nimport type { NodeWithPortPoints } from \"../../types/high-density-types\"\nimport type { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\n\nexport interface SegmentWithAssignedPoints extends NodePortSegment {\n assignedPoints?: {\n connectionName: string\n point: { x: number; y: number; z: number }\n }[]\n}\n\n/**\n * CapacitySegmentToPointSolver:\n *\n * In each step, the solver iterates over all unsolved segments (segments\n * without points assigned for each connection). For each segment:\n *\n * - If there is only one connection, it assigns the center as the point.\n * - If there are two connections, it attempts to determine the ordering using\n * other segments within the node. If no ordering can be determined, it does nothing.\n *\n * If an iteration produces no new assignments, the solver picks the segment with\n * the fewest connections and assigns points evenly spaced along the segment,\n * ordering them alphabetically.\n */\nexport class CapacitySegmentToPointSolver extends BaseSolver {\n unsolvedSegments: SegmentWithAssignedPoints[]\n solvedSegments: (NodePortSegment & {\n assignedPoints: {\n connectionName: string\n point: { x: number; y: number; z: number }\n }[]\n })[]\n nodeMap: Record<string, CapacityMeshNode>\n colorMap: Record<string, string>\n\n // We use an extra property on segments to remember assigned points.\n // Each segment will get an added property \"assignedPoints\" which is an array of:\n // { connectionName: string, point: {x: number, y: number } }\n // This is a temporary extension used by the solver.\n constructor({\n segments,\n colorMap,\n nodes,\n }: {\n segments: NodePortSegment[]\n colorMap?: Record<string, string>\n /**\n * This isn't used by the algorithm, but allows associating metadata\n * for the result datatype (the center, width, height of the node)\n */\n nodes: CapacityMeshNode[]\n }) {\n super()\n this.MAX_ITERATIONS = 100_000\n this.unsolvedSegments = segments\n this.solvedSegments = []\n this.colorMap = colorMap ?? {}\n this.nodeMap = Object.fromEntries(\n nodes.map((node) => [node.capacityMeshNodeId, node]),\n )\n }\n\n /**\n * Perform one iteration step.\n */\n _step() {\n let updated = false\n // unsolved segments: segments without complete assignments.\n const unsolved = [...this.unsolvedSegments]\n\n // Iterate over unsolved segments.\n for (const seg of unsolved) {\n const n = seg.connectionNames.length\n // Already processed? Skip if assignedPoints exists for all connections.\n if (\"assignedPoints\" in seg && seg.assignedPoints?.length === n) continue\n\n if (n === 1) {\n // For a single connection, assign the center of the segment.\n const center = {\n x: (seg.start.x + seg.end.x) / 2,\n y: (seg.start.y + seg.end.y) / 2,\n z: seg.availableZ[0],\n }\n ;(seg as any).assignedPoints = [\n { connectionName: seg.connectionNames[0], point: center },\n ]\n // Move seg from unsolvedSegments to solvedSegments.\n this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(seg), 1)\n this.solvedSegments.push(seg as any)\n updated = true\n }\n }\n\n // If no segments were updated in this iteration, perform a fallback.\n if (!updated && unsolved.length > 0) {\n // Choose the unsolved segment with the fewest connections.\n let candidate = unsolved[0]\n for (const seg of unsolved) {\n if (seg.connectionNames.length < candidate.connectionNames.length) {\n candidate = seg\n }\n }\n // Fallback: assign points evenly spaced along the segment,\n // after sorting connection names alphabetically.\n const sortedConnections = [...candidate.connectionNames].sort()\n const dx = candidate.end.x - candidate.start.x\n const dy = candidate.end.y - candidate.start.y\n const n = sortedConnections.length\n const points: { x: number; y: number; z: number }[] = []\n // Evenly space positions using fractions of the segment distance.\n for (let i = 1; i <= n; i++) {\n const fraction = i / (n + 1)\n points.push({\n x: candidate.start.x + dx * fraction,\n y: candidate.start.y + dy * fraction,\n z: candidate.availableZ[0],\n })\n }\n ;(candidate as any).assignedPoints = sortedConnections.map(\n (conn, idx) => ({\n connectionName: conn,\n point: points[idx],\n }),\n )\n // Move candidate from unsolvedSegments to solvedSegments.\n this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(candidate), 1)\n this.solvedSegments.push(candidate as any)\n updated = true\n }\n\n // If all segments have been assigned points, mark solved.\n if (this.unsolvedSegments.length === 0) {\n this.solved = true\n }\n }\n\n /**\n * Return the assigned points for each segment.\n */\n getNodesWithPortPoints(): NodeWithPortPoints[] {\n if (!this.solved) {\n throw new Error(\n \"CapacitySegmentToPointSolver not solved, can't give port points yet\",\n )\n }\n const map = new Map<string, NodeWithPortPoints>()\n for (const seg of this.solvedSegments) {\n const nodeId = seg.capacityMeshNodeId\n const node = this.nodeMap[nodeId]\n if (!map.has(nodeId)) {\n map.set(nodeId, {\n capacityMeshNodeId: nodeId,\n portPoints: [],\n center: node.center,\n width: node.width,\n height: node.height,\n })\n }\n map.get(nodeId)!.portPoints.push(\n ...seg.assignedPoints.map((ap) => ({\n ...ap.point,\n connectionName: ap.connectionName,\n })),\n )\n }\n return Array.from(map.values())\n }\n\n /**\n * Return a GraphicsObject that visualizes the segments with assigned points.\n */\n visualize(): GraphicsObject {\n const graphics = {\n points: this.solvedSegments.flatMap((seg) =>\n seg.assignedPoints.map((ap) => ({\n x: ap.point.x,\n y: ap.point.y,\n label: [\n `${seg.capacityMeshNodeId}-${ap.connectionName}`,\n `z: ${seg.availableZ.join(\",\")}`,\n ].join(\"\\n\"),\n color: this.colorMap[ap.connectionName],\n step: 4,\n })),\n ),\n lines: this.solvedSegments.map((seg) => ({\n points: [seg.start, seg.end],\n step: 4,\n })),\n rects: [],\n circles: [],\n }\n\n // Add a dashed line connecting the assignment points with the same\n // connection name within the same node\n const dashedLines: Line[] = []\n const nodeConnections: Record<\n CapacityMeshNodeId,\n Record<string, { x: number; y: number }[]>\n > = {}\n for (const seg of this.solvedSegments) {\n const nodeId = seg.capacityMeshNodeId\n if (!nodeConnections[nodeId]) {\n nodeConnections[nodeId] = {}\n }\n for (const ap of seg.assignedPoints) {\n if (!nodeConnections[nodeId][ap.connectionName]) {\n nodeConnections[nodeId][ap.connectionName] = []\n }\n nodeConnections[nodeId][ap.connectionName].push({\n x: ap.point.x,\n y: ap.point.y,\n })\n }\n }\n for (const nodeId in nodeConnections) {\n for (const conn in nodeConnections[nodeId]) {\n const points = nodeConnections[nodeId][conn]\n if (points.length > 1) {\n dashedLines.push({\n points,\n step: 4,\n strokeDash: \"5 5\",\n strokeColor: this.colorMap[conn] || \"#000\",\n } as Line)\n }\n }\n }\n graphics.lines.push(...(dashedLines as any))\n\n return graphics\n }\n}\n","import { BaseSolver } from \"../BaseSolver\"\nimport type { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport {\n distance,\n pointToSegmentDistance,\n doSegmentsIntersect,\n} from \"@tscircuit/math-utils\"\nimport type { GraphicsObject } from \"graphics-debug\"\nimport { HighDensityHyperParameters } from \"./HighDensityHyperParameters\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\n\nexport type FutureConnection = {\n connectionName: string\n points: { x: number; y: number }[]\n}\n\nexport type Node = {\n x: number\n y: number\n z: number\n\n g: number\n h: number\n f: number\n\n parent: Node | null\n}\n\nexport class SingleHighDensityRouteSolver extends BaseSolver {\n obstacleRoutes: HighDensityIntraNodeRoute[]\n bounds: { minX: number; maxX: number; minY: number; maxY: number }\n boundsSize: { width: number; height: number }\n boundsCenter: { x: number; y: number }\n A: { x: number; y: number; z: number }\n B: { x: number; y: number; z: number }\n straightLineDistance: number\n\n viaDiameter: number\n traceThickness: number\n obstacleMargin: number\n layerCount: number\n minCellSize = 0.05\n cellStep = 0.05\n GREEDY_MULTIPLER = 1.1\n numRoutes: number\n\n VIA_PENALTY_FACTOR = 0.3\n CELL_SIZE_FACTOR: number\n\n exploredNodes: Set<string>\n\n candidates: Node[]\n\n connectionName: string\n solvedPath: HighDensityIntraNodeRoute | null = null\n\n futureConnections: FutureConnection[]\n hyperParameters: Partial<HighDensityHyperParameters>\n\n connMap?: ConnectivityMap\n\n /** For debugging/animating the exploration */\n debug_exploredNodesOrdered: string[]\n debug_nodesTooCloseToObstacle: Set<string>\n debug_nodePathToParentIntersectsObstacle: Set<string>\n\n debugEnabled = true\n\n constructor(opts: {\n connectionName: string\n obstacleRoutes: HighDensityIntraNodeRoute[]\n minDistBetweenEnteringPoints: number\n bounds: { minX: number; maxX: number; minY: number; maxY: number }\n A: { x: number; y: number; z: number }\n B: { x: number; y: number; z: number }\n viaDiameter?: number\n traceThickness?: number\n obstacleMargin?: number\n layerCount?: number\n futureConnections?: FutureConnection[]\n hyperParameters?: Partial<HighDensityHyperParameters>\n connMap?: ConnectivityMap\n }) {\n super()\n this.bounds = opts.bounds\n this.connMap = opts.connMap\n this.hyperParameters = opts.hyperParameters ?? {}\n this.CELL_SIZE_FACTOR = this.hyperParameters.CELL_SIZE_FACTOR ?? 1\n this.boundsSize = {\n width: this.bounds.maxX - this.bounds.minX,\n height: this.bounds.maxY - this.bounds.minY,\n }\n this.boundsCenter = {\n x: (this.bounds.minX + this.bounds.maxX) / 2,\n y: (this.bounds.minY + this.bounds.maxY) / 2,\n }\n this.connectionName = opts.connectionName\n this.obstacleRoutes = opts.obstacleRoutes\n this.A = opts.A\n this.B = opts.B\n this.viaDiameter = opts.viaDiameter ?? 0.6\n this.traceThickness = opts.traceThickness ?? 0.15\n this.obstacleMargin = opts.obstacleMargin ?? 0.2\n this.layerCount = opts.layerCount ?? 2\n this.exploredNodes = new Set()\n this.candidates = [\n {\n ...opts.A,\n z: opts.A.z ?? 0,\n g: 0,\n h: 0,\n f: 0,\n parent: null,\n },\n ]\n this.straightLineDistance = distance(this.A, this.B)\n this.futureConnections = opts.futureConnections ?? []\n this.MAX_ITERATIONS = 5000\n\n this.debug_exploredNodesOrdered = []\n this.debug_nodesTooCloseToObstacle = new Set()\n this.debug_nodePathToParentIntersectsObstacle = new Set()\n this.numRoutes = this.obstacleRoutes.length + this.futureConnections.length\n const bestRowOrColumnCount = Math.ceil(5 * (this.numRoutes + 1))\n let numXCells = this.boundsSize.width / this.cellStep\n let numYCells = this.boundsSize.height / this.cellStep\n\n while (numXCells * numYCells > bestRowOrColumnCount ** 2) {\n if (this.cellStep * 2 > opts.minDistBetweenEnteringPoints) {\n break\n }\n this.cellStep *= 2\n numXCells = this.boundsSize.width / this.cellStep\n numYCells = this.boundsSize.height / this.cellStep\n }\n\n this.cellStep *= this.CELL_SIZE_FACTOR\n\n if (\n this.futureConnections &&\n this.futureConnections.length === 0 &&\n this.obstacleRoutes.length === 0\n ) {\n this.handleSimpleCases()\n }\n }\n\n handleSimpleCases() {\n this.solved = true\n const { A, B } = this\n const route =\n A.z === B.z\n ? [A, B]\n : [\n A,\n { ...this.boundsCenter, z: this.A.z },\n {\n ...this.boundsCenter,\n z: B.z,\n },\n B,\n ]\n this.solvedPath = {\n connectionName: this.connectionName,\n route,\n traceThickness: this.traceThickness,\n viaDiameter: this.viaDiameter,\n vias: this.A.z === this.B.z ? [] : [this.boundsCenter],\n }\n }\n\n get viaPenaltyDistance() {\n return this.cellStep + this.straightLineDistance * this.VIA_PENALTY_FACTOR\n }\n\n isNodeTooCloseToObstacle(node: Node, margin?: number, isVia?: boolean) {\n margin ??= this.obstacleMargin\n\n if (isVia && node.parent) {\n const viasInMyRoute = this.getViasInNodePath(node.parent)\n for (const via of viasInMyRoute) {\n if (distance(node, via) < this.viaDiameter / 2 + margin) {\n return true\n }\n }\n }\n\n for (const route of this.obstacleRoutes) {\n const connectedToObstacle = this.connMap?.areIdsConnected?.(\n this.connectionName,\n route.connectionName,\n )\n\n if (!connectedToObstacle) {\n const pointPairs = getSameLayerPointPairs(route)\n for (const pointPair of pointPairs) {\n if (\n (isVia || pointPair.z === node.z) &&\n pointToSegmentDistance(node, pointPair.A, pointPair.B) <\n this.traceThickness + margin\n ) {\n return true\n }\n }\n }\n for (const via of route.vias) {\n if (distance(node, via) < this.viaDiameter / 2 + margin) {\n return true\n }\n }\n }\n\n return false\n }\n\n isNodeTooCloseToEdge(node: Node, isVia?: boolean) {\n const margin = isVia ? this.viaDiameter / 2 : this.obstacleMargin\n const tooClose =\n node.x < this.bounds.minX + margin ||\n node.x > this.bounds.maxX - margin ||\n node.y < this.bounds.minY + margin ||\n node.y > this.bounds.maxY - margin\n if (tooClose && !isVia) {\n // If it's close to B or A it's an exception\n if (\n distance(node, this.B) < margin * 2 ||\n distance(node, this.A) < margin * 2\n ) {\n return false\n }\n }\n return tooClose\n }\n\n doesPathToParentIntersectObstacle(node: Node) {\n const parent = node.parent\n if (!parent) return false\n for (const route of this.obstacleRoutes) {\n const obstacleIsConnectedToNewPath = this.connMap?.areIdsConnected?.(\n this.connectionName,\n route.connectionName,\n )\n if (obstacleIsConnectedToNewPath) continue\n for (const pointPair of getSameLayerPointPairs(route)) {\n if (pointPair.z !== node.z) continue\n if (doSegmentsIntersect(node, parent, pointPair.A, pointPair.B)) {\n return true\n }\n }\n }\n return false\n }\n\n computeH(node: Node) {\n return (\n distance(node, this.B) +\n // via penalty\n Math.abs(node.z - this.B.z) * this.viaPenaltyDistance\n )\n }\n\n computeG(node: Node) {\n return (\n (node.parent?.g ?? 0) +\n (node.z === 0 ? 0 : this.viaPenaltyDistance) +\n distance(node, node.parent!)\n )\n }\n\n computeF(g: number, h: number) {\n return g + h * this.GREEDY_MULTIPLER\n }\n\n getNodeKey(node: Node) {\n return `${Math.round(node.x / this.cellStep) * this.cellStep},${Math.round(node.y / this.cellStep) * this.cellStep},${node.z}`\n }\n\n getNeighbors(node: Node) {\n const neighbors: Node[] = []\n\n const { maxX, minX, maxY, minY } = this.bounds\n\n for (let x = -1; x <= 1; x++) {\n for (let y = -1; y <= 1; y++) {\n if (x === 0 && y === 0) continue\n\n const neighbor = {\n ...node,\n parent: node,\n x: clamp(node.x + x * this.cellStep, minX, maxX),\n y: clamp(node.y + y * this.cellStep, minY, maxY),\n }\n\n const neighborKey = this.getNodeKey(neighbor)\n\n if (this.exploredNodes.has(neighborKey)) {\n continue\n }\n\n if (this.isNodeTooCloseToObstacle(neighbor)) {\n this.debug_nodesTooCloseToObstacle.add(neighborKey)\n this.exploredNodes.add(neighborKey)\n continue\n }\n\n if (this.isNodeTooCloseToEdge(neighbor, false)) {\n this.exploredNodes.add(neighborKey)\n continue\n }\n\n if (this.doesPathToParentIntersectObstacle(neighbor)) {\n this.debug_nodePathToParentIntersectsObstacle.add(neighborKey)\n this.exploredNodes.add(neighborKey)\n continue\n }\n\n neighbor.g = this.computeG(neighbor)\n neighbor.h = this.computeH(neighbor)\n neighbor.f = this.computeF(neighbor.g, neighbor.h)\n\n neighbors.push(neighbor)\n }\n }\n\n const viaNeighbor = {\n ...node,\n parent: node,\n z: node.z === 0 ? this.layerCount - 1 : 0,\n }\n\n if (\n !this.exploredNodes.has(this.getNodeKey(viaNeighbor)) &&\n !this.isNodeTooCloseToObstacle(\n viaNeighbor,\n this.viaDiameter / 2 + this.obstacleMargin / 2,\n true,\n ) &&\n !this.isNodeTooCloseToEdge(viaNeighbor, true)\n ) {\n viaNeighbor.g = this.computeG(viaNeighbor)\n viaNeighbor.h = this.computeH(viaNeighbor)\n viaNeighbor.f = this.computeF(viaNeighbor.g, viaNeighbor.h)\n\n neighbors.push(viaNeighbor)\n }\n\n return neighbors\n }\n\n getNodePath(node: Node) {\n const path: Node[] = []\n while (node) {\n path.push(node)\n node = node.parent!\n }\n return path\n }\n\n getViasInNodePath(node: Node) {\n const path = this.getNodePath(node)\n const vias: { x: number; y: number }[] = []\n for (let i = 0; i < path.length - 1; i++) {\n if (path[i].z !== path[i + 1].z) {\n vias.push({ x: path[i].x, y: path[i].y })\n }\n }\n return vias\n }\n\n setSolvedPath(node: Node) {\n const path = this.getNodePath(node)\n path.reverse()\n\n const vias: { x: number; y: number }[] = []\n for (let i = 0; i < path.length - 1; i++) {\n if (path[i].z !== path[i + 1].z) {\n vias.push({ x: path[i].x, y: path[i].y })\n }\n }\n\n this.solvedPath = {\n connectionName: this.connectionName,\n traceThickness: this.traceThickness,\n viaDiameter: this.viaDiameter,\n route: path\n .map((node) => ({ x: node.x, y: node.y, z: node.z }))\n .concat([this.B]),\n vias,\n }\n }\n\n computeProgress(currentNode: Node, goalDist: number, isOnLayer: boolean) {\n if (!isOnLayer) goalDist += this.viaPenaltyDistance\n const goalDistPercent = 1 - goalDist / this.straightLineDistance\n\n // This is a perfectly acceptable progress metric\n // return Math.max(this.progress || 0, goalDistPercent)\n\n // Linearize because it typically gets harder towards the end\n return Math.max(\n this.progress || 0,\n // 0.112 = ~90% -> 50%\n // ~25% -> 2%\n // ~99% -> 94%\n // ~95% -> 72%\n (2 / Math.PI) *\n Math.atan((0.112 * goalDistPercent) / (1 - goalDistPercent)),\n )\n }\n\n _step() {\n this.candidates.sort((a, b) => b.f - a.f)\n let currentNode = this.candidates.pop()\n\n while (\n currentNode &&\n this.exploredNodes.has(this.getNodeKey(currentNode))\n ) {\n currentNode = this.candidates.pop()\n }\n\n if (!currentNode) {\n this.failed = true\n return\n }\n this.exploredNodes.add(this.getNodeKey(currentNode))\n this.debug_exploredNodesOrdered.push(this.getNodeKey(currentNode))\n\n const goalDist = distance(currentNode, this.B)\n\n this.progress = this.computeProgress(\n currentNode,\n goalDist,\n currentNode.z === this.B.z,\n )\n\n if (goalDist <= this.cellStep && currentNode.z === this.B.z) {\n this.solved = true\n this.setSolvedPath(currentNode)\n }\n\n const neighbors = this.getNeighbors(currentNode)\n for (const neighbor of neighbors) {\n this.candidates.push(neighbor)\n }\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n\n // Display the input port points (from nodeWithPortPoints via A and B)\n graphics.points!.push({\n x: this.A.x,\n y: this.A.y,\n label: `Input A\\nz: ${this.A.z}`,\n color: \"orange\",\n })\n graphics.points!.push({\n x: this.B.x,\n y: this.B.y,\n label: `Input B\\nz: ${this.B.z}`,\n color: \"orange\",\n })\n\n // Draw circles at future connection points\n // if (\"FUTURE_CONNECTION_PROXIMITY_VD\" in this) {\n // for (const futureConnection of this.futureConnections) {\n // for (const point of futureConnection.points) {\n // graphics.circles!.push({\n // center: point,\n // radius:\n // (this.viaDiameter *\n // (this.FUTURE_CONNECTION_PROXIMITY_VD as number)) /\n // 2,\n // // strokeColor: \"rgba(0, 255, 0, 0.3)\",\n // stroke: \"rgba(0,255,0,0.1)\",\n // label: `Future Connection: ${futureConnection.connectionName}`,\n // })\n // }\n // }\n // // Draw circles around obstacle route points\n // for (const route of this.obstacleRoutes) {\n // for (const point of [\n // route.route[0],\n // route.route[route.route.length - 1],\n // ]) {\n // graphics.circles!.push({\n // center: point,\n // radius:\n // (this.viaDiameter *\n // (this.FUTURE_CONNECTION_PROXIMITY_VD as number)) /\n // 2,\n // stroke: \"rgba(255,0,0,0.1)\",\n // label: \"Obstacle Route Point\",\n // })\n // }\n // }\n // }\n\n // Draw a line representing the direct connection between the input port points\n graphics.lines!.push({\n points: [this.A, this.B],\n strokeColor: \"rgba(255, 0, 0, 0.5)\",\n label: \"Direct Input Connection\",\n })\n\n // Show any obstacle routes as background references\n for (\n let routeIndex = 0;\n routeIndex < this.obstacleRoutes.length;\n routeIndex++\n ) {\n const route = this.obstacleRoutes[routeIndex]\n for (let i = 0; i < route.route.length - 1; i++) {\n const z = route.route[i].z\n graphics.lines!.push({\n points: [route.route[i], route.route[i + 1]],\n strokeColor:\n z === 0 ? \"rgba(255, 0, 0, 0.75)\" : \"rgba(255, 128, 0, 0.25)\",\n strokeWidth: route.traceThickness,\n label: \"Obstacle Route\",\n layer: `obstacle${routeIndex.toString()}`,\n })\n }\n }\n\n // Optionally, visualize explored nodes for debugging purposes\n for (let i = 0; i < this.debug_exploredNodesOrdered.length; i++) {\n const nodeKey = this.debug_exploredNodesOrdered[i]\n const [x, y, z] = nodeKey.split(\",\").map(Number)\n if (this.debug_nodesTooCloseToObstacle.has(nodeKey)) continue\n if (this.debug_nodePathToParentIntersectsObstacle.has(nodeKey)) continue\n graphics.rects!.push({\n center: {\n x: x + (z * this.cellStep) / 20,\n y: y + (z * this.cellStep) / 20,\n },\n fill:\n z === 0\n ? `rgba(255,0,255,${0.3 - (i / this.debug_exploredNodesOrdered.length) * 0.2})`\n : `rgba(0,0,255,${0.3 - (i / this.debug_exploredNodesOrdered.length) * 0.2})`,\n width: this.cellStep * 0.9,\n height: this.cellStep * 0.9,\n label: `Explored (z=${z})`,\n })\n }\n\n // Visualize vias from obstacle routes\n for (const route of this.obstacleRoutes) {\n for (const via of route.vias) {\n graphics.circles!.push({\n center: {\n x: via.x,\n y: via.y,\n },\n radius: this.viaDiameter / 2,\n fill: \"rgba(255, 0, 0, 0.5)\",\n label: \"Via\",\n })\n }\n }\n // If a solved route exists, display it along with via markers\n if (this.solvedPath) {\n graphics.lines!.push({\n points: this.solvedPath.route,\n strokeColor: \"green\",\n label: \"Solved Route\",\n })\n for (const via of this.solvedPath.vias) {\n graphics.circles!.push({\n center: via,\n radius: this.viaDiameter / 2,\n fill: \"green\",\n label: \"Via\",\n })\n }\n }\n\n return graphics\n }\n}\n\nfunction getSameLayerPointPairs(route: HighDensityIntraNodeRoute) {\n const pointPairs: {\n z: number\n A: { x: number; y: number; z: number }\n B: { x: number; y: number; z: number }\n }[] = []\n\n for (let i = 0; i < route.route.length - 1; i++) {\n if (route.route[i].z === route.route[i + 1].z) {\n pointPairs.push({\n z: route.route[i].z,\n A: route.route[i],\n B: route.route[i + 1],\n })\n }\n }\n\n return pointPairs\n}\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(value, max))\n}\n","import { distance } from \"@tscircuit/math-utils\"\nimport {\n SingleHighDensityRouteSolver,\n type Node,\n} from \"./SingleHighDensityRouteSolver\"\n\nexport class SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost extends SingleHighDensityRouteSolver {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR = 2\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR = 1\n FUTURE_CONNECTION_PROXIMITY_VD = 10\n MISALIGNED_DIST_PENALTY_FACTOR = 5\n VIA_PENALTY_FACTOR_2 = 1\n FLIP_TRACE_ALIGNMENT_DIRECTION = false\n\n constructor(\n opts: ConstructorParameters<typeof SingleHighDensityRouteSolver>[0],\n ) {\n super(opts)\n for (const key in opts.hyperParameters) {\n // @ts-ignore\n this[key] = opts.hyperParameters[key]\n }\n\n // Ratio of available space determines via penalty\n const viasThatCanFitHorz = this.boundsSize.width / this.viaDiameter\n this.VIA_PENALTY_FACTOR =\n 0.3 * (viasThatCanFitHorz / this.numRoutes) * this.VIA_PENALTY_FACTOR_2\n }\n\n getClosestFutureConnectionPoint(node: Node) {\n let minDist = Infinity\n let closestPoint = null\n\n for (const futureConnection of this.futureConnections) {\n for (const point of futureConnection.points) {\n const dist = distance(node, point)\n if (dist < minDist) {\n minDist = dist\n closestPoint = point\n }\n }\n }\n\n return closestPoint\n }\n\n /**\n * Rapidly approaches 0 as the goal distance approaches 0\n */\n diminishCloseToGoal(node: Node) {\n const goalDist = distance(node, this.B)\n return 1 - Math.exp((-goalDist / this.straightLineDistance) * 5)\n }\n\n getFutureConnectionPenalty(node: Node, isVia: boolean) {\n let futureConnectionPenalty = 0\n const closestFuturePoint = this.getClosestFutureConnectionPoint(node)\n const goalDist = distance(node, this.B)\n if (closestFuturePoint) {\n const distToFuturePoint = distance(node, closestFuturePoint)\n if (goalDist <= distToFuturePoint) return 0\n const maxDist = this.viaDiameter * this.FUTURE_CONNECTION_PROXIMITY_VD\n const distRatio = distToFuturePoint / maxDist\n const maxPenalty = isVia\n ? this.straightLineDistance *\n this.FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR\n : this.straightLineDistance *\n this.FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR\n futureConnectionPenalty = maxPenalty * Math.exp(-distRatio * 5)\n }\n return futureConnectionPenalty\n }\n\n computeH(node: Node) {\n const goalDist = distance(node, this.B) ** 1.6\n const goalDistRatio = goalDist / this.straightLineDistance\n\n // Base cost from original function\n const baseCost =\n goalDist + (node.z !== this.B.z ? this.viaPenaltyDistance : 0)\n\n return (\n baseCost +\n this.getFutureConnectionPenalty(node, node.z !== node.parent?.z)\n )\n }\n\n computeG(node: Node) {\n const dx = Math.abs(node.x - node.parent!.x)\n const dy = Math.abs(node.y - node.parent!.y)\n const dist = Math.sqrt(dx ** 2 + dy ** 2)\n\n const misalignedDist = !this.FLIP_TRACE_ALIGNMENT_DIRECTION\n ? node.z === 0\n ? dy\n : dx\n : node.z === 0\n ? dx\n : dy\n\n // Base cost from original function\n const baseCost =\n (node.parent?.g ?? 0) +\n (node.z === node.parent?.z ? 0 : this.viaPenaltyDistance) +\n dist +\n misalignedDist * this.MISALIGNED_DIST_PENALTY_FACTOR\n\n return (\n baseCost +\n this.getFutureConnectionPenalty(node, node.z !== node.parent?.z)\n )\n }\n}\n","export function seededRandom(seed: number) {\n // Use a simple hash to initialize both state variables\n let s = seed\n for (let i = 0; i < 10; i++) {\n s = (s * 16807) % 2147483647\n }\n let state0 = s\n\n // Use a different hash for the second state\n s = (seed * 69069 + 1) % 2147483647\n for (let i = 0; i < 10; i++) {\n s = (s * 48271) % 2147483647\n }\n let state1 = s\n\n // Return the function that generates random numbers\n return () => {\n // xorshift128+ algorithm produces much better randomness than LCG\n let s1 = state0\n const s0 = state1\n\n state0 = s0\n s1 ^= s1 << 23\n s1 ^= s1 >>> 17\n s1 ^= s0\n s1 ^= s0 >>> 26\n state1 = s1\n\n // Generate a number between 0 and 1\n const result = (state0 + state1) / 4294967296\n return result - Math.floor(result)\n }\n}\n\nexport function cloneAndShuffleArray<T>(arr: T[], seed: number): T[] {\n if (seed === 0) return arr\n const random = seededRandom(seed)\n // if (arr.length === 2) {\n // console.log(random(), seed)\n // if (random() > 0.5) return arr.slice()\n // return [arr[1], arr[0]]\n // }\n const shuffled = arr.slice() // Copy the array\n for (let i = 0; i < shuffled.length; i++) {\n const i1 = Math.floor(random() * shuffled.length)\n const i2 = Math.floor(random() * (i + 1))\n ;[shuffled[i1], shuffled[i2]] = [shuffled[i2], shuffled[i1]]\n }\n return shuffled\n}\n","import { NodeWithPortPoints } from \"lib/types/high-density-types\"\n\nexport function getBoundsFromNodeWithPortPoints(\n nodeWithPortPoints: NodeWithPortPoints,\n): { minX: number; maxX: number; minY: number; maxY: number } {\n const bounds = {\n minX: nodeWithPortPoints.center.x - nodeWithPortPoints.width / 2,\n maxX: nodeWithPortPoints.center.x + nodeWithPortPoints.width / 2,\n minY: nodeWithPortPoints.center.y - nodeWithPortPoints.height / 2,\n maxY: nodeWithPortPoints.center.y + nodeWithPortPoints.height / 2,\n }\n\n // Sometimes port points may be outside the node- this happens when there's\n // a \"leap\" to the final target or at the end or beginning of a trace when\n // we're wrapping up\n for (const pt of nodeWithPortPoints.portPoints) {\n if (pt.x < bounds.minX) {\n bounds.minX = pt.x\n }\n if (pt.x > bounds.maxX) {\n bounds.maxX = pt.x\n }\n if (pt.y < bounds.minY) {\n bounds.minY = pt.y\n }\n if (pt.y > bounds.maxY) {\n bounds.maxY = pt.y\n }\n }\n\n return bounds\n}\n","import { NodeWithPortPoints } from \"lib/types/high-density-types\"\n\nexport const getMinDistBetweenEnteringPoints = (node: NodeWithPortPoints) => {\n let minDist = Infinity\n const points = node.portPoints\n\n // Compare each point with every other point\n for (let i = 0; i < points.length; i++) {\n for (let j = i + 1; j < points.length; j++) {\n const p1 = points[i]\n const p2 = points[j]\n\n // Calculate Euclidean distance between points\n const dist = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2)\n\n minDist = Math.min(minDist, dist)\n }\n }\n\n return minDist === Infinity ? 0 : minDist\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport type {\n HighDensityIntraNodeRoute,\n NodeWithPortPoints,\n} from \"../../types/high-density-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { SingleHighDensityRouteSolver } from \"./SingleHighDensityRouteSolver\"\nimport { safeTransparentize } from \"../colors\"\nimport { SingleHighDensityRouteSolver2_CenterAttraction } from \"./SingleHighDensityRouteSolver2_CenterAttraction\"\nimport { SingleHighDensityRouteSolver3_RepelEndpoints } from \"./SingleHighDensityRouteSolver3_RepellingEndpoints\"\nimport { SingleHighDensityRouteSolver4_RepelEdgeViaFuture } from \"./SingleHighDensityRouteSolver4_RepelEdgeViaFuture\"\nimport { SingleHighDensityRouteSolver5_BinaryFutureConnectionPenalty } from \"./SingleHighDensityRouteSolver5_BinaryFutureConnectionPenalty\"\nimport { SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost } from \"./SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost\"\nimport { HighDensityHyperParameters } from \"./HighDensityHyperParameters\"\nimport { cloneAndShuffleArray } from \"lib/utils/cloneAndShuffleArray\"\nimport { SingleHighDensityRouteSolver7_CostPoint } from \"./SingleHighDensityRouteSolver7_CostPoint\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { getBoundsFromNodeWithPortPoints } from \"lib/utils/getBoundsFromNodeWithPortPoints\"\nimport { getIntraNodeCrossings } from \"lib/utils/getIntraNodeCrossings\"\nimport { getMinDistBetweenEnteringPoints } from \"lib/utils/getMinDistBetweenEnteringPoints\"\n\nexport class IntraNodeRouteSolver extends BaseSolver {\n nodeWithPortPoints: NodeWithPortPoints\n colorMap: Record<string, string>\n unsolvedConnections: {\n connectionName: string\n points: { x: number; y: number; z: number }[]\n }[]\n\n totalConnections: number\n solvedRoutes: HighDensityIntraNodeRoute[]\n failedSubSolvers: SingleHighDensityRouteSolver[]\n hyperParameters: Partial<HighDensityHyperParameters>\n minDistBetweenEnteringPoints: number\n\n activeSolver: SingleHighDensityRouteSolver | null = null\n connMap?: ConnectivityMap\n\n // Legacy compat\n get failedSolvers() {\n return this.failedSubSolvers\n }\n\n constructor(params: {\n nodeWithPortPoints: NodeWithPortPoints\n colorMap?: Record<string, string>\n hyperParameters?: Partial<HighDensityHyperParameters>\n connMap?: ConnectivityMap\n }) {\n const { nodeWithPortPoints, colorMap } = params\n super()\n this.nodeWithPortPoints = nodeWithPortPoints\n this.colorMap = colorMap ?? {}\n this.solvedRoutes = []\n this.hyperParameters = params.hyperParameters ?? {}\n this.failedSubSolvers = []\n this.connMap = params.connMap\n const unsolvedConnectionsMap: Map<\n string,\n { x: number; y: number; z: number }[]\n > = new Map()\n for (const { connectionName, x, y, z } of nodeWithPortPoints.portPoints) {\n unsolvedConnectionsMap.set(connectionName, [\n ...(unsolvedConnectionsMap.get(connectionName) ?? []),\n { x, y, z: z ?? 0 },\n ])\n }\n console.log({ unsolvedConnectionsMap })\n this.unsolvedConnections = Array.from(\n unsolvedConnectionsMap.entries().map(([connectionName, points]) => ({\n connectionName,\n points,\n })),\n )\n\n if (this.hyperParameters.SHUFFLE_SEED) {\n this.unsolvedConnections = cloneAndShuffleArray(\n this.unsolvedConnections,\n this.hyperParameters.SHUFFLE_SEED ?? 0,\n )\n\n // Shuffle the starting and ending points of each connection (some\n // algorithms are biased towards the start or end of a trace)\n this.unsolvedConnections = this.unsolvedConnections.map(\n ({ points, ...rest }, i) => ({\n ...rest,\n points: cloneAndShuffleArray(\n points,\n i * 7117 + (this.hyperParameters.SHUFFLE_SEED ?? 0),\n ),\n }),\n )\n }\n\n this.totalConnections = this.unsolvedConnections.length\n this.MAX_ITERATIONS = 1_000 * this.totalConnections ** 1.5\n\n this.minDistBetweenEnteringPoints = getMinDistBetweenEnteringPoints(\n this.nodeWithPortPoints,\n )\n\n // const {\n // numEntryExitLayerChanges,\n // numSameLayerCrossings,\n // numTransitionPairCrossings,\n // numTransitions,\n // } = getIntraNodeCrossings(this.nodeWithPortPoints)\n\n // if (\n // numSameLayerCrossings === 0 &&\n // numTransitions === 0 &&\n // numEntryExitLayerChanges === 0\n // ) {\n // this.handleSimpleNoCrossingsCase()\n // }\n }\n\n // handleSimpleNoCrossingsCase() {\n // // TODO check to make sure there are no crossings due to trace width\n // this.solved = true\n // this.solvedRoutes = this.unsolvedConnections.map(\n // ({ connectionName, points }) => ({\n // connectionName,\n // route: points,\n // traceThickness: 0.1, // TODO load from hyperParameters\n // viaDiameter: 0.6,\n // vias: [],\n // }),\n // )\n // this.unsolvedConnections = []\n // }\n\n computeProgress() {\n return (\n (this.solvedRoutes.length + (this.activeSolver?.progress || 0)) /\n this.totalConnections\n )\n }\n\n _step() {\n if (this.activeSolver) {\n this.activeSolver.step()\n this.progress = this.computeProgress()\n if (this.activeSolver.solved) {\n this.solvedRoutes.push(this.activeSolver.solvedPath!)\n this.activeSolver = null\n } else if (this.activeSolver.failed) {\n this.failedSubSolvers.push(this.activeSolver)\n this.activeSolver = null\n this.error = this.failedSubSolvers.map((s) => s.error).join(\"\\n\")\n this.failed = true\n }\n return\n }\n\n const unsolvedConnection = this.unsolvedConnections.pop()\n this.progress = this.computeProgress()\n if (!unsolvedConnection) {\n this.solved = this.failedSubSolvers.length === 0\n return\n }\n if (unsolvedConnection.points.length === 1) {\n return\n }\n if (unsolvedConnection.points.length === 2) {\n const [A, B] = unsolvedConnection.points\n if (A.x === B.x && A.y === B.y && A.z === B.z) {\n return\n }\n }\n const { connectionName, points } = unsolvedConnection\n this.activeSolver =\n new SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost({\n connectionName,\n minDistBetweenEnteringPoints: this.minDistBetweenEnteringPoints,\n bounds: getBoundsFromNodeWithPortPoints(this.nodeWithPortPoints),\n A: { x: points[0].x, y: points[0].y, z: points[0].z },\n B: {\n x: points[points.length - 1].x,\n y: points[points.length - 1].y,\n z: points[points.length - 1].z,\n },\n obstacleRoutes: this.solvedRoutes,\n futureConnections: this.unsolvedConnections,\n layerCount: 2,\n hyperParameters: this.hyperParameters,\n connMap: this.connMap,\n })\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n\n // Draw node bounds\n // graphics.rects!.push({\n // center: {\n // x: this.nodeWithPortPoints.center.x,\n // y: this.nodeWithPortPoints.center.y,\n // },\n // width: this.nodeWithPortPoints.width,\n // height: this.nodeWithPortPoints.height,\n // stroke: \"gray\",\n // fill: \"transparent\",\n // })\n\n // Visualize input nodeWithPortPoints\n for (const pt of this.nodeWithPortPoints.portPoints) {\n graphics.points!.push({\n x: pt.x,\n y: pt.y,\n label: [pt.connectionName, `layer: ${pt.z}`].join(\"\\n\"),\n color: this.colorMap[pt.connectionName] ?? \"blue\",\n })\n }\n\n // Visualize solvedRoutes\n for (\n let routeIndex = 0;\n routeIndex < this.solvedRoutes.length;\n routeIndex++\n ) {\n const route = this.solvedRoutes[routeIndex]\n if (route.route.length > 0) {\n const routeColor = this.colorMap[route.connectionName] ?? \"blue\"\n\n // Draw route segments between points\n for (let i = 0; i < route.route.length - 1; i++) {\n const p1 = route.route[i]\n const p2 = route.route[i + 1]\n\n graphics.lines!.push({\n points: [p1, p2],\n strokeColor:\n p1.z === 0\n ? safeTransparentize(routeColor, 0.2)\n : safeTransparentize(routeColor, 0.8),\n layer: `route-layer-${p1.z}`,\n step: routeIndex,\n strokeWidth: route.traceThickness,\n })\n }\n\n // Draw vias\n for (const via of route.vias) {\n graphics.circles!.push({\n center: { x: via.x, y: via.y },\n radius: route.viaDiameter / 2,\n fill: safeTransparentize(routeColor, 0.5),\n layer: \"via\",\n step: routeIndex,\n })\n }\n }\n }\n\n // Draw border around the node\n const bounds = getBoundsFromNodeWithPortPoints(this.nodeWithPortPoints)\n const { minX, minY, maxX, maxY } = bounds\n\n // Draw the four sides of the border with thin red lines\n graphics.lines!.push({\n points: [\n { x: minX, y: minY },\n { x: maxX, y: minY },\n { x: maxX, y: maxY },\n { x: minX, y: maxY },\n { x: minX, y: minY },\n ],\n strokeColor: \"rgba(255, 0, 0, 0.25)\",\n strokeDash: \"4 4\",\n layer: \"border\",\n })\n\n return graphics\n }\n}\n","import { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"./BaseSolver\"\n\nexport type SupervisedSolver<T extends BaseSolver> = {\n hyperParameters: any\n solver: T\n h: number\n g: number\n f: number\n}\n\nexport type HyperParameterDef = {\n name: string\n possibleValues: Array<any>\n}\n\n/**\n * The HyperParameterSupervisorSolver is a solver that solves a problem by\n * running competing solvers with different hyperparameters.\n *\n * As solvers make progress, the supervisor will allow the best solvers to run\n * for more iterations, prioritizing the solvers that are working the best.\n */\nexport class HyperParameterSupervisorSolver<\n T extends BaseSolver,\n> extends BaseSolver {\n GREEDY_MULTIPLIER = 1.2\n MIN_SUBSTEPS = 1\n\n supervisedSolvers?: Array<SupervisedSolver<T>>\n\n getHyperParameterDefs(): Array<HyperParameterDef> {\n throw new Error(\"Not implemented\")\n }\n\n getCombinationDefs(): Array<Array<string>> | null {\n return null\n }\n\n getHyperParameterCombinations(\n hyperParameterDefs?: Array<HyperParameterDef>,\n ): Array<Record<string, any>> {\n if (!hyperParameterDefs) {\n hyperParameterDefs = this.getHyperParameterDefs()\n }\n const combinations: Array<Record<string, any>> = []\n // Base case - no more hyperparameters to combine\n if (hyperParameterDefs.length === 0) {\n return [{}]\n }\n\n // Take first hyperparameter definition\n const [currentDef, ...remainingDefs] = hyperParameterDefs\n\n // Get combinations for remaining hyperparameters\n const subCombinations = this.getHyperParameterCombinations(remainingDefs)\n\n // For each possible value of current hyperparameter,\n // combine with all sub-combinations\n currentDef.possibleValues.forEach((value) => {\n subCombinations.forEach((subCombo) => {\n combinations.push({\n ...subCombo,\n ...value,\n })\n })\n })\n\n return combinations\n }\n\n initializeSolvers() {\n const hyperParameterDefs = this.getHyperParameterDefs()\n\n const combinationDefs = this.getCombinationDefs() ?? [\n hyperParameterDefs.map((def) => def.name),\n ]\n\n this.supervisedSolvers = []\n for (const combinationDef of combinationDefs) {\n const hyperParameterCombinations = this.getHyperParameterCombinations(\n hyperParameterDefs.filter((hpd) => combinationDef.includes(hpd.name)),\n )\n\n for (const hyperParameters of hyperParameterCombinations) {\n const solver = this.generateSolver(hyperParameters)\n this.supervisedSolvers.push({\n hyperParameters,\n solver,\n h: 0,\n g: 0,\n f: 0,\n })\n }\n }\n }\n\n generateSolver(hyperParameters: any): T {\n throw new Error(\"Not implemented\")\n }\n\n computeG(solver: T) {\n return solver.iterations / solver.MAX_ITERATIONS\n }\n\n computeH(solver: T) {\n return 1 - (solver.progress || 0)\n }\n\n computeF(g: number, h: number) {\n return g + h * this.GREEDY_MULTIPLIER\n }\n\n getSupervisedSolverWithBestFitness(): SupervisedSolver<T> | null {\n let bestFitness = Infinity\n let bestSolver: SupervisedSolver<T> | null = null\n for (const supervisedSolver of this.supervisedSolvers ?? []) {\n if (supervisedSolver.solver.solved) {\n return supervisedSolver\n }\n if (supervisedSolver.solver.failed) {\n continue\n }\n const fitness = supervisedSolver.f\n if (fitness < bestFitness) {\n bestFitness = fitness\n bestSolver = supervisedSolver\n }\n }\n return bestSolver\n }\n\n _step() {\n if (!this.supervisedSolvers) this.initializeSolvers()\n\n const supervisedSolver = this.getSupervisedSolverWithBestFitness()\n\n if (!supervisedSolver) {\n this.failed = true\n this.error = \"All solvers failed\"\n return\n }\n\n for (let i = 0; i < this.MIN_SUBSTEPS; i++) {\n supervisedSolver.solver.step()\n }\n\n supervisedSolver.g = this.computeG(supervisedSolver.solver)\n supervisedSolver.h = this.computeH(supervisedSolver.solver)\n supervisedSolver.f = this.computeF(supervisedSolver.g, supervisedSolver.h)\n\n if (supervisedSolver.solver.solved) {\n this.solved = true\n this.onSolve?.(supervisedSolver)\n }\n }\n\n onSolve(solver: SupervisedSolver<T>) {}\n\n visualize(): GraphicsObject {\n const bestSupervisedSolver = this.getSupervisedSolverWithBestFitness()\n let graphics: GraphicsObject = {\n lines: [],\n circles: [],\n points: [],\n rects: [],\n }\n\n if (bestSupervisedSolver) {\n graphics = bestSupervisedSolver.solver.visualize()\n }\n return graphics\n }\n}\n","import {\n HighDensityIntraNodeRoute,\n NodeWithPortPoints,\n} from \"lib/types/high-density-types\"\nimport { IntraNodeRouteSolver } from \"../HighDensitySolver/IntraNodeSolver\"\nimport {\n HyperParameterSupervisorSolver,\n SupervisedSolver,\n} from \"../HyperParameterSupervisorSolver\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\n\nexport class HyperSingleIntraNodeSolver extends HyperParameterSupervisorSolver<IntraNodeRouteSolver> {\n constructorParams: ConstructorParameters<typeof IntraNodeRouteSolver>[0]\n solvedRoutes: HighDensityIntraNodeRoute[] = []\n nodeWithPortPoints: NodeWithPortPoints\n\n constructor(opts: ConstructorParameters<typeof IntraNodeRouteSolver>[0]) {\n super()\n this.nodeWithPortPoints = opts.nodeWithPortPoints\n this.constructorParams = opts\n this.MAX_ITERATIONS = 250_000\n this.GREEDY_MULTIPLIER = 5\n this.MIN_SUBSTEPS = 100\n }\n\n getCombinationDefs() {\n return [\n [\"majorCombinations\", \"orderings6\", \"cellSizeFactor\"],\n [\"noVias\"],\n [\"orderings50\"],\n [\"flipTraceAlignmentDirection\", \"orderings6\"],\n ]\n }\n\n getHyperParameterDefs() {\n return [\n {\n name: \"majorCombinations\",\n possibleValues: [\n {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR: 2,\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR: 1,\n FUTURE_CONNECTION_PROXIMITY_VD: 10,\n MISALIGNED_DIST_PENALTY_FACTOR: 5,\n },\n {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR: 1,\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR: 0.5,\n FUTURE_CONNECTION_PROXIMITY_VD: 5,\n MISALIGNED_DIST_PENALTY_FACTOR: 2,\n },\n {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR: 10,\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR: 1,\n FUTURE_CONNECTION_PROXIMITY_VD: 5,\n MISALIGNED_DIST_PENALTY_FACTOR: 10,\n VIA_PENALTY_FACTOR_2: 1,\n },\n ],\n },\n {\n name: \"orderings6\",\n possibleValues: [\n {\n SHUFFLE_SEED: 0,\n },\n {\n SHUFFLE_SEED: 1,\n },\n {\n SHUFFLE_SEED: 2,\n },\n {\n SHUFFLE_SEED: 3,\n },\n {\n SHUFFLE_SEED: 4,\n },\n {\n SHUFFLE_SEED: 5,\n },\n ],\n },\n {\n name: \"cellSizeFactor\",\n possibleValues: [\n {\n CELL_SIZE_FACTOR: 0.5,\n },\n {\n CELL_SIZE_FACTOR: 1,\n },\n ],\n },\n {\n name: \"flipTraceAlignmentDirection\",\n possibleValues: [\n {\n FLIP_TRACE_ALIGNMENT_DIRECTION: true,\n },\n ],\n },\n {\n name: \"noVias\",\n possibleValues: [\n {\n CELL_SIZE_FACTOR: 2,\n VIA_PENALTY_FACTOR_2: 10,\n },\n ],\n },\n {\n name: \"orderings50\",\n possibleValues: Array.from({ length: 50 }, (_, i) => ({\n SHUFFLE_SEED: 100 + i,\n })),\n },\n ]\n }\n\n computeG(solver: IntraNodeRouteSolver) {\n return (\n solver.iterations / 10_000 // + solver.hyperParameters.SHUFFLE_SEED! * 0.05\n )\n }\n\n computeH(solver: IntraNodeRouteSolver) {\n return 1 - (solver.progress || 0)\n }\n\n generateSolver(hyperParameters: any): IntraNodeRouteSolver {\n return new IntraNodeRouteSolver({\n ...this.constructorParams,\n hyperParameters,\n })\n }\n\n onSolve(solver: SupervisedSolver<IntraNodeRouteSolver>) {\n this.solvedRoutes = solver.solver.solvedRoutes\n }\n}\n","interface RoutePoint {\n x: number\n y: number\n z: number\n}\n\ninterface MergedSegment {\n points: { x: number; y: number }[]\n z: number\n connectionName: string\n color: string\n}\n\n/**\n * Merges consecutive route points with the same z-coordinate into segments\n * @param route Array of route points\n * @param connectionName Name of the connection\n * @param color Color for the segment\n * @returns Array of merged segments\n */\nexport function mergeRouteSegments(\n route: RoutePoint[],\n connectionName: string,\n color: string,\n): MergedSegment[] {\n const segments: MergedSegment[] = []\n let currentSegment: MergedSegment | null = null\n\n for (let i = 0; i < route.length; i++) {\n const point = route[i]\n\n if (!currentSegment) {\n currentSegment = {\n points: [{ x: point.x, y: point.y }],\n z: point.z,\n connectionName,\n color,\n }\n } else if (currentSegment.z === point.z) {\n currentSegment.points.push({ x: point.x, y: point.y })\n } else {\n segments.push(currentSegment)\n currentSegment = {\n points: [{ x: point.x, y: point.y }],\n z: point.z,\n connectionName,\n color,\n }\n }\n\n // Add final segment if we're at the last point\n if (i === route.length - 1 && currentSegment) {\n segments.push(currentSegment)\n }\n }\n\n return segments\n}\n","import type {\n HighDensityIntraNodeRoute,\n NodeWithPortPoints,\n} from \"../../types/high-density-types\"\nimport type { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { safeTransparentize } from \"../colors\"\nimport { IntraNodeRouteSolver } from \"./IntraNodeSolver\"\nimport { HyperSingleIntraNodeSolver } from \"../HyperHighDensitySolver/HyperSingleIntraNodeSolver\"\nimport { combineVisualizations } from \"lib/utils/combineVisualizations\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { mergeRouteSegments } from \"lib/utils/mergeRouteSegments\"\n\nexport class HighDensitySolver extends BaseSolver {\n unsolvedNodePortPoints: NodeWithPortPoints[]\n routes: HighDensityIntraNodeRoute[]\n colorMap: Record<string, string>\n\n // Defaults as specified: viaDiameter of 0.6 and traceThickness of 0.15\n readonly defaultViaDiameter = 0.6\n readonly defaultTraceThickness = 0.15\n\n failedSolvers: (IntraNodeRouteSolver | HyperSingleIntraNodeSolver)[]\n activeSubSolver: IntraNodeRouteSolver | HyperSingleIntraNodeSolver | null =\n null\n connMap?: ConnectivityMap\n\n constructor({\n nodePortPoints,\n colorMap,\n connMap,\n }: {\n nodePortPoints: NodeWithPortPoints[]\n colorMap?: Record<string, string>\n connMap?: ConnectivityMap\n }) {\n super()\n this.unsolvedNodePortPoints = nodePortPoints\n this.colorMap = colorMap ?? {}\n this.connMap = connMap\n this.routes = []\n this.failedSolvers = []\n this.MAX_ITERATIONS = 1e6\n }\n\n /**\n * Each iteration, pop an unsolved node and attempt to find the routes inside\n * of it.\n */\n _step() {\n if (this.activeSubSolver) {\n this.activeSubSolver.step()\n if (this.activeSubSolver.solved) {\n this.routes.push(...this.activeSubSolver.solvedRoutes)\n this.activeSubSolver = null\n } else if (this.activeSubSolver.failed) {\n this.failedSolvers.push(this.activeSubSolver)\n this.activeSubSolver = null\n }\n return\n }\n if (this.unsolvedNodePortPoints.length === 0) {\n this.solved = true\n return\n }\n const node = this.unsolvedNodePortPoints.pop()!\n\n this.activeSubSolver = new HyperSingleIntraNodeSolver({\n nodeWithPortPoints: node,\n colorMap: this.colorMap,\n connMap: this.connMap,\n })\n }\n\n visualize(): GraphicsObject {\n let graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n for (const route of this.routes) {\n // Merge segments based on z-coordinate\n const mergedSegments = mergeRouteSegments(\n route.route,\n route.connectionName,\n this.colorMap[route.connectionName],\n )\n\n // Add merged segments to graphics\n for (const segment of mergedSegments) {\n graphics.lines!.push({\n points: segment.points,\n label: segment.connectionName,\n strokeColor:\n segment.z === 0\n ? segment.color\n : safeTransparentize(segment.color, 0.75),\n strokeWidth: route.traceThickness,\n strokeDash: segment.z !== 0 ? \"10, 5\" : undefined,\n })\n }\n for (const via of route.vias) {\n graphics.circles!.push({\n center: via,\n radius: route.viaDiameter / 2,\n fill: this.colorMap[route.connectionName],\n label: `${route.connectionName} via`,\n })\n }\n }\n for (const solver of this.failedSolvers) {\n const node = solver.nodeWithPortPoints\n // Group port points by connectionName\n const connectionGroups: Record<\n string,\n { x: number; y: number; z: number }[]\n > = {}\n for (const pt of node.portPoints) {\n if (!connectionGroups[pt.connectionName]) {\n connectionGroups[pt.connectionName] = []\n }\n connectionGroups[pt.connectionName].push({ x: pt.x, y: pt.y, z: pt.z })\n }\n\n for (const [connectionName, points] of Object.entries(connectionGroups)) {\n for (let i = 0; i < points.length - 1; i++) {\n const start = points[i]\n const end = points[i + 1]\n graphics.lines!.push({\n points: [start, end],\n strokeColor: \"red\",\n strokeDash: \"10, 5\",\n })\n }\n }\n }\n if (this.activeSubSolver) {\n graphics = combineVisualizations(\n graphics,\n this.activeSubSolver.visualize(),\n )\n }\n return graphics\n }\n}\n","type NodeId = string\n\nexport function findConnectedNetworks(\n connections: Array<NodeId[]>,\n): Record<string, string[]> {\n const networks: Map<string, Set<string>> = new Map()\n let netCounter = 0\n\n function getOrCreateNetwork(nodeId: string): Set<string> {\n for (const [, network] of networks) {\n if (network.has(nodeId)) {\n return network\n }\n }\n const newNetwork = new Set<string>()\n networks.set(`connectivity_net${netCounter++}`, newNetwork)\n return newNetwork\n }\n\n for (const connection of connections) {\n let network: Set<string> | null = null\n\n for (const nodeId of connection) {\n if (!network) {\n network = getOrCreateNetwork(nodeId)\n } else if (!network.has(nodeId)) {\n const existingNetwork = getOrCreateNetwork(nodeId)\n if (existingNetwork !== network) {\n // Merge networks\n for (const node of existingNetwork) {\n network.add(node)\n }\n networks.delete(\n Array.from(networks.entries()).find(\n ([, net]) => net === existingNetwork,\n )![0],\n )\n }\n }\n network.add(nodeId)\n }\n }\n\n return Object.fromEntries(\n Array.from(networks.entries()).map(([netId, connectedNodes]) => [\n netId,\n Array.from(connectedNodes),\n ]),\n )\n}\n","export class ConnectivityMap {\n netMap: Record<string, string[]>\n\n idToNetMap: Record<string, string>\n\n constructor(netMap: Record<string, string[]>) {\n this.netMap = netMap\n this.idToNetMap = {}\n for (const [netId, ids] of Object.entries(netMap)) {\n for (const id of ids) {\n this.idToNetMap[id] = netId\n }\n }\n }\n\n addConnections(connections: string[][]) {\n for (const connection of connections) {\n const existingNets = new Set<string>()\n\n // Find all existing nets for the connection\n for (const id of connection) {\n const existingNetId = this.idToNetMap[id]\n if (existingNetId) {\n existingNets.add(existingNetId)\n }\n }\n\n let targetNetId: string\n\n if (existingNets.size === 0) {\n // If no existing nets found, create a new one\n targetNetId = `connectivity_net${Object.keys(this.netMap).length}`\n this.netMap[targetNetId] = []\n } else if (existingNets.size === 1) {\n // If only one existing net found, use it\n targetNetId =\n existingNets.values().next().value ??\n `connectivity_net${Object.keys(this.netMap).length}`\n } else {\n // If multiple nets found, merge them\n targetNetId =\n existingNets.values().next().value ??\n `connectivity_net${Object.keys(this.netMap).length}`\n for (const netId of existingNets) {\n if (netId !== targetNetId) {\n this.netMap[targetNetId].push(...this.netMap[netId])\n\n // we could delete the net, but setting it to reference the other net\n // will make sure any usage of the old netId will still work\n this.netMap[netId] = this.netMap[targetNetId]\n for (const id of this.netMap[targetNetId]) {\n this.idToNetMap[id] = targetNetId\n }\n }\n }\n }\n\n // Add all ids to the target net\n for (const id of connection) {\n if (!this.netMap[targetNetId].includes(id)) {\n this.netMap[targetNetId].push(id)\n }\n this.idToNetMap[id] = targetNetId\n }\n }\n }\n\n getIdsConnectedToNet(netId: string): string[] {\n return this.netMap[netId] || []\n }\n\n getNetConnectedToId(id: string): string | undefined {\n return this.idToNetMap[id]\n }\n\n areIdsConnected(id1: string, id2: string): boolean {\n if (id1 === id2) return true\n const netId1 = this.getNetConnectedToId(id1)\n if (!netId1) return false\n const netId2 = this.getNetConnectedToId(id2)\n if (!netId2) return false\n return netId1 === netId2 || netId2 === id1 || netId2 === id1\n }\n\n areAllIdsConnected(ids: string[]): boolean {\n const netId = this.getNetConnectedToId(ids[0])\n for (const id of ids) {\n const nextNetId = this.getNetConnectedToId(id)\n if (nextNetId === undefined) {\n return false\n }\n if (nextNetId !== netId) {\n return false\n }\n }\n return true\n }\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getSourcePortConnectivityMapFromCircuitJson = (\n circuitJson: AnyCircuitElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push([\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ])\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getFullConnectivityMapFromCircuitJson = (\n circuitJson: AnyCircuitElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push(\n [\n element.source_trace_id,\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ].filter(Boolean),\n )\n } else if (element.type === \"pcb_port\") {\n const { pcb_port_id, source_port_id } = element\n if (source_port_id && pcb_port_id) {\n connections.push([source_port_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_smtpad\") {\n const { pcb_smtpad_id, pcb_port_id } = element\n if (pcb_port_id && pcb_smtpad_id) {\n connections.push([pcb_smtpad_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_plated_hole\") {\n const { pcb_plated_hole_id, pcb_port_id } = element\n if (pcb_port_id && pcb_plated_hole_id) {\n connections.push([pcb_plated_hole_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_trace\") {\n const { pcb_trace_id, source_trace_id } = element\n if (source_trace_id && pcb_trace_id) {\n connections.push([pcb_trace_id, source_trace_id])\n }\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnyCircuitElement, PCBPort, PCBTrace } from \"circuit-json\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\nimport { doesLineIntersectLine } from \"@tscircuit/math-utils\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\n\n/**\n * A PCB Connectivity Map is a connectivity map that has analyzed what traces and ports are actually connected on the\n * PCB.\n *\n * This is useful for determining how to route a trace on the PCB. For example, you may want to determine where the\n * nearest connected net point is to connect an unrouted pin.\n */\nexport class PcbConnectivityMap {\n circuitJson: AnyCircuitElement[]\n traceIdToElm: Map<string, PCBTrace>\n portIdToElm: Map<string, PCBPort>\n connMap: ConnectivityMap\n\n constructor(circuitJson?: AnyCircuitElement[]) {\n this.circuitJson = circuitJson || []\n this.traceIdToElm = new Map()\n this.portIdToElm = new Map()\n if (circuitJson) {\n this._buildTraceMap()\n this._buildPortMap()\n this.connMap = this._buildTraceConnectivityMap()\n } else {\n this.connMap = new ConnectivityMap({})\n }\n }\n\n private _buildPortMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_port\") {\n this.portIdToElm.set(element.pcb_port_id, element as PCBPort)\n }\n }\n }\n\n private _buildTraceMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_trace\") {\n this.traceIdToElm.set(element.pcb_trace_id, element as PCBTrace)\n }\n }\n }\n\n private _buildTraceConnectivityMap(): ConnectivityMap {\n const connections: string[][] = []\n const traceIds = Array.from(this.traceIdToElm.keys())\n\n for (let i = 0; i < traceIds.length; i++) {\n for (let j = i + 1; j < traceIds.length; j++) {\n const trace1 = this.traceIdToElm.get(traceIds[i])!\n const trace2 = this.traceIdToElm.get(traceIds[j])!\n if (this._arePcbTracesConnected(trace1, trace2)) {\n connections.push([traceIds[i], traceIds[j]])\n }\n }\n }\n\n for (const port of this.portIdToElm.values()) {\n for (const trace of this.traceIdToElm.values()) {\n for (const rp of trace.route) {\n if (rp.route_type === \"wire\") {\n if (rp.start_pcb_port_id === port.pcb_port_id) {\n connections.push([port.pcb_port_id, trace.pcb_trace_id])\n } else if (rp.end_pcb_port_id === port.pcb_port_id) {\n connections.push([trace.pcb_trace_id, port.pcb_port_id])\n }\n }\n }\n }\n }\n\n return new ConnectivityMap(findConnectedNetworks(connections))\n }\n\n addTrace(trace: PCBTrace) {\n this.traceIdToElm.set(trace.pcb_trace_id, trace)\n const connections: string[][] = []\n for (const rp of trace.route) {\n if (rp.route_type === \"wire\") {\n if (rp.start_pcb_port_id) {\n connections.push([rp.start_pcb_port_id, trace.pcb_trace_id])\n }\n if (rp.end_pcb_port_id) {\n connections.push([rp.end_pcb_port_id, trace.pcb_trace_id])\n }\n }\n }\n\n this.connMap.addConnections(connections)\n }\n\n _arePcbTracesConnected(trace1: PCBTrace, trace2: PCBTrace): boolean {\n for (let i = 0; i < trace1.route.length - 1; i++) {\n const segment1A = trace1.route[i]\n const segment1B = trace1.route[i + 1]\n if (segment1A.route_type !== \"wire\") continue\n if (segment1B.route_type !== \"wire\") continue\n for (let j = 0; j < trace2.route.length - 1; j++) {\n const segment2A = trace2.route[j]\n const segment2B = trace2.route[j + 1]\n\n if (segment2A.route_type !== \"wire\") continue\n if (segment2B.route_type !== \"wire\") continue\n\n // Check if lines are overlapping\n const isOverlapping = doesLineIntersectLine(\n [segment1A, segment1B],\n [segment2A, segment2B],\n {\n lineThickness: (segment1A.width + segment2A.width) / 2,\n },\n )\n if (isOverlapping) {\n return true\n }\n }\n }\n return false\n }\n\n areTracesConnected(traceId1: string, traceId2: string): boolean {\n return this.connMap.areIdsConnected(traceId1, traceId2)\n }\n\n getAllTracesConnectedToTrace(traceId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(traceId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n\n getAllTracesConnectedToPort(portId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(portId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n}\n","import { SimpleRouteJson } from \"lib/types\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\n\nexport const getConnectivityMapFromSimpleRouteJson = (srj: SimpleRouteJson) => {\n const connMap = new ConnectivityMap({})\n for (const connection of srj.connections) {\n for (const point of connection.pointsToConnect) {\n if (\"pcb_port_id\" in point && point.pcb_port_id) {\n connMap.addConnections([[connection.name, point.pcb_port_id as string]])\n }\n }\n }\n return connMap\n}\n","import { CapacityMeshNode } from \"lib/types/capacity-mesh-types\"\n\n/**\n * Calculate the capacity of a node based on its width\n *\n * This capacity corresponds to how many vias the node can fit, tuned for two\n * layers.\n *\n * @param nodeOrWidth The node or width to calculate capacity for\n * @param maxCapacityFactor Optional multiplier to adjust capacity\n * @returns The calculated capacity\n */\nexport const getTunedTotalCapacity1 = (\n nodeOrWidth: CapacityMeshNode | { width: number },\n maxCapacityFactor = 1,\n) => {\n const VIA_DIAMETER = 0.6\n const TRACE_WIDTH = 0.15\n const obstacleMargin = 0.2\n\n const width = \"width\" in nodeOrWidth ? nodeOrWidth.width : nodeOrWidth\n const viaLengthAcross = width / (VIA_DIAMETER / 2 + obstacleMargin)\n\n return (viaLengthAcross / 2) ** 1.1 * maxCapacityFactor\n}\n\n/**\n * Calculate the optimal subdivision depth to reach a target minimum capacity\n * @param initialWidth The initial width of the top-level node\n * @param targetMinCapacity The minimum capacity target (default 0.5)\n * @param maxDepth Maximum allowed depth (default 10)\n * @returns The optimal capacity depth\n */\nexport const calculateOptimalCapacityDepth = (\n initialWidth: number,\n targetMinCapacity = 0.5,\n maxDepth = 16,\n): number => {\n let depth = 0\n let width = initialWidth\n\n // Calculate capacity at each subdivision level until we reach target or max depth\n while (depth < maxDepth) {\n const capacity = getTunedTotalCapacity1({ width })\n\n // If capacity is below target, we've gone far enough\n if (capacity <= targetMinCapacity) {\n break\n }\n\n // Move to next subdivision level (each level divides width by 2)\n width /= 2\n depth++\n }\n\n // Return depth + 1 to account for the fact that we want to subdivide\n // until the smallest nodes have capacity <= targetMinCapacity\n return Math.max(1, depth)\n}\n","type Point = { x: number; y: number }\n\nexport class KDNode {\n point: Point\n left: KDNode | null = null\n right: KDNode | null = null\n\n constructor(point: Point) {\n this.point = point\n }\n}\n\nclass KDTree {\n root: KDNode | null = null\n\n constructor(points: Point[]) {\n if (points.length > 0) {\n this.root = this.buildTree(points, 0)\n }\n }\n\n private buildTree(points: Point[], depth: number): KDNode {\n const axis = depth % 2 === 0 ? \"x\" : \"y\"\n\n // Sort points by the current axis\n points.sort((a, b) => a[axis] - b[axis])\n\n // Choose median as the pivot element\n const medianIndex = Math.floor(points.length / 2)\n const node = new KDNode(points[medianIndex])\n\n // Recursively build left and right subtrees\n if (medianIndex > 0) {\n node.left = this.buildTree(points.slice(0, medianIndex), depth + 1)\n }\n\n if (medianIndex < points.length - 1) {\n node.right = this.buildTree(points.slice(medianIndex + 1), depth + 1)\n }\n\n return node\n }\n\n // Find the nearest neighbor to a query point\n findNearestNeighbor(queryPoint: Point): Point {\n if (!this.root) {\n throw new Error(\"Tree is empty\")\n }\n\n const best: Point = this.root.point\n const bestDistance = this.distance(queryPoint, best)\n\n this.nearestNeighborSearch(this.root, queryPoint, 0, best, bestDistance)\n\n return best\n }\n\n private nearestNeighborSearch(\n node: KDNode | null,\n queryPoint: Point,\n depth: number,\n best: Point,\n bestDistance: number,\n ): Point {\n if (!node) {\n return best\n }\n\n const axis = depth % 2 ? \"x\" : \"y\"\n const currentDistance = this.distance(queryPoint, node.point)\n\n if (currentDistance < bestDistance) {\n best = node.point\n bestDistance = currentDistance\n }\n\n // Determine which subtree to search first\n const axisDiff = queryPoint[axis] - node.point[axis]\n const firstBranch = axisDiff <= 0 ? node.left : node.right\n const secondBranch = axisDiff <= 0 ? node.right : node.left\n\n // Recursively search the first branch\n best = this.nearestNeighborSearch(\n firstBranch,\n queryPoint,\n depth + 1,\n best,\n bestDistance,\n )\n bestDistance = this.distance(queryPoint, best)\n\n // Check if we need to search the second branch\n if (Math.abs(axisDiff) < bestDistance) {\n best = this.nearestNeighborSearch(\n secondBranch,\n queryPoint,\n depth + 1,\n best,\n bestDistance,\n )\n }\n\n return best\n }\n\n // Find k nearest neighbors\n findKNearestNeighbors(queryPoint: Point, k: number): Point[] {\n if (!this.root) {\n return []\n }\n\n const neighbors: Array<{ point: Point; distance: number }> = []\n\n this.kNearestNeighborSearch(this.root, queryPoint, 0, neighbors, k)\n\n return neighbors\n .sort((a, b) => a.distance - b.distance)\n .slice(0, k)\n .map((n) => n.point)\n }\n\n private kNearestNeighborSearch(\n node: KDNode | null,\n queryPoint: Point,\n depth: number,\n neighbors: Array<{ point: Point; distance: number }>,\n k: number,\n ): void {\n if (!node) {\n return\n }\n\n const axis = depth % 2 ? \"x\" : \"y\"\n const currentDistance = this.distance(queryPoint, node.point)\n\n // Add current node to neighbors\n neighbors.push({ point: node.point, distance: currentDistance })\n\n // Determine which subtree to search first\n const axisDiff = queryPoint[axis] - node.point[axis]\n const firstBranch = axisDiff <= 0 ? node.left : node.right\n const secondBranch = axisDiff <= 0 ? node.right : node.left\n\n // Recursively search the first branch\n this.kNearestNeighborSearch(\n firstBranch,\n queryPoint,\n depth + 1,\n neighbors,\n k,\n )\n\n // Get the kth distance if we have k neighbors\n let kthDistance = Infinity\n if (neighbors.length >= k) {\n neighbors.sort((a, b) => a.distance - b.distance)\n kthDistance = neighbors[k - 1]?.distance || Infinity\n }\n\n // Search the other branch if necessary\n if (Math.abs(axisDiff) < kthDistance || neighbors.length < k) {\n this.kNearestNeighborSearch(\n secondBranch,\n queryPoint,\n depth + 1,\n neighbors,\n k,\n )\n }\n }\n\n // Calculate Euclidean distance between two points\n private distance(a: Point, b: Point): number {\n return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)\n }\n}\n\n// Disjoint Set (Union-Find) data structure for Kruskal's algorithm\nexport class DisjointSet {\n private parent: Map<string, string> = new Map()\n private rank: Map<string, number> = new Map()\n\n constructor(points: Point[]) {\n // Initialize each point as a separate set\n for (const point of points) {\n const key = this.pointToKey(point)\n this.parent.set(key, key)\n this.rank.set(key, 0)\n }\n }\n\n private pointToKey(point: Point): string {\n return `${point.x},${point.y}`\n }\n\n find(point: Point): string {\n const key = this.pointToKey(point)\n if (!this.parent.has(key)) {\n throw new Error(`Point ${key} not found in DisjointSet`)\n }\n\n let root = key\n while (root !== this.parent.get(root)) {\n root = this.parent.get(root)!\n }\n\n // Path compression\n let current = key\n while (current !== root) {\n const next = this.parent.get(current)!\n this.parent.set(current, root)\n current = next\n }\n\n return root\n }\n\n union(pointA: Point, pointB: Point): boolean {\n const rootA = this.find(pointA)\n const rootB = this.find(pointB)\n\n if (rootA === rootB) {\n return false // Already in the same set\n }\n\n // Union by rank\n const rankA = this.rank.get(rootA) || 0\n const rankB = this.rank.get(rootB) || 0\n\n if (rankA < rankB) {\n this.parent.set(rootA, rootB)\n } else if (rankA > rankB) {\n this.parent.set(rootB, rootA)\n } else {\n this.parent.set(rootB, rootA)\n this.rank.set(rootA, rankA + 1)\n }\n\n return true\n }\n}\n\n// Edge representation for Kruskal's algorithm\ninterface Edge<T extends Point> {\n from: T\n to: T\n weight: number\n}\n\n// Main function to build a minimum spanning tree using Kruskal's algorithm\nexport function buildMinimumSpanningTree<T extends Point>(\n points: T[],\n): Edge<T>[] {\n if (points.length <= 1) {\n return []\n }\n\n // Build KD-Tree for efficient nearest neighbor search\n const kdTree = new KDTree(points)\n\n // Generate edges with k-nearest neighbors for each point\n // This is an optimization to avoid generating all possible n(n-1)/2 edges\n const edges: Edge<T>[] = []\n const k = Math.min(10, points.length - 1) // Consider k nearest neighbors\n\n for (const point of points) {\n const neighbors = kdTree.findKNearestNeighbors(point, k + 1) // +1 because it includes the point itself\n\n for (const neighbor of neighbors) {\n // Skip self\n if (point.x === neighbor.x && point.y === neighbor.y) {\n continue\n }\n\n const distance = Math.sqrt(\n (point.x - neighbor.x) ** 2 + (point.y - neighbor.y) ** 2,\n )\n\n edges.push({\n from: point,\n to: neighbor as T,\n weight: distance,\n })\n }\n }\n\n // Sort edges by weight (distance)\n edges.sort((a, b) => a.weight - b.weight)\n\n // Apply Kruskal's algorithm\n const disjointSet = new DisjointSet(points)\n const mstEdges: Edge<T>[] = []\n\n for (const edge of edges) {\n if (disjointSet.union(edge.from, edge.to)) {\n mstEdges.push(edge)\n\n // MST has n-1 edges for n points\n if (mstEdges.length === points.length - 1) {\n break\n }\n }\n }\n\n return mstEdges\n}\n","import { SimpleRouteConnection, SimpleRouteJson } from \"lib/types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { buildMinimumSpanningTree } from \"./buildMinimumSpanningTree\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { seededRandom } from \"lib/utils/cloneAndShuffleArray\"\n\n/**\n * Converts a net containing many points to connect into an array of point pair\n * connections.\n *\n * For example, a connection with 3 pointsToConnect could be turned into 2\n * connections of 2 points each.\n *\n * Where we create the minimum number of pairs, we're using a minimum spanning\n * tree (MST).\n *\n * Sometimes it can be used to add additional traces to help make sure we\n * distribute load effectively. In this version we don't do that!\n */\nexport class NetToPointPairsSolver extends BaseSolver {\n unprocessedConnections: Array<SimpleRouteConnection>\n newConnections: Array<SimpleRouteConnection>\n\n constructor(\n public ogSrj: SimpleRouteJson,\n public colorMap: Record<string, string> = {},\n ) {\n super()\n this.unprocessedConnections = [...ogSrj.connections]\n this.newConnections = []\n }\n\n _step() {\n if (this.unprocessedConnections.length === 0) {\n this.solved = true\n return\n }\n const connection = this.unprocessedConnections.pop()!\n if (connection.pointsToConnect.length === 2) {\n this.newConnections.push(connection)\n return\n }\n\n const edges = buildMinimumSpanningTree(connection.pointsToConnect)\n\n for (let i = 0; i < edges.length; i++) {\n const edge = edges[i]\n this.newConnections.push({\n pointsToConnect: [edge.from, edge.to],\n name: `${connection.name}_mst${i}`,\n })\n }\n }\n\n getNewSimpleRouteJson(): SimpleRouteJson {\n return {\n ...this.ogSrj,\n connections: this.newConnections,\n }\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Net To Point Pairs Visualization\",\n }\n\n // Draw unprocessed connections in red\n this.unprocessedConnections.forEach((connection) => {\n // Draw points\n connection.pointsToConnect.forEach((point) => {\n graphics.points!.push({\n x: point.x,\n y: point.y,\n color: \"red\",\n label: connection.name,\n })\n })\n\n // Draw lines connecting all points in the connection\n const fullyConnectedEdgeCount = connection.pointsToConnect.length ** 2\n const random = seededRandom(0)\n const alreadyPlacedEdges = new Set<string>()\n for (\n let i = 0;\n i <\n Math.max(\n fullyConnectedEdgeCount,\n connection.pointsToConnect.length * 2,\n );\n i++\n ) {\n const a = Math.floor(random() * connection.pointsToConnect.length)\n const b = Math.floor(random() * connection.pointsToConnect.length)\n if (alreadyPlacedEdges.has(`${a}-${b}`)) continue\n alreadyPlacedEdges.add(`${a}-${b}`)\n graphics.lines!.push({\n points: [\n connection.pointsToConnect[a],\n connection.pointsToConnect[b],\n ],\n strokeColor: \"rgba(255,0,0,0.25)\",\n })\n }\n })\n\n // Draw processed connections with appropriate colors\n this.newConnections.forEach((connection) => {\n const color = this.colorMap?.[connection.name] || \"blue\"\n\n // Draw points\n connection.pointsToConnect.forEach((point) => {\n graphics.points!.push({\n x: point.x,\n y: point.y,\n color: color,\n label: connection.name,\n })\n })\n\n // Draw lines connecting all points in the connection\n for (let i = 0; i < connection.pointsToConnect.length - 1; i++) {\n for (let j = i + 1; j < connection.pointsToConnect.length; j++) {\n graphics.lines!.push({\n points: [\n connection.pointsToConnect[i],\n connection.pointsToConnect[j],\n ],\n strokeColor: color,\n })\n }\n }\n })\n\n return graphics\n }\n}\n","export const mapZToLayerName = (z: number, layerCount: number) => {\n if (z < 0 || z >= layerCount) {\n throw new Error(`Invalid z \"${z}\" for layer count: ${layerCount}`)\n }\n\n if (z === 0) return \"top\"\n if (z === layerCount - 1) return \"bottom\"\n return `inner${z}`\n}\n","import { SimplifiedPcbTraces } from \"lib/types\"\nimport { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport { mapZToLayerName } from \"./mapZToLayerName\"\n\ntype Point = { x: number; y: number; z: number }\n\nexport const convertHdRouteToSimplifiedRoute = (\n hdRoute: HighDensityIntraNodeRoute,\n layerCount: number,\n): SimplifiedPcbTraces[number][\"route\"] => {\n const result: SimplifiedPcbTraces[number][\"route\"] = []\n if (hdRoute.route.length === 0) return result\n\n let currentLayerPoints: Point[] = []\n let currentZ = hdRoute.route[0].z\n\n // Add all points to their respective layer segments\n for (let i = 0; i < hdRoute.route.length; i++) {\n const point = hdRoute.route[i]\n\n // If we're changing layers, process the current layer's points\n // and add a via if one exists at this position\n if (point.z !== currentZ) {\n // Add all wire segments for the current layer\n const layerName = mapZToLayerName(currentZ, layerCount)\n for (const layerPoint of currentLayerPoints) {\n result.push({\n route_type: \"wire\",\n x: layerPoint.x,\n y: layerPoint.y,\n width: hdRoute.traceThickness,\n layer: layerName,\n })\n }\n\n // Check if a via exists at this position\n const viaExists = hdRoute.vias.some(\n (via) =>\n Math.abs(via.x - point.x) < 0.001 &&\n Math.abs(via.y - point.y) < 0.001,\n )\n\n // Add a via if one exists\n if (viaExists) {\n const fromLayer = mapZToLayerName(currentZ, layerCount)\n const toLayer = mapZToLayerName(point.z, layerCount)\n\n result.push({\n route_type: \"via\",\n x: point.x,\n y: point.y,\n from_layer: fromLayer,\n to_layer: toLayer,\n })\n }\n\n // Start a new layer\n currentLayerPoints = [point]\n currentZ = point.z\n } else {\n // Continue on the same layer\n currentLayerPoints.push(point)\n }\n }\n\n // Add the final layer's wire segments\n const layerName = mapZToLayerName(currentZ, layerCount)\n for (const layerPoint of currentLayerPoints) {\n result.push({\n route_type: \"wire\",\n x: layerPoint.x,\n y: layerPoint.y,\n width: hdRoute.traceThickness,\n layer: layerName,\n })\n }\n\n return result\n}\n","import { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { distance } from \"@tscircuit/math-utils\"\n\nexport class SingleHighDensityRouteStitchSolver extends BaseSolver {\n mergedHdRoute: HighDensityIntraNodeRoute\n remainingHdRoutes: HighDensityIntraNodeRoute[]\n start: { x: number; y: number; z: number }\n end: { x: number; y: number; z: number }\n\n constructor(opts: {\n hdRoutes: HighDensityIntraNodeRoute[]\n start: { x: number; y: number; z: number }\n end: { x: number; y: number; z: number }\n }) {\n super()\n this.remainingHdRoutes = [...opts.hdRoutes]\n this.mergedHdRoute = {\n connectionName: opts.hdRoutes[0].connectionName,\n route: [\n {\n x: opts.start.x,\n y: opts.start.y,\n z: opts.start.z,\n },\n ],\n vias: [],\n viaDiameter: opts.hdRoutes[0].viaDiameter,\n traceThickness: opts.hdRoutes[0].traceThickness,\n }\n this.start = opts.start\n this.end = opts.end\n }\n\n _step() {\n if (this.remainingHdRoutes.length === 0) {\n // Add the end point to the merged route\n this.mergedHdRoute.route.push({\n x: this.end.x,\n y: this.end.y,\n z: this.end.z,\n })\n this.solved = true\n return\n }\n\n const lastMergedPoint =\n this.mergedHdRoute.route[this.mergedHdRoute.route.length - 1]\n\n // Find the next logical route to merge\n // 1. We need to check both the first and last points of the remaining routes\n // 2. If the last point is closest, we need to reverse the hd route before merging\n // 3. After merging, we remove it from the remaining routes\n\n let closestRouteIndex = 0\n let matchedOn: \"first\" | \"last\" = \"first\"\n let closestDistance = Infinity\n for (let i = 0; i < this.remainingHdRoutes.length; i++) {\n const hdRoute = this.remainingHdRoutes[i]\n const lastPointInCandidate = hdRoute.route[hdRoute.route.length - 1]\n const firstPointInCandidate = hdRoute.route[0]\n const distToFirst = distance(lastMergedPoint, firstPointInCandidate)\n const distToLast = distance(lastMergedPoint, lastPointInCandidate)\n if (distToFirst < closestDistance) {\n closestDistance = distToFirst\n closestRouteIndex = i\n matchedOn = \"first\"\n }\n if (distToLast < closestDistance) {\n closestDistance = distToLast\n closestRouteIndex = i\n matchedOn = \"last\"\n }\n }\n\n const hdRouteToMerge = this.remainingHdRoutes[closestRouteIndex]\n this.remainingHdRoutes.splice(closestRouteIndex, 1)\n\n if (matchedOn === \"first\") {\n this.mergedHdRoute.route.push(...hdRouteToMerge.route)\n } else {\n this.mergedHdRoute.route.push(...[...hdRouteToMerge.route].reverse())\n }\n\n this.mergedHdRoute.vias.push(...hdRouteToMerge.vias)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n points: [],\n lines: [],\n circles: [],\n title: \"Single High Density Route Stitch Solver\",\n }\n\n // Visualize start and end points\n graphics.points?.push(\n {\n x: this.start.x,\n y: this.start.y,\n color: \"green\",\n label: \"Start\",\n },\n {\n x: this.end.x,\n y: this.end.y,\n color: \"red\",\n label: \"End\",\n },\n )\n\n // Visualize the merged HD route in green\n if (this.mergedHdRoute && this.mergedHdRoute.route.length > 1) {\n graphics.lines?.push({\n points: this.mergedHdRoute.route.map((point) => ({\n x: point.x,\n y: point.y,\n })),\n strokeColor: \"green\",\n })\n\n // Add points for the merged route\n for (const point of this.mergedHdRoute.route) {\n graphics.points?.push({\n x: point.x,\n y: point.y,\n color: \"green\",\n })\n }\n\n // Visualize vias in the merged route\n for (const via of this.mergedHdRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: this.mergedHdRoute.viaDiameter / 2,\n fill: \"green\",\n })\n }\n }\n\n // Visualize all remaining HD routes\n const colorList = Array.from(\n { length: this.remainingHdRoutes.length },\n (_, i) => `hsl(${(i * 360) / this.remainingHdRoutes.length}, 100%, 50%)`,\n )\n for (const [i, hdRoute] of this.remainingHdRoutes.entries()) {\n if (hdRoute.route.length > 1) {\n // Create a line for the route\n graphics.lines?.push({\n points: hdRoute.route.map((point) => ({ x: point.x, y: point.y })),\n strokeColor: colorList[i],\n })\n }\n\n // Add points for each route node\n for (let pi = 0; pi < hdRoute.route.length; pi++) {\n const point = hdRoute.route[pi]\n graphics.points?.push({\n x: point.x + ((i % 2) - 0.5) / 500 + ((pi % 8) - 4) / 1000,\n y: point.y + ((i % 2) - 0.5) / 500 + ((pi % 8) - 4) / 1000,\n color: colorList[i],\n label: `Route ${i} ${point === hdRoute.route[0] ? \"First\" : point === hdRoute.route[hdRoute.route.length - 1] ? \"Last\" : \"\"}`,\n })\n }\n\n // Visualize vias\n for (const via of hdRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: hdRoute.viaDiameter / 2,\n fill: colorList[i],\n })\n }\n }\n\n return graphics\n }\n}\n","import { SimpleRouteConnection } from \"lib/types\"\nimport { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\nimport { SingleHighDensityRouteStitchSolver } from \"./SingleHighDensityRouteStitchSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { safeTransparentize } from \"../colors\"\n\nexport type UnsolvedRoute = {\n connectionName: string\n hdRoutes: HighDensityIntraNodeRoute[]\n start: { x: number; y: number; z: number }\n end: { x: number; y: number; z: number }\n}\n\nexport class MultipleHighDensityRouteStitchSolver extends BaseSolver {\n unsolvedRoutes: UnsolvedRoute[]\n activeSolver: SingleHighDensityRouteStitchSolver | null = null\n mergedHdRoutes: HighDensityIntraNodeRoute[] = []\n\n constructor(opts: {\n connections: SimpleRouteConnection[]\n hdRoutes: HighDensityIntraNodeRoute[]\n layerCount: number\n }) {\n super()\n this.unsolvedRoutes = opts.connections.map((c) => ({\n connectionName: c.name,\n hdRoutes: opts.hdRoutes.filter((r) => r.connectionName === c.name),\n start: {\n ...c.pointsToConnect[0],\n z: mapLayerNameToZ(c.pointsToConnect[0].layer, opts.layerCount),\n },\n end: {\n ...c.pointsToConnect[1],\n z: mapLayerNameToZ(c.pointsToConnect[1].layer, opts.layerCount),\n },\n }))\n }\n\n _step() {\n if (this.activeSolver) {\n this.activeSolver.step()\n if (this.activeSolver.solved) {\n this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute)\n this.activeSolver = null\n } else if (this.activeSolver.failed) {\n this.failed = true\n this.error = this.activeSolver.error\n }\n return\n }\n\n const unsolvedRoute = this.unsolvedRoutes.pop()\n\n if (!unsolvedRoute) {\n this.solved = true\n return\n }\n\n if (unsolvedRoute.hdRoutes.length === 0) {\n console.warn(`No routes to stitch for ${unsolvedRoute.connectionName}`)\n return\n }\n\n this.activeSolver = new SingleHighDensityRouteStitchSolver({\n hdRoutes: unsolvedRoute.hdRoutes,\n start: unsolvedRoute.start,\n end: unsolvedRoute.end,\n })\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n points: [],\n lines: [],\n circles: [],\n title: \"Multiple High Density Route Stitch Solver\",\n }\n\n // Visualize the active solver if one exists\n if (this.activeSolver) {\n // Combine visualizations from the active solver\n const activeSolverGraphics = this.activeSolver.visualize()\n\n // Merge points\n if (activeSolverGraphics.points?.length) {\n graphics.points?.push(...activeSolverGraphics.points)\n }\n\n // Merge lines\n if (activeSolverGraphics.lines?.length) {\n graphics.lines?.push(...activeSolverGraphics.lines)\n }\n\n // Merge circles\n if (activeSolverGraphics.circles?.length) {\n graphics.circles?.push(...activeSolverGraphics.circles)\n }\n\n // Merge rects if they exist\n if (activeSolverGraphics.rects?.length) {\n graphics.rects = activeSolverGraphics.rects\n }\n }\n\n // Visualize all merged HD routes that have been solved\n for (const [i, mergedRoute] of this.mergedHdRoutes.entries()) {\n const solvedColor = `hsl(120, 100%, ${40 + ((i * 10) % 40)}%)` // Different shades of green\n\n // Visualize the route path\n if (mergedRoute.route.length > 1) {\n graphics.lines?.push({\n points: mergedRoute.route.map((point) => ({\n x: point.x,\n y: point.y,\n })),\n strokeColor: solvedColor,\n strokeWidth: mergedRoute.traceThickness,\n })\n }\n\n // Visualize route points\n for (const point of mergedRoute.route) {\n graphics.points?.push({\n x: point.x,\n y: point.y,\n color: solvedColor,\n })\n }\n\n // Visualize vias in the merged route\n for (const via of mergedRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: mergedRoute.viaDiameter / 2,\n fill: solvedColor,\n })\n }\n }\n\n // Visualize all remaining unsolved routes - start/end points only\n const colorList = Array.from(\n { length: this.unsolvedRoutes.length },\n (_, i) => `hsl(${(i * 360) / this.unsolvedRoutes.length}, 100%, 50%)`,\n )\n for (const [i, unsolvedRoute] of this.unsolvedRoutes.entries()) {\n // Add start and end points for unsolved connections\n graphics.points?.push(\n {\n x: unsolvedRoute.start.x,\n y: unsolvedRoute.start.y,\n color: colorList[i],\n label: `${unsolvedRoute.connectionName} Start`,\n },\n {\n x: unsolvedRoute.end.x,\n y: unsolvedRoute.end.y,\n color: colorList[i],\n label: `${unsolvedRoute.connectionName} End`,\n },\n )\n\n // Add a light dashed line between start and end to show pending connections\n graphics.lines?.push({\n points: [\n { x: unsolvedRoute.start.x, y: unsolvedRoute.start.y },\n { x: unsolvedRoute.end.x, y: unsolvedRoute.end.y },\n ],\n strokeColor: colorList[i],\n strokeDash: \"2 2\",\n })\n\n // Visualize HD routes associated with unsolved routes (faded)\n for (const hdRoute of unsolvedRoute.hdRoutes) {\n if (hdRoute.route.length > 1) {\n graphics.lines?.push({\n points: hdRoute.route.map((point) => ({ x: point.x, y: point.y })),\n strokeColor: safeTransparentize(colorList[i], 0.5),\n strokeDash: \"10 5\",\n })\n }\n\n // Visualize vias\n for (const via of hdRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: hdRoute.viaDiameter / 2,\n fill: colorList[i],\n })\n }\n }\n }\n\n return graphics\n }\n}\n","import { Rect, Line, Circle, Point } from \"graphics-debug\"\nimport { SimpleRouteJson } from \"../../lib/types/srj-types\"\nimport { getColorMap, safeTransparentize } from \"lib/solvers/colors\"\n\nexport const convertSrjToGraphicsObject = (srj: SimpleRouteJson) => {\n const lines: Line[] = []\n const circles: Circle[] = []\n const points: Point[] = []\n\n const colorMap: Record<string, string> = getColorMap(srj)\n\n // Add points for each connection's pointsToConnect\n if (srj.connections) {\n for (const connection of srj.connections) {\n for (const point of connection.pointsToConnect) {\n points.push({\n x: point.x,\n y: point.y,\n color: colorMap[connection.name]!,\n label: `${connection.name} (${point.layer})`,\n })\n }\n }\n }\n\n // Process each trace\n if (srj.traces) {\n for (const trace of srj.traces) {\n for (let j = 0; j < trace.route.length - 1; j++) {\n const routePoint = trace.route[j]\n const nextRoutePoint = trace.route[j + 1]\n\n if (routePoint.route_type === \"via\") {\n // Add a circle for the via\n circles.push({\n center: { x: routePoint.x, y: routePoint.y },\n radius: 0.3, // 0.6 via diameter\n fill: \"blue\",\n stroke: \"none\",\n })\n } else if (\n routePoint.route_type === \"wire\" &&\n nextRoutePoint.route_type === \"wire\" &&\n nextRoutePoint.layer === routePoint.layer\n ) {\n // Create a line between consecutive wire segments on the same layer\n lines.push({\n points: [\n { x: routePoint.x, y: routePoint.y },\n { x: nextRoutePoint.x, y: nextRoutePoint.y },\n ],\n strokeWidth: 0.15,\n strokeColor: safeTransparentize(\n {\n top: \"red\",\n bottom: \"blue\",\n inner1: \"green\",\n inner2: \"yellow\",\n }[routePoint.layer]!,\n 0.5,\n ),\n // For some reason this is too small, likely a graphics-debug bug\n // strokeWidth: 0.15,\n })\n }\n }\n }\n }\n\n return {\n rects: srj.obstacles.map(\n (o) =>\n ({\n center: o.center,\n width: o.width,\n height: o.height,\n fill: \"rgba(255,0,0,0.5)\",\n }) as Rect,\n ),\n circles,\n lines,\n points,\n }\n}\n","import { CapacityMeshNodeId } from \"lib/types\"\n\nexport function getNodesNearNode(params: {\n nodeId: CapacityMeshNodeId\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n hops: number\n}): CapacityMeshNodeId[] {\n const { nodeId, nodeIdToSegmentIds, segmentIdToNodeIds, hops } = params\n\n if (hops === 0) return [nodeId]\n const segments = nodeIdToSegmentIds.get(nodeId)!\n const nodes = new Set<CapacityMeshNodeId>()\n for (const segmentId of segments) {\n const adjacentNodeIds = segmentIdToNodeIds.get(segmentId)!\n for (const adjacentNodeId of adjacentNodeIds) {\n const ancestors = getNodesNearNode({\n nodeId: adjacentNodeId,\n nodeIdToSegmentIds,\n segmentIdToNodeIds,\n hops: hops - 1,\n })\n for (const ancestor of ancestors) {\n nodes.add(ancestor)\n }\n }\n }\n return Array.from(nodes)\n}\n","import { SegmentPointId } from \"./types\"\n\nexport const createPointModificationsHash = (\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n) => {\n return Array.from(pointModifications.entries())\n .map(\n ([id, { x, y, z }]) =>\n `${id}(${x?.toFixed(3) ?? \"\"},${y?.toFixed(3) ?? \"\"},${z ?? \"\"})`,\n )\n .sort()\n .join(\"&\")\n}\n\nexport const createFullPointModificationsHash = (\n originalPoints: Map<SegmentPointId, { x: number; y: number; z: number }>,\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n) => {\n return Array.from(originalPoints.entries())\n .map(([id, originalPoint]) => {\n const mods = pointModifications.get(id)\n const finalPoint = {\n x: mods?.x !== undefined ? mods.x : originalPoint.x,\n y: mods?.y !== undefined ? mods.y : originalPoint.y,\n z: mods?.z !== undefined ? mods.z : originalPoint.z,\n }\n return `${id}(${finalPoint.x.toFixed(3)},${finalPoint.y.toFixed(3)},${finalPoint.z})`\n })\n .sort()\n .join(\"&\")\n}\n","export const hasZRangeOverlap = (\n A_z1: number,\n A_z2: number,\n B_z1: number,\n B_z2: number,\n) => {\n const Amin = Math.min(A_z1, A_z2)\n const Amax = Math.max(A_z1, A_z2)\n const Bmin = Math.min(B_z1, B_z2)\n const Bmax = Math.max(B_z1, B_z2)\n return Amin <= Bmax && Amax >= Bmin\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport {\n UnravelSection,\n UnravelIssue,\n UnravelTransitionViaIssue,\n SegmentPoint,\n SegmentPointId,\n UnravelSameLayerCrossingIssue,\n UnravelSingleTransitionCrossingIssue,\n UnravelDoubleTransitionCrossingIssue,\n} from \"./types\"\nimport { getIntraNodeCrossingsFromSegments } from \"lib/utils/getIntraNodeCrossingsFromSegments\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\nimport { getLogProbability } from \"./getLogProbability\"\nimport { doSegmentsIntersect } from \"@tscircuit/math-utils\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { hasZRangeOverlap } from \"./hasZRangeOverlap\"\n\nexport const getIssuesInSection = (\n section: UnravelSection,\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>,\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n connMap?: ConnectivityMap,\n): UnravelIssue[] => {\n const issues: UnravelIssue[] = []\n\n const points: Map<SegmentPointId, { x: number; y: number; z: number }> =\n new Map()\n for (const nodeId of section.allNodeIds) {\n for (const segmentPointId of section.segmentPointsInNode.get(nodeId)!) {\n if (!points.has(segmentPointId)) {\n const ogPoint = section.segmentPointMap.get(segmentPointId)!\n const modPoint = pointModifications.get(segmentPointId)\n points.set(segmentPointId, {\n x: modPoint?.x ?? ogPoint.x,\n y: modPoint?.y ?? ogPoint.y,\n z: modPoint?.z ?? ogPoint.z,\n })\n }\n }\n }\n\n for (const nodeId of section.allNodeIds) {\n const node = nodeMap.get(nodeId)\n if (!node) continue\n\n const nodeSegmentPairs = section.segmentPairsInNode.get(nodeId)!\n\n // If there's a Z transition within the pair, there's a transition_via issue\n for (const pair of nodeSegmentPairs) {\n const A = points.get(pair[0])!\n const B = points.get(pair[1])!\n if (A.z !== B.z) {\n issues.push({\n type: \"transition_via\",\n segmentPoints: pair,\n capacityMeshNodeId: nodeId,\n probabilityOfFailure: 0,\n })\n }\n }\n\n // Find crossing issues\n for (let i = 0; i < nodeSegmentPairs.length; i++) {\n for (let j = i + 1; j < nodeSegmentPairs.length; j++) {\n if (\n connMap?.areIdsConnected(\n nodeSegmentPairs[i][0],\n nodeSegmentPairs[i][1],\n )\n ) {\n continue\n }\n\n const pair1 = nodeSegmentPairs[i]\n const pair2 = nodeSegmentPairs[j]\n\n const A = points.get(pair1[0])!\n const B = points.get(pair1[1])!\n const C = points.get(pair2[0])!\n const D = points.get(pair2[1])!\n\n // Are the lines ever on the same layer? Is there any risk of overlap?\n if (!hasZRangeOverlap(A.z, B.z, C.z, D.z)) continue\n\n const areCrossing = doSegmentsIntersect(A, B, C, D)\n const isSameLayer = A.z === B.z && C.z === D.z && A.z === C.z\n if (areCrossing) {\n if (isSameLayer) {\n issues.push({\n type: \"same_layer_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n crossingLine1: pair1,\n crossingLine2: pair2,\n probabilityOfFailure: 0,\n } as UnravelSameLayerCrossingIssue)\n } else if (A.z === B.z && C.z !== D.z) {\n issues.push({\n type: \"single_transition_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n sameLayerCrossingLine: pair1,\n transitionCrossingLine: pair2,\n probabilityOfFailure: 0,\n } as UnravelSingleTransitionCrossingIssue)\n } else if (A.z !== B.z && C.z === D.z) {\n issues.push({\n type: \"single_transition_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n sameLayerCrossingLine: pair2,\n transitionCrossingLine: pair1,\n probabilityOfFailure: 0,\n } as UnravelSingleTransitionCrossingIssue)\n } else if (A.z !== B.z && C.z !== D.z) {\n issues.push({\n type: \"double_transition_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n crossingLine1: pair1,\n crossingLine2: pair2,\n probabilityOfFailure: 0,\n } as UnravelDoubleTransitionCrossingIssue)\n }\n }\n }\n }\n }\n\n return issues\n}\n","export const getLogProbability = (probability: number) => {\n const K = -2.3\n return 1 - Math.exp(probability * K)\n}\n","import { SegmentPointId, UnravelOperation } from \"./types\"\n\n/**\n * Applies an operation to the point modifications map\n * @param pointModifications The current point modifications map\n * @param operation The operation to apply\n * @param getPointInCandidate Function to get the current point values (with any existing modifications)\n * @returns The modified point modifications map\n */\nexport const applyOperationToPointModifications = (\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n operation: UnravelOperation,\n getPointInCandidate: (segmentPointId: SegmentPointId) => {\n x: number\n y: number\n z: number\n segmentId: string\n },\n) => {\n if (operation.type === \"change_layer\") {\n for (const segmentPointId of operation.segmentPointIds) {\n const existingMods = pointModifications.get(segmentPointId) || {}\n pointModifications.set(segmentPointId, {\n ...existingMods,\n z: operation.newZ,\n })\n }\n } else if (operation.type === \"swap_position_on_segment\") {\n const [ASpId, BSpId] = operation.segmentPointIds\n const A = getPointInCandidate(ASpId)\n const B = getPointInCandidate(BSpId)\n\n const existingModsA = pointModifications.get(ASpId) || {}\n const existingModsB = pointModifications.get(BSpId) || {}\n\n pointModifications.set(ASpId, {\n ...existingModsA,\n x: B.x,\n y: B.y,\n })\n\n pointModifications.set(BSpId, {\n ...existingModsB,\n x: A.x,\n y: A.y,\n })\n } else if (operation.type === \"combined\") {\n // For combined operations, recursively apply each operation\n for (const subOperation of operation.operations) {\n // Apply each sub-operation directly to the modifications\n applyOperationToPointModifications(\n pointModifications,\n subOperation,\n getPointInCandidate,\n )\n }\n }\n}\n","import { CapacityMeshNodeId } from \"lib/types\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport {\n SegmentId,\n SegmentPoint,\n SegmentPointId,\n SegmentPointMap,\n} from \"./types\"\n\nexport const createSegmentPointMap = (\n dedupedSegments: SegmentWithAssignedPoints[],\n segmentIdToNodeIds: Map<SegmentId, CapacityMeshNodeId[]>,\n): SegmentPointMap => {\n const segmentPoints: SegmentPoint[] = []\n let highestSegmentPointId = 0\n for (const segment of dedupedSegments) {\n for (const point of segment.assignedPoints!) {\n segmentPoints.push({\n segmentPointId: `SP${highestSegmentPointId++}`,\n segmentId: segment.nodePortSegmentId!,\n capacityMeshNodeIds: segmentIdToNodeIds.get(\n segment.nodePortSegmentId!,\n )!,\n connectionName: point.connectionName,\n x: point.point.x,\n y: point.point.y,\n z: point.point.z,\n directlyConnectedSegmentPointIds: [],\n })\n }\n }\n\n const segmentPointMap = new Map<SegmentPointId, SegmentPoint>()\n for (const segmentPoint of segmentPoints) {\n segmentPointMap.set(segmentPoint.segmentPointId, segmentPoint)\n }\n\n return segmentPointMap\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport {\n UnravelSection,\n UnravelCandidate,\n SegmentPoint,\n SegmentPointId,\n SegmentId,\n UnravelOperation,\n UnravelIssue,\n SegmentPointMap,\n} from \"./types\"\nimport { getNodesNearNode } from \"./getNodesNearNode\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport {\n createFullPointModificationsHash,\n createPointModificationsHash,\n} from \"./createPointModificationsHash\"\nimport { getIssuesInSection } from \"./getIssuesInSection\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\nimport { getLogProbability } from \"./getLogProbability\"\nimport { applyOperationToPointModifications } from \"./applyOperationToPointModifications\"\nimport { createSegmentPointMap } from \"./createSegmentPointMap\"\n\n/**\n * The UntangleSectionSolver optimizes a section of connected capacity nodes\n * with their deduplicated segments.\n *\n * The section always has a \"root\" node. From the root node, MUTABLE_HOPS are\n * taken to reach other nodes that are mutable. One additional hop is taken to\n * have all the impacted nodes in section. So a section is composed of mutable\n * and immutable nodes.\n *\n * The goal of the solver is to perform operations on the mutable nodes of the\n * section to lower the overall cost of the section.\n *\n * The untangle phase will perform \"operations\" on segments based on \"issues\"\n *\n * An \"issue\" is anything that increases the cost of the node:\n * - Anything that causes a via (e.g. layer transition)\n * - Any time two traces cross on the same layer\n *\n * An operation is a change to a segment. There are two main operations:\n * - Change layer\n * - Change point order on segment\n *\n * This solver works by exploring different paths of operations. When an\n * operation is performed, new issues are created. Each path has a cost, and\n * a set of neighbors representing next operations to perform.\n *\n */\nexport class UnravelSectionSolver extends BaseSolver {\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n dedupedSegments: SegmentWithAssignedPoints[]\n dedupedSegmentMap: Map<SegmentId, SegmentWithAssignedPoints>\n\n MUTABLE_HOPS = 1\n\n unravelSection: UnravelSection\n\n candidates: UnravelCandidate[] = []\n\n lastProcessedCandidate: UnravelCandidate | null = null\n bestCandidate: UnravelCandidate | null = null\n originalCandidate: UnravelCandidate\n\n rootNodeId: CapacityMeshNodeId\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n colorMap: Record<string, string>\n tunedNodeCapacityMap: Map<CapacityMeshNodeId, number>\n MAX_CANDIDATES = 500\n\n selectedCandidateIndex: number | \"best\" | \"original\" | null = null\n\n queuedOrExploredCandidatePointModificationHashes: Set<string> = new Set()\n\n constructor(params: {\n rootNodeId: CapacityMeshNodeId\n colorMap?: Record<string, string>\n MUTABLE_HOPS?: number\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n dedupedSegments: SegmentWithAssignedPoints[]\n dedupedSegmentMap?: Map<SegmentId, SegmentWithAssignedPoints>\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentPointMap?: SegmentPointMap\n }) {\n super()\n\n this.MUTABLE_HOPS = params.MUTABLE_HOPS ?? this.MUTABLE_HOPS\n\n this.nodeMap = params.nodeMap\n this.dedupedSegments = params.dedupedSegments\n if (params.dedupedSegmentMap) {\n this.dedupedSegmentMap = params.dedupedSegmentMap\n } else {\n this.dedupedSegmentMap = new Map()\n for (const segment of this.dedupedSegments) {\n this.dedupedSegmentMap.set(segment.nodePortSegmentId!, segment)\n }\n }\n this.nodeIdToSegmentIds = params.nodeIdToSegmentIds\n this.segmentIdToNodeIds = params.segmentIdToNodeIds\n this.rootNodeId = params.rootNodeId\n this.colorMap = params.colorMap ?? {}\n this.unravelSection = this.createUnravelSection(params.segmentPointMap)\n this.tunedNodeCapacityMap = new Map()\n for (const nodeId of this.unravelSection.allNodeIds) {\n this.tunedNodeCapacityMap.set(\n nodeId,\n getTunedTotalCapacity1(this.nodeMap.get(nodeId)!),\n )\n }\n this.originalCandidate = this.createInitialCandidate()\n this.candidates = [this.originalCandidate]\n }\n\n createUnravelSection(segmentPointMap?: SegmentPointMap): UnravelSection {\n const mutableNodeIds = getNodesNearNode({\n nodeId: this.rootNodeId,\n nodeIdToSegmentIds: this.nodeIdToSegmentIds,\n segmentIdToNodeIds: this.segmentIdToNodeIds,\n hops: this.MUTABLE_HOPS,\n })\n const allNodeIds = getNodesNearNode({\n nodeId: this.rootNodeId,\n nodeIdToSegmentIds: this.nodeIdToSegmentIds,\n segmentIdToNodeIds: this.segmentIdToNodeIds,\n hops: this.MUTABLE_HOPS + 1,\n })\n const immutableNodeIds = Array.from(\n new Set(allNodeIds).difference(new Set(mutableNodeIds)),\n )\n\n if (!segmentPointMap) {\n segmentPointMap = createSegmentPointMap(\n this.dedupedSegments,\n this.segmentIdToNodeIds,\n )\n }\n\n const segmentPoints = Array.from(segmentPointMap.values())\n\n const segmentPointsInNode = new Map<CapacityMeshNodeId, SegmentPointId[]>()\n for (const segmentPoint of segmentPoints) {\n for (const nodeId of segmentPoint.capacityMeshNodeIds) {\n segmentPointsInNode.set(nodeId, [\n ...(segmentPointsInNode.get(nodeId) ?? []),\n segmentPoint.segmentPointId,\n ])\n }\n }\n\n const segmentPointsInSegment = new Map<SegmentId, SegmentPointId[]>()\n for (const segmentPoint of segmentPoints) {\n segmentPointsInSegment.set(segmentPoint.segmentId, [\n ...(segmentPointsInSegment.get(segmentPoint.segmentId) ?? []),\n segmentPoint.segmentPointId,\n ])\n }\n\n // Second pass: set neighboring segment point ids\n for (let i = 0; i < segmentPoints.length; i++) {\n const A = segmentPoints[i]\n for (let j = i + 1; j < segmentPoints.length; j++) {\n const B = segmentPoints[j]\n if (B.segmentPointId === A.segmentPointId) continue\n if (B.segmentId === A.segmentId) continue\n if (B.connectionName !== A.connectionName) continue\n // If the points share the same capacity node, and share the same\n // connection name, then they're neighbors\n if (\n A.capacityMeshNodeIds.some((nId) =>\n B.capacityMeshNodeIds.includes(nId),\n )\n ) {\n A.directlyConnectedSegmentPointIds.push(B.segmentPointId)\n B.directlyConnectedSegmentPointIds.push(A.segmentPointId)\n }\n }\n }\n\n const segmentPairsInNode = new Map<\n CapacityMeshNodeId,\n Array<[SegmentPointId, SegmentPointId]>\n >()\n for (const nodeId of allNodeIds) {\n segmentPairsInNode.set(nodeId, [])\n }\n\n for (const A of segmentPoints) {\n for (const nodeId of A.capacityMeshNodeIds) {\n const otherSegmentPoints = segmentPointsInNode\n .get(nodeId)!\n .map((spId) => segmentPointMap.get(spId)!)\n const segmentPairs = segmentPairsInNode.get(nodeId)\n if (!segmentPairs) continue\n for (const BId of A.directlyConnectedSegmentPointIds) {\n const B = segmentPointMap.get(BId)!\n if (B.segmentPointId === A.segmentPointId) continue\n if (!B.capacityMeshNodeIds.some((nId) => nId === nodeId)) continue\n if (\n !segmentPairs.some(\n ([a, b]) =>\n (a === A.segmentPointId && b === B.segmentPointId) ||\n (a === B.segmentPointId && b === A.segmentPointId),\n )\n ) {\n segmentPairs.push([A.segmentPointId, B.segmentPointId])\n }\n }\n }\n }\n\n const mutableSegmentIds = new Set<string>()\n for (const nodeId of mutableNodeIds) {\n for (const segmentId of this.nodeIdToSegmentIds.get(nodeId)!) {\n const allNodeIdsWithSegment = this.segmentIdToNodeIds.get(segmentId)!\n if (\n allNodeIdsWithSegment.every(\n (nodeId) => !this.nodeMap.get(nodeId)!._containsTarget,\n )\n ) {\n mutableSegmentIds.add(segmentId)\n }\n }\n }\n\n return {\n allNodeIds,\n mutableNodeIds,\n immutableNodeIds,\n mutableSegmentIds,\n segmentPairsInNode,\n segmentPointMap,\n segmentPointsInNode,\n segmentPointsInSegment,\n }\n }\n\n createInitialCandidate(): UnravelCandidate {\n const pointModifications = new Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >()\n const issues = getIssuesInSection(\n this.unravelSection,\n this.nodeMap,\n pointModifications,\n )\n const g = this.computeG({\n issues,\n originalCandidate: {} as any,\n operationsPerformed: 0,\n operation: {} as any,\n })\n return {\n pointModifications,\n issues,\n g,\n h: 0,\n f: g,\n operationsPerformed: 0,\n candidateHash: createPointModificationsHash(pointModifications),\n // candidateFullHash: createFullPointModificationsHash(\n // this.unravelSection.segmentPointMap,\n // pointModifications,\n // ),\n }\n }\n\n get nextCandidate(): UnravelCandidate | null {\n return this.candidates[0] ?? null\n }\n\n getPointInCandidate(\n candidate: UnravelCandidate,\n segmentPointId: SegmentPointId,\n ): { x: number; y: number; z: number; segmentId: string } {\n const originalPoint =\n this.unravelSection.segmentPointMap.get(segmentPointId)!\n const modifications = candidate.pointModifications.get(segmentPointId)\n\n return {\n x: modifications?.x ?? originalPoint.x,\n y: modifications?.y ?? originalPoint.y,\n z: modifications?.z ?? originalPoint.z,\n segmentId: originalPoint.segmentId,\n }\n }\n\n getOperationsForIssue(\n candidate: UnravelCandidate,\n issue: UnravelIssue,\n ): UnravelOperation[] {\n const operations: UnravelOperation[] = []\n\n if (issue.type === \"transition_via\") {\n // When there's a transition via, we attempt to change the layer of either\n // end to match the other end\n const [APointId, BPointId] = issue.segmentPoints\n const pointA = this.getPointInCandidate(candidate, APointId)\n const pointB = this.getPointInCandidate(candidate, BPointId)\n\n const aAvailableZ = this.dedupedSegmentMap.get(\n pointA.segmentId,\n )!.availableZ\n const bAvailableZ = this.dedupedSegmentMap.get(\n pointB.segmentId,\n )!.availableZ\n\n if (\n this.unravelSection.mutableSegmentIds.has(pointA.segmentId) &&\n aAvailableZ.includes(pointB.z)\n ) {\n operations.push({\n type: \"change_layer\",\n newZ: pointB.z,\n segmentPointIds: [APointId],\n })\n }\n if (\n this.unravelSection.mutableSegmentIds.has(pointB.segmentId) &&\n bAvailableZ.includes(pointA.z)\n ) {\n operations.push({\n type: \"change_layer\",\n newZ: pointA.z,\n segmentPointIds: [BPointId],\n })\n }\n }\n\n if (issue.type === \"same_layer_crossing\") {\n // For a same-layer crossing, we should try all the following:\n // 1. Swap the points on each segment (for each shared segment, if any)\n // 2. Change the layer of each segment entirely to remove the crossing\n // 3. Change the layer of each point individually to make it a transition\n // crossing\n\n // 1. SWAP POINTS\n const [APointId, BPointId] = issue.crossingLine1\n const [CPointId, DPointId] = issue.crossingLine2\n\n const sharedSegments: Array<[SegmentPointId, SegmentPointId]> = []\n const A = this.unravelSection.segmentPointMap.get(APointId)!\n const B = this.unravelSection.segmentPointMap.get(BPointId)!\n const C = this.unravelSection.segmentPointMap.get(CPointId)!\n const D = this.unravelSection.segmentPointMap.get(DPointId)!\n\n if (A.segmentId === C.segmentId) {\n sharedSegments.push([APointId, CPointId])\n }\n if (A.segmentId === D.segmentId) {\n sharedSegments.push([APointId, DPointId])\n }\n if (B.segmentId === C.segmentId) {\n sharedSegments.push([BPointId, CPointId])\n }\n if (B.segmentId === D.segmentId) {\n sharedSegments.push([BPointId, DPointId])\n }\n\n for (const [EPointId, FPointId] of sharedSegments) {\n operations.push({\n type: \"swap_position_on_segment\",\n segmentPointIds: [EPointId, FPointId],\n })\n }\n\n // 2. CHANGE LAYER OF EACH SEGMENT ENTIRELY TO REMOVE CROSSING\n const Amutable = this.unravelSection.mutableSegmentIds.has(A.segmentId)\n const Bmutable = this.unravelSection.mutableSegmentIds.has(B.segmentId)\n const Cmutable = this.unravelSection.mutableSegmentIds.has(C.segmentId)\n const Dmutable = this.unravelSection.mutableSegmentIds.has(D.segmentId)\n if (Amutable && Bmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: A.z === 0 ? 1 : 0,\n segmentPointIds: [APointId, BPointId],\n })\n }\n if (Cmutable && Dmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: C.z === 0 ? 1 : 0,\n segmentPointIds: [CPointId, DPointId],\n })\n }\n\n // 3. CHANGE LAYER OF EACH POINT INDIVIDUALLY TO MAKE TRANSITION CROSSING\n if (Amutable) {\n operations.push({\n type: \"change_layer\",\n newZ: A.z === 0 ? 1 : 0,\n segmentPointIds: [APointId],\n })\n }\n if (Bmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: B.z === 0 ? 1 : 0,\n segmentPointIds: [BPointId],\n })\n }\n if (Cmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: C.z === 0 ? 1 : 0,\n segmentPointIds: [CPointId],\n })\n }\n if (Dmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: D.z === 0 ? 1 : 0,\n segmentPointIds: [DPointId],\n })\n }\n }\n\n // TODO single_transition_crossing\n // TODO double_transition_crossing\n // TODO same_layer_trace_imbalance_with_low_capacity\n\n return operations\n }\n\n computeG(params: {\n issues: UnravelIssue[]\n originalCandidate: UnravelCandidate\n operationsPerformed: number\n operation: UnravelOperation\n }): number {\n const { issues, originalCandidate, operationsPerformed, operation } = params\n\n const nodeProblemCounts = new Map<\n CapacityMeshNodeId,\n {\n numTransitionCrossings: number\n numSameLayerCrossings: number\n numEntryExitLayerChanges: number\n }\n >()\n\n for (const issue of issues) {\n if (!nodeProblemCounts.has(issue.capacityMeshNodeId)) {\n nodeProblemCounts.set(issue.capacityMeshNodeId, {\n numTransitionCrossings: 0,\n numSameLayerCrossings: 0,\n numEntryExitLayerChanges: 0,\n })\n }\n\n const nodeProblemCount = nodeProblemCounts.get(issue.capacityMeshNodeId)!\n\n if (issue.type === \"transition_via\") {\n nodeProblemCount.numTransitionCrossings++\n } else if (issue.type === \"same_layer_crossing\") {\n nodeProblemCount.numSameLayerCrossings++\n } else if (\n issue.type === \"double_transition_crossing\" ||\n issue.type === \"single_transition_crossing\"\n ) {\n nodeProblemCount.numEntryExitLayerChanges++\n } else if (\n issue.type === \"same_layer_trace_imbalance_with_low_capacity\"\n ) {\n // TODO\n }\n }\n\n let cost = 0\n\n for (const [\n nodeId,\n {\n numEntryExitLayerChanges,\n numSameLayerCrossings,\n numTransitionCrossings,\n },\n ] of nodeProblemCounts) {\n const estNumVias =\n numSameLayerCrossings * 0.82 +\n numEntryExitLayerChanges * 0.41 +\n numTransitionCrossings * 0.2\n\n const estUsedCapacity = (estNumVias / 2) ** 1.1\n\n const totalCapacity = this.tunedNodeCapacityMap.get(nodeId)!\n\n const estPf = estUsedCapacity / totalCapacity\n\n cost += getLogProbability(estPf)\n }\n\n return cost\n }\n\n getNeighborByApplyingOperation(\n currentCandidate: UnravelCandidate,\n operation: UnravelOperation,\n ): UnravelCandidate {\n const pointModifications = new Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >(currentCandidate.pointModifications)\n\n applyOperationToPointModifications(\n pointModifications,\n operation,\n (segmentPointId) =>\n this.getPointInCandidate(currentCandidate, segmentPointId),\n )\n\n const issues = getIssuesInSection(\n this.unravelSection,\n this.nodeMap,\n pointModifications,\n )\n\n const operationsPerformed = currentCandidate.operationsPerformed + 1\n\n const g = this.computeG({\n issues,\n originalCandidate: currentCandidate,\n operationsPerformed,\n operation,\n })\n\n return {\n issues,\n g,\n h: 0,\n f: g,\n pointModifications,\n candidateHash: createPointModificationsHash(pointModifications),\n\n // TODO PERFORMANCE allow disabling this\n // candidateFullHash: createFullPointModificationsHash(\n // this.unravelSection.segmentPointMap,\n // pointModifications,\n // ),\n\n operationsPerformed,\n }\n }\n\n getNeighborOperationsForCandidate(\n candidate: UnravelCandidate,\n ): UnravelOperation[] {\n return candidate.issues.flatMap((issue) =>\n this.getOperationsForIssue(candidate, issue),\n )\n }\n\n getNeighbors(candidate: UnravelCandidate): UnravelCandidate[] {\n const neighbors: UnravelCandidate[] = []\n\n const operations = this.getNeighborOperationsForCandidate(candidate)\n for (const operation of operations) {\n const neighbor = this.getNeighborByApplyingOperation(candidate, operation)\n neighbors.push(neighbor)\n }\n\n return neighbors\n }\n\n _step() {\n const candidate = this.candidates.shift()\n if (!candidate) {\n this.solved = true\n return\n }\n this.lastProcessedCandidate = candidate\n\n if (candidate.f < (this.bestCandidate?.f ?? Infinity)) {\n this.bestCandidate = candidate\n // TODO, only works if we start computing f\n // if (candidate.f <= 0.00001) {\n // this.solved = true\n // return\n // }\n }\n\n this.getNeighbors(candidate).forEach((neighbor) => {\n const isPartialHashExplored =\n this.queuedOrExploredCandidatePointModificationHashes.has(\n neighbor.candidateHash,\n )\n // const isFullHashExplored =\n // neighbor.candidateFullHash &&\n // this.queuedOrExploredCandidatePointModificationHashes.has(\n // neighbor.candidateFullHash,\n // )\n\n // if (isPartialHashExplored || isFullHashExplored) return\n if (isPartialHashExplored) return\n this.queuedOrExploredCandidatePointModificationHashes.add(\n neighbor.candidateHash,\n )\n // if (neighbor.candidateFullHash) {\n // this.queuedOrExploredCandidatePointModificationHashes.add(\n // neighbor.candidateFullHash,\n // )\n // }\n this.candidates.push(neighbor)\n })\n this.candidates.sort((a, b) => a.f - b.f)\n this.candidates.length = Math.min(\n this.candidates.length,\n this.MAX_CANDIDATES,\n )\n }\n\n visualize(): GraphicsObject {\n const graphics: Required<GraphicsObject> = {\n points: [],\n lines: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Unravel Section Solver\",\n }\n\n // Get the candidate to visualize\n let candidate: UnravelCandidate | null = null\n if (this.selectedCandidateIndex !== null) {\n if (this.selectedCandidateIndex === \"best\") {\n candidate = this.bestCandidate\n } else if (this.selectedCandidateIndex === \"original\") {\n candidate = this.originalCandidate\n } else {\n candidate = this.candidates[this.selectedCandidateIndex]\n }\n } else {\n candidate = this.lastProcessedCandidate || this.candidates[0]\n }\n if (!candidate) return graphics\n\n // Create a map of segment points with modifications applied\n const modifiedSegmentPoints = new Map<string, SegmentPoint>()\n for (const [segmentPointId, segmentPoint] of this.unravelSection\n .segmentPointMap) {\n // Create a copy of the original point\n const modifiedPoint = { ...segmentPoint }\n\n // Apply any modifications from the candidate\n const modification = candidate.pointModifications.get(segmentPointId)\n if (modification) {\n if (modification.x !== undefined) modifiedPoint.x = modification.x\n if (modification.y !== undefined) modifiedPoint.y = modification.y\n if (modification.z !== undefined) modifiedPoint.z = modification.z\n }\n\n modifiedSegmentPoints.set(segmentPointId, modifiedPoint)\n }\n\n // Visualize all segment points with modifications applied\n for (const [segmentPointId, segmentPoint] of modifiedSegmentPoints) {\n graphics.points.push({\n x: segmentPoint.x,\n y: segmentPoint.y,\n label: `${segmentPointId}\\nSegment: ${segmentPoint.segmentId} ${this.unravelSection.mutableSegmentIds.has(segmentPoint.segmentId) ? \"MUTABLE\" : \"IMMUTABLE\"}\\nLayer: ${segmentPoint.z}`,\n color: this.colorMap[segmentPoint.connectionName] || \"#000\",\n })\n }\n\n // Visualize nodes\n for (const nodeId of this.unravelSection.allNodeIds) {\n const node = this.nodeMap.get(nodeId)!\n const isMutable = this.unravelSection.mutableNodeIds.includes(nodeId)\n\n graphics.rects.push({\n center: node.center,\n label: `${nodeId}\\n${node.width.toFixed(2)}x${node.height.toFixed(2)}\\n${isMutable ? \"MUTABLE\" : \"IMMUTABLE\"}`,\n color: isMutable ? \"green\" : \"red\",\n width: node.width / 8,\n height: node.height / 8,\n })\n }\n\n // Connect segment points that belong to the same segment\n for (const [segmentId, segmentPointIds] of this.unravelSection\n .segmentPointsInSegment) {\n if (segmentPointIds.length <= 1) continue\n\n const points = segmentPointIds.map(\n (spId) => modifiedSegmentPoints.get(spId)!,\n )\n\n // Connect points in order\n for (let i = 0; i < points.length - 1; i++) {\n graphics.lines.push({\n points: [\n { x: points[i].x, y: points[i].y },\n { x: points[i + 1].x, y: points[i + 1].y },\n ],\n strokeColor: this.colorMap[segmentId] || \"#000\",\n })\n }\n }\n\n // Connect directly connected segment points (points with the same connection name)\n for (const [segmentPointId, segmentPoint] of modifiedSegmentPoints) {\n for (const connectedPointId of segmentPoint.directlyConnectedSegmentPointIds) {\n // Only process each connection once (when the current point's ID is less than the connected point's ID)\n if (segmentPointId < connectedPointId) {\n const connectedPoint = modifiedSegmentPoints.get(connectedPointId)!\n\n // Determine line style based on layer (z) values\n const sameLayer = segmentPoint.z === connectedPoint.z\n const commonLayer = segmentPoint.z\n\n let strokeDash: string | undefined\n if (sameLayer) {\n strokeDash = commonLayer === 0 ? undefined : \"10 5\" // top layer: solid, bottom layer: long dash\n } else {\n strokeDash = \"3 3 10\" // transition between layers: mixed dash pattern\n }\n\n graphics.lines.push({\n points: [\n { x: segmentPoint.x, y: segmentPoint.y },\n { x: connectedPoint.x, y: connectedPoint.y },\n ],\n strokeDash,\n strokeColor: this.colorMap[segmentPoint.connectionName] || \"#000\",\n })\n }\n }\n }\n\n // Visualize issues\n for (const issue of candidate.issues) {\n const node = this.nodeMap.get(issue.capacityMeshNodeId)!\n\n if (issue.type === \"transition_via\") {\n // Highlight via issues\n for (const segmentPointId of issue.segmentPoints) {\n const segmentPoint = modifiedSegmentPoints.get(segmentPointId)!\n graphics.circles.push({\n center: { x: segmentPoint.x, y: segmentPoint.y },\n radius: node.width / 16,\n stroke: \"#ff0000\",\n fill: \"rgba(255, 0, 0, 0.2)\",\n label: `Via Issue\\n${segmentPointId}\\nLayer: ${segmentPoint.z}`,\n })\n }\n } else if (issue.type === \"same_layer_crossing\") {\n // Highlight crossing issues\n for (const [sp1Id, sp2Id] of [\n issue.crossingLine1,\n issue.crossingLine2,\n ]) {\n const sp1 = modifiedSegmentPoints.get(sp1Id)!\n const sp2 = modifiedSegmentPoints.get(sp2Id)!\n\n graphics.lines.push({\n points: [\n { x: sp1.x, y: sp1.y },\n { x: sp2.x, y: sp2.y },\n ],\n strokeColor: \"rgba(255,0,0,0.2)\",\n strokeWidth: node.width / 32,\n })\n }\n }\n }\n\n // Highlight modified points\n for (const [segmentPointId, modification] of candidate.pointModifications) {\n const modifiedPoint = modifiedSegmentPoints.get(segmentPointId)!\n const originalPoint =\n this.unravelSection.segmentPointMap.get(segmentPointId)!\n\n graphics.circles.push({\n center: { x: modifiedPoint.x, y: modifiedPoint.y },\n radius: 0.05,\n stroke: \"#0000ff\",\n fill: \"rgba(0, 0, 255, 0.2)\",\n label: `${segmentPointId}\\nOriginal: (${originalPoint.x.toFixed(2)}, ${originalPoint.y.toFixed(2)}, ${originalPoint.z})\\nNew: (${modifiedPoint.x.toFixed(2)}, ${modifiedPoint.y.toFixed(2)}, ${modifiedPoint.z})`,\n })\n }\n\n return graphics\n }\n}\n","import { NodePortSegment } from \"lib/types/capacity-edges-to-port-segments-types\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\n\n/**\n * Deduplicates segments with the same start and end points.\n * Assigns a unique ID to each unique segment and ensures all segments with the same\n * start/end points share the same ID.\n * @param assignedSegments The segments to deduplicate\n * @returns Deduplicated segments with unique IDs\n */\nexport const getDedupedSegments = (\n assignedSegments: NodePortSegment[],\n): SegmentWithAssignedPoints[] => {\n const dedupedSegments: SegmentWithAssignedPoints[] = []\n type SegKey = `${number}-${number}-${number}-${number}`\n const dedupedSegPointMap: Map<SegKey, NodePortSegment> = new Map()\n let highestSegmentId = -1\n\n for (const seg of assignedSegments) {\n // Check if there's another segment with the same start and end\n const segKey: SegKey = `${seg.start.x}-${seg.start.y}-${seg.end.x}-${seg.end.y}`\n const existingSeg = dedupedSegPointMap.get(segKey)\n\n if (!existingSeg) {\n highestSegmentId++\n seg.nodePortSegmentId = `SEG${highestSegmentId}`\n dedupedSegPointMap.set(segKey, seg)\n dedupedSegments.push(seg)\n continue\n }\n\n seg.nodePortSegmentId = existingSeg.nodePortSegmentId\n }\n\n return dedupedSegments\n}\n","import { doSegmentsIntersect } from \"@tscircuit/math-utils\"\nimport { SegmentWithAssignedPoints } from \"lib/solvers/CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport { NodeWithPortPoints } from \"lib/types/high-density-types\"\n\n/**\n * Get the number of crossings between segments on the same node\n */\nexport const getIntraNodeCrossingsFromSegments = (\n segments: SegmentWithAssignedPoints[],\n): {\n numSameLayerCrossings: number\n numEntryExitLayerChanges: number\n numTransitionCrossings: number\n} => {\n // Count the number of crossings\n let numSameLayerCrossings = 0\n const pointPairs: {\n points: { x: number; y: number; z: number }[]\n z: number\n connectionName: string\n }[] = []\n\n const transitionPairPoints: {\n points: { x: number; y: number; z: number }[]\n connectionName: string\n }[] = []\n\n let numEntryExitLayerChanges = 0\n\n const portPoints = segments.flatMap((seg) => seg.assignedPoints!)\n\n for (const { connectionName: aConnName, point: A } of portPoints) {\n if (pointPairs.some((p) => p.connectionName === aConnName)) {\n continue\n }\n if (transitionPairPoints.some((p) => p.connectionName === aConnName)) {\n continue\n }\n const pointPair = {\n connectionName: aConnName,\n z: A.z,\n points: [A],\n }\n for (const { connectionName: bConnName, point: B } of portPoints) {\n if (aConnName !== bConnName) continue\n if (A === B) continue\n pointPair.points.push(B)\n\n if (pointPair.points.some((p) => p.z !== pointPair.z)) {\n numEntryExitLayerChanges++\n transitionPairPoints.push(pointPair)\n break\n } else {\n pointPairs.push(pointPair)\n break\n }\n }\n }\n\n for (let i = 0; i < pointPairs.length; i++) {\n for (let j = i + 1; j < pointPairs.length; j++) {\n const pair1 = pointPairs[i]\n const pair2 = pointPairs[j]\n if (\n pair1.z === pair2.z &&\n doSegmentsIntersect(\n pair1.points[0],\n pair1.points[1],\n pair2.points[0],\n pair2.points[1],\n )\n ) {\n numSameLayerCrossings++\n }\n }\n }\n\n let numTransitionCrossings = 0\n for (let i = 0; i < transitionPairPoints.length; i++) {\n for (let j = i + 1; j < transitionPairPoints.length; j++) {\n const pair1 = transitionPairPoints[i]\n const pair2 = transitionPairPoints[j]\n\n if (\n doSegmentsIntersect(\n pair1.points[0],\n pair1.points[1],\n pair2.points[0],\n pair2.points[1],\n )\n ) {\n numTransitionCrossings++\n }\n }\n }\n\n for (let i = 0; i < transitionPairPoints.length; i++) {\n for (let j = 0; j < pointPairs.length; j++) {\n const pair1 = transitionPairPoints[i]\n const pair2 = pointPairs[j]\n if (\n doSegmentsIntersect(\n pair1.points[0],\n pair1.points[1],\n pair2.points[0],\n pair2.points[1],\n )\n ) {\n numTransitionCrossings++\n }\n }\n }\n\n return {\n numSameLayerCrossings,\n numEntryExitLayerChanges,\n numTransitionCrossings,\n }\n}\n","import { CapacityMeshNode } from \"lib/types\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\n\nexport const calculateNodeProbabilityOfFailure = (\n node: CapacityMeshNode,\n numSameLayerCrossings: number,\n numEntryExitLayerChanges: number,\n numTransitionCrossings: number,\n): number => {\n if (node?._containsTarget) return 0\n\n // Number of traces through the node\n const totalCapacity = getTunedTotalCapacity1(node)\n\n // Estimated number of vias based on crossings\n const estNumVias =\n numSameLayerCrossings * 0.82 +\n numEntryExitLayerChanges * 0.41 +\n numTransitionCrossings * 0.2\n\n const estUsedCapacity = (estNumVias / 2) ** 1.1\n\n // We could refine this with actual trace capacity\n const approxProb = estUsedCapacity / totalCapacity\n\n // Bounded probability calculation\n return approxProb\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport { UnravelSectionSolver } from \"./UnravelSectionSolver\"\nimport { getIntraNodeCrossings } from \"lib/utils/getIntraNodeCrossings\"\nimport { NodePortSegment } from \"lib/types/capacity-edges-to-port-segments-types\"\nimport { getDedupedSegments } from \"./getDedupedSegments\"\nimport { getIntraNodeCrossingsFromSegments } from \"lib/utils/getIntraNodeCrossingsFromSegments\"\nimport { calculateNodeProbabilityOfFailure } from \"./calculateCrossingProbabilityOfFailure\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { NodeWithPortPoints } from \"lib/types/high-density-types\"\nimport {\n PointModificationsMap,\n SegmentId,\n SegmentPoint,\n SegmentPointId,\n SegmentPointMap,\n} from \"./types\"\nimport { createSegmentPointMap } from \"./createSegmentPointMap\"\n\nexport class UnravelMultiSectionSolver extends BaseSolver {\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n dedupedSegmentMap: Map<SegmentId, SegmentWithAssignedPoints>\n dedupedSegments: SegmentWithAssignedPoints[]\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n colorMap: Record<string, string>\n tunedNodeCapacityMap: Map<CapacityMeshNodeId, number>\n\n MAX_NODE_ATTEMPTS = 2\n\n MUTABLE_HOPS = 1\n\n ACCEPTABLE_PF = 0.05\n\n /**\n * Probability of failure for each node\n */\n nodePfMap: Map<CapacityMeshNodeId, number>\n\n attemptsToFixNode: Map<CapacityMeshNodeId, number>\n\n activeSolver: UnravelSectionSolver | null = null\n\n segmentPointMap: SegmentPointMap\n\n constructor({\n assignedSegments,\n colorMap,\n nodes,\n }: {\n assignedSegments: NodePortSegment[]\n colorMap?: Record<string, string>\n /**\n * This isn't used by the algorithm, but allows associating metadata\n * for the result datatype (the center, width, height of the node)\n */\n nodes: CapacityMeshNode[]\n }) {\n super()\n\n this.MAX_ITERATIONS = 100_000\n\n this.dedupedSegments = getDedupedSegments(assignedSegments)\n this.dedupedSegmentMap = new Map()\n for (const segment of this.dedupedSegments) {\n this.dedupedSegmentMap.set(segment.nodePortSegmentId!, segment)\n }\n this.nodeMap = new Map()\n for (const node of nodes) {\n this.nodeMap.set(node.capacityMeshNodeId, node)\n }\n\n this.nodeIdToSegmentIds = new Map()\n this.segmentIdToNodeIds = new Map()\n this.attemptsToFixNode = new Map()\n\n for (const segment of assignedSegments) {\n this.segmentIdToNodeIds.set(segment.nodePortSegmentId!, [\n ...(this.segmentIdToNodeIds.get(segment.nodePortSegmentId!) ?? []),\n segment.capacityMeshNodeId,\n ])\n this.nodeIdToSegmentIds.set(segment.capacityMeshNodeId, [\n ...(this.nodeIdToSegmentIds.get(segment.capacityMeshNodeId) ?? []),\n segment.nodePortSegmentId!,\n ])\n }\n\n this.colorMap = colorMap ?? {}\n\n // Compute tuned capacity for each node\n this.tunedNodeCapacityMap = new Map()\n for (const [nodeId, node] of this.nodeMap) {\n this.tunedNodeCapacityMap.set(nodeId, getTunedTotalCapacity1(node))\n }\n\n this.segmentPointMap = createSegmentPointMap(\n this.dedupedSegments,\n this.segmentIdToNodeIds,\n )\n\n this.nodePfMap = this.computeInitialPfMap()\n }\n\n computeInitialPfMap() {\n const pfMap = new Map<CapacityMeshNodeId, number>()\n\n for (const [nodeId, node] of this.nodeMap.entries()) {\n pfMap.set(nodeId, this.computeNodePf(node))\n }\n\n return pfMap\n }\n\n computeNodePf(node: CapacityMeshNode) {\n const {\n numSameLayerCrossings,\n numEntryExitLayerChanges,\n numTransitionCrossings,\n } = getIntraNodeCrossingsFromSegments(\n this.dedupedSegments.filter((seg) =>\n this.segmentIdToNodeIds\n .get(seg.nodePortSegmentId!)!\n .includes(node.capacityMeshNodeId),\n ),\n )\n\n const probabilityOfFailure = calculateNodeProbabilityOfFailure(\n node,\n numSameLayerCrossings,\n numEntryExitLayerChanges,\n numTransitionCrossings,\n )\n\n return probabilityOfFailure\n }\n\n _step() {\n if (this.iterations >= this.MAX_ITERATIONS - 1) {\n this.solved = true\n return\n }\n if (!this.activeSolver) {\n // Find the node with the highest probability of failure\n let highestPfNodeId = null\n let highestPf = 0\n for (const [nodeId, pf] of this.nodePfMap.entries()) {\n const pfReduced =\n pf *\n (1 -\n (this.attemptsToFixNode.get(nodeId) ?? 0) / this.MAX_NODE_ATTEMPTS)\n if (pfReduced > highestPf) {\n highestPf = pf\n highestPfNodeId = nodeId\n }\n }\n\n if (!highestPfNodeId || highestPf < this.ACCEPTABLE_PF) {\n this.solved = true\n return\n }\n\n this.attemptsToFixNode.set(\n highestPfNodeId,\n (this.attemptsToFixNode.get(highestPfNodeId) ?? 0) + 1,\n )\n this.activeSolver = new UnravelSectionSolver({\n dedupedSegments: this.dedupedSegments,\n dedupedSegmentMap: this.dedupedSegmentMap,\n nodeMap: this.nodeMap,\n nodeIdToSegmentIds: this.nodeIdToSegmentIds,\n segmentIdToNodeIds: this.segmentIdToNodeIds,\n colorMap: this.colorMap,\n rootNodeId: highestPfNodeId,\n MUTABLE_HOPS: this.MUTABLE_HOPS,\n segmentPointMap: this.segmentPointMap,\n })\n }\n\n this.activeSolver.step()\n\n const { bestCandidate, originalCandidate, lastProcessedCandidate } =\n this.activeSolver\n\n const giveUpFactor =\n 1 + 4 * (1 - Math.min(1, this.activeSolver.iterations / 40))\n const shouldEarlyStop =\n lastProcessedCandidate &&\n lastProcessedCandidate!.g > bestCandidate!.g * giveUpFactor\n\n if (this.activeSolver.solved || shouldEarlyStop) {\n // Incorporate the changes from the active solver\n\n const foundBetterSolution =\n bestCandidate && bestCandidate.g < originalCandidate!.g\n\n if (foundBetterSolution) {\n // Modify the points using the pointModifications of the candidate\n for (const [\n segmentPointId,\n pointModification,\n ] of bestCandidate.pointModifications.entries()) {\n const segmentPoint = this.segmentPointMap.get(segmentPointId)!\n segmentPoint.x = pointModification.x ?? segmentPoint.x\n segmentPoint.y = pointModification.y ?? segmentPoint.y\n segmentPoint.z = pointModification.z ?? segmentPoint.z\n }\n }\n\n // Update node failure probabilities\n for (const nodeId of this.activeSolver.unravelSection.allNodeIds) {\n this.nodePfMap.set(\n nodeId,\n this.computeNodePf(this.nodeMap.get(nodeId)!),\n )\n }\n\n this.activeSolver = null\n }\n }\n\n visualize(): GraphicsObject {\n if (this.activeSolver) {\n return this.activeSolver.visualize()\n }\n\n const graphics: Required<GraphicsObject> = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Unravel Multi Section Solver\",\n }\n\n // Visualize nodes\n for (const [nodeId, node] of this.nodeMap.entries()) {\n const probabilityOfFailure = this.nodePfMap.get(nodeId) || 0\n // Color based on probability of failure - red for high, gradient to green for low\n const pf = Math.min(probabilityOfFailure, 1) // Cap at 1\n const red = Math.floor(255 * pf)\n const green = Math.floor(255 * (1 - pf))\n const color = `rgb(${red}, ${green}, 0)`\n\n if ((this.attemptsToFixNode.get(nodeId) ?? 0) === 0 && pf === 0) {\n continue\n }\n\n graphics.rects.push({\n center: node.center,\n label: [\n nodeId,\n `${node.width.toFixed(2)}x${node.height.toFixed(2)}`,\n `Pf: ${probabilityOfFailure.toFixed(3)}`,\n ].join(\"\\n\"),\n color,\n width: node.width / 8,\n height: node.height / 8,\n })\n }\n\n // Visualize segment points\n for (const segmentPoint of this.segmentPointMap.values()) {\n const segment = this.dedupedSegmentMap.get(segmentPoint.segmentId)\n graphics.points.push({\n x: segmentPoint.x,\n y: segmentPoint.y,\n label: [\n segmentPoint.segmentPointId,\n segmentPoint.segmentId,\n `z: ${segmentPoint.z}`,\n `segment.availableZ: ${segment?.availableZ.join(\",\")}`,\n ].join(\"\\n\"),\n color: this.colorMap[segmentPoint.connectionName] || \"#000\",\n })\n }\n\n // Connect segment points that belong to the same segment\n // Group points by segment ID\n const pointsBySegment = new Map<string, SegmentPoint[]>()\n for (const point of this.segmentPointMap.values()) {\n if (!pointsBySegment.has(point.segmentId)) {\n pointsBySegment.set(point.segmentId, [])\n }\n pointsBySegment.get(point.segmentId)!.push(point)\n }\n\n // Connect points in each segment\n for (const [segmentId, points] of pointsBySegment.entries()) {\n if (points.length < 2) continue\n\n // Sort points by some logical order (this approximates the correct ordering)\n const sortedPoints = [...points].sort((a, b) =>\n a.x !== b.x ? a.x - b.x : a.y - b.y,\n )\n\n // Connect adjacent points in the sorted order\n for (let i = 0; i < sortedPoints.length - 1; i++) {\n graphics.lines.push({\n points: [\n { x: sortedPoints[i].x, y: sortedPoints[i].y },\n { x: sortedPoints[i + 1].x, y: sortedPoints[i + 1].y },\n ],\n strokeColor: this.colorMap[segmentId] || \"#000\",\n })\n }\n }\n\n // Connect points with the same connection name that share a node\n const processedConnections = new Set<string>()\n const allPoints = Array.from(this.segmentPointMap.values())\n\n for (let i = 0; i < allPoints.length; i++) {\n const point1 = allPoints[i]\n for (let j = i + 1; j < allPoints.length; j++) {\n const point2 = allPoints[j]\n\n // Skip if they have different connection names or are in the same segment\n if (\n point1.connectionName !== point2.connectionName ||\n point1.segmentId === point2.segmentId\n ) {\n continue\n }\n\n // Check if they share a node\n const hasSharedNode = point1.capacityMeshNodeIds.some((nodeId) =>\n point2.capacityMeshNodeIds.includes(nodeId),\n )\n\n if (hasSharedNode) {\n const connectionKey = `${point1.segmentPointId}-${point2.segmentPointId}`\n if (processedConnections.has(connectionKey)) continue\n processedConnections.add(connectionKey)\n\n // Determine line style based on layer (z) values\n const sameLayer = point1.z === point2.z\n const layer = point1.z\n\n let strokeDash: string | undefined\n if (sameLayer) {\n strokeDash = layer === 0 ? undefined : \"10 5\" // Solid for layer 0, long dash for other layers\n } else {\n strokeDash = \"3 3 10\" // Mixed dash for transitions between layers\n }\n\n graphics.lines.push({\n points: [\n { x: point1.x, y: point1.y },\n { x: point2.x, y: point2.y },\n ],\n strokeDash,\n strokeColor: this.colorMap[point1.connectionName] || \"#666\",\n })\n }\n }\n }\n return graphics\n }\n\n getNodesWithPortPoints(): NodeWithPortPoints[] {\n if (!this.solved) {\n throw new Error(\n \"CapacitySegmentToPointSolver not solved, can't give port points yet\",\n )\n }\n const nodeWithPortPointsMap = new Map<string, NodeWithPortPoints>()\n for (const segment of this.dedupedSegments) {\n const segId = segment.nodePortSegmentId!\n for (const nodeId of this.segmentIdToNodeIds.get(segId)!) {\n const node = this.nodeMap.get(nodeId)!\n if (!nodeWithPortPointsMap.has(nodeId)) {\n nodeWithPortPointsMap.set(nodeId, {\n capacityMeshNodeId: nodeId,\n portPoints: [],\n center: node.center,\n width: node.width,\n height: node.height,\n })\n }\n }\n }\n\n for (const segmentPoint of this.segmentPointMap.values()) {\n for (const nodeId of segmentPoint.capacityMeshNodeIds) {\n const nodeWithPortPoints = nodeWithPortPointsMap.get(nodeId)\n if (nodeWithPortPoints) {\n nodeWithPortPoints.portPoints.push({\n x: segmentPoint.x,\n y: segmentPoint.y,\n z: segmentPoint.z,\n connectionName: segmentPoint.connectionName,\n })\n }\n }\n }\n\n return Array.from(nodeWithPortPointsMap.values())\n }\n}\n","import { Rect } from \"graphics-debug\"\nimport { CapacityMeshNode } from \"lib/types\"\n\nexport const createRectFromCapacityNode = (\n node: CapacityMeshNode,\n opts: {\n rectMargin?: number\n } = {},\n): Rect => {\n const lowestZ = Math.min(...node.availableZ)\n return {\n center: !opts.rectMargin\n ? {\n x: node.center.x + lowestZ * node.width * 0.05,\n y: node.center.y - lowestZ * node.width * 0.05,\n }\n : node.center,\n width: opts.rectMargin\n ? node.width - opts.rectMargin * 2\n : Math.max(node.width - 0.5, node.width * 0.8),\n height: opts.rectMargin\n ? node.height - opts.rectMargin * 2\n : Math.max(node.height - 0.5, node.height * 0.8),\n fill: node._containsObstacle\n ? \"rgba(255,0,0,0.1)\"\n : ({\n \"0,1\": \"rgba(0,0,0,0.1)\",\n \"0\": \"rgba(0,200,200, 0.1)\",\n \"1\": \"rgba(0,0,200, 0.1)\",\n }[node.availableZ.join(\",\")] ?? \"rgba(0,200,200,0.1)\"),\n label: [\n node.capacityMeshNodeId,\n `availableZ: ${node.availableZ.join(\",\")}`,\n `${node._containsTarget ? \"containsTarget\" : \"\"}`,\n `${node._containsObstacle ? \"containsObstacle\" : \"\"}`,\n ]\n .filter(Boolean)\n .join(\"\\n\"),\n }\n}\n","import { BaseSolver } from \"../BaseSolver\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n CapacityPath,\n SimpleRouteConnection,\n SimpleRouteJson,\n} from \"../../types\"\nimport { getNodeEdgeMap } from \"../CapacityMeshSolver/getNodeEdgeMap\"\nimport { distance } from \"@tscircuit/math-utils\"\nimport { CapacityHyperParameters } from \"../CapacityHyperParameters\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { safeTransparentize } from \"../colors\"\nimport { createRectFromCapacityNode } from \"lib/utils/createRectFromCapacityNode\"\n\nexport type Candidate = {\n prevCandidate: Candidate | null\n node: CapacityMeshNode\n f: number\n g: number\n h: number\n}\n\nexport class CapacityPathingSolver extends BaseSolver {\n connectionsWithNodes: Array<{\n connection: SimpleRouteConnection\n nodes: CapacityMeshNode[]\n path?: CapacityMeshNode[]\n }>\n\n usedNodeCapacityMap: Map<CapacityMeshNodeId, number>\n\n simpleRouteJson: SimpleRouteJson\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n GREEDY_MULTIPLIER = 1.1\n\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n nodeEdgeMap: Map<CapacityMeshNodeId, CapacityMeshEdge[]>\n connectionNameToGoalNodeIds: Map<string, CapacityMeshNodeId[]>\n colorMap: Record<string, string>\n maxDepthOfNodes: number\n\n activeCandidateStraightLineDistance?: number\n\n debug_lastNodeCostMap: Map<\n CapacityMeshNodeId,\n {\n g: number\n h: number\n f: number\n }\n >\n\n hyperParameters: Partial<CapacityHyperParameters>\n\n constructor({\n simpleRouteJson,\n nodes,\n edges,\n colorMap,\n MAX_ITERATIONS = 1e6,\n hyperParameters = {},\n }: {\n simpleRouteJson: SimpleRouteJson\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n colorMap?: Record<string, string>\n MAX_ITERATIONS?: number\n hyperParameters?: Partial<CapacityHyperParameters>\n }) {\n super()\n this.MAX_ITERATIONS = MAX_ITERATIONS\n this.simpleRouteJson = simpleRouteJson\n this.nodes = nodes\n this.edges = edges\n this.colorMap = colorMap ?? {}\n const { connectionsWithNodes, connectionNameToGoalNodeIds } =\n this.getConnectionsWithNodes()\n this.connectionsWithNodes = connectionsWithNodes\n this.connectionNameToGoalNodeIds = connectionNameToGoalNodeIds\n this.hyperParameters = hyperParameters\n this.usedNodeCapacityMap = new Map(\n this.nodes.map((node) => [node.capacityMeshNodeId, 0]),\n )\n this.nodeMap = new Map(\n this.nodes.map((node) => [node.capacityMeshNodeId, node]),\n )\n this.nodeEdgeMap = getNodeEdgeMap(this.edges)\n this.maxDepthOfNodes = Math.max(\n ...this.nodes.map((node) => node._depth ?? 0),\n )\n this.debug_lastNodeCostMap = new Map()\n }\n\n getTotalCapacity(node: CapacityMeshNode): number {\n const depth = node._depth ?? 0\n return (this.maxDepthOfNodes - depth + 1) ** 2\n }\n\n getConnectionsWithNodes() {\n const connectionsWithNodes: Array<{\n connection: SimpleRouteConnection\n nodes: CapacityMeshNode[]\n pathFound: boolean\n }> = []\n const nodesWithTargets = this.nodes.filter((node) => node._containsTarget)\n const connectionNameToGoalNodeIds = new Map<string, CapacityMeshNodeId[]>()\n\n for (const connection of this.simpleRouteJson.connections) {\n const nodesForConnection: CapacityMeshNode[] = []\n for (const point of connection.pointsToConnect) {\n let closestNode = this.nodes[0]\n let minDistance = Number.MAX_VALUE\n\n for (const node of nodesWithTargets) {\n const distance = Math.sqrt(\n (node.center.x - point.x) ** 2 + (node.center.y - point.y) ** 2,\n )\n if (distance < minDistance) {\n minDistance = distance\n closestNode = node\n }\n }\n nodesForConnection.push(closestNode)\n }\n if (nodesForConnection.length < 2) {\n throw new Error(\n `Not enough nodes for connection \"${connection.name}\", only ${nodesForConnection.length} found`,\n )\n }\n connectionNameToGoalNodeIds.set(\n connection.name,\n nodesForConnection.map((n) => n.capacityMeshNodeId),\n )\n connectionsWithNodes.push({\n connection,\n nodes: nodesForConnection,\n pathFound: false,\n })\n }\n return { connectionsWithNodes, connectionNameToGoalNodeIds }\n }\n\n currentConnectionIndex = 0\n\n candidates?: Array<Candidate> | null\n visitedNodes?: Set<CapacityMeshNodeId> | null\n\n computeG(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return (\n prevCandidate.g + this.getDistanceBetweenNodes(prevCandidate.node, node)\n )\n }\n\n computeH(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return this.getDistanceBetweenNodes(node, endGoal)\n }\n\n getBacktrackedPath(candidate: Candidate) {\n const path: CapacityMeshNode[] = []\n let currentCandidate = candidate\n while (currentCandidate) {\n path.push(currentCandidate.node)\n currentCandidate = currentCandidate.prevCandidate!\n }\n return path\n }\n\n getNeighboringNodes(node: CapacityMeshNode) {\n return this.nodeEdgeMap\n .get(node.capacityMeshNodeId)!\n .flatMap((edge): CapacityMeshNodeId[] =>\n edge.nodeIds.filter((n) => n !== node.capacityMeshNodeId),\n )\n .map((n) => this.nodeMap.get(n)!)\n }\n\n getCapacityPaths() {\n const capacityPaths: CapacityPath[] = []\n for (const connection of this.connectionsWithNodes) {\n const path = connection.path\n if (path) {\n capacityPaths.push({\n capacityPathId: connection.connection.name,\n connectionName: connection.connection.name,\n nodeIds: path.map((node) => node.capacityMeshNodeId),\n })\n }\n }\n return capacityPaths\n }\n\n doesNodeHaveCapacityForTrace(node: CapacityMeshNode) {\n const usedCapacity =\n this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0\n const totalCapacity = this.getTotalCapacity(node)\n\n // Single layer nodes can't safely have multiple traces because there's no\n // way to cross over two traces without a via\n if (\n node.availableZ.length === 1 &&\n !node._containsTarget &&\n usedCapacity > 0\n )\n return false\n return usedCapacity < totalCapacity\n }\n\n canTravelThroughObstacle(node: CapacityMeshNode, connectionName: string) {\n const goalNodeIds = this.connectionNameToGoalNodeIds.get(connectionName)\n\n return goalNodeIds?.includes(node.capacityMeshNodeId) ?? false\n }\n\n getDistanceBetweenNodes(A: CapacityMeshNode, B: CapacityMeshNode) {\n return Math.sqrt(\n (A.center.x - B.center.x) ** 2 + (A.center.y - B.center.y) ** 2,\n )\n }\n\n reduceCapacityAlongPath(nextConnection: {\n path?: CapacityMeshNode[]\n }) {\n for (const node of nextConnection.path ?? []) {\n this.usedNodeCapacityMap.set(\n node.capacityMeshNodeId,\n this.usedNodeCapacityMap.get(node.capacityMeshNodeId)! + 1,\n )\n }\n }\n\n isConnectedToEndGoal(node: CapacityMeshNode, endGoal: CapacityMeshNode) {\n return this.nodeEdgeMap\n .get(node.capacityMeshNodeId)!\n .some((edge) => edge.nodeIds.includes(endGoal.capacityMeshNodeId))\n }\n\n _step() {\n const nextConnection =\n this.connectionsWithNodes[this.currentConnectionIndex]\n if (!nextConnection) {\n this.solved = true\n return\n }\n const [start, end] = nextConnection.nodes\n if (!this.candidates) {\n this.candidates = [{ prevCandidate: null, node: start, f: 0, g: 0, h: 0 }]\n this.debug_lastNodeCostMap = new Map()\n this.visitedNodes = new Set([start.capacityMeshNodeId])\n this.activeCandidateStraightLineDistance = distance(\n start.center,\n end.center,\n )\n }\n\n this.candidates.sort((a, b) => a.f - b.f)\n const currentCandidate = this.candidates.shift()\n if (!currentCandidate) {\n // TODO Track failed paths, make sure solver doesn't think it solved\n console.error(\n `Ran out of candidates on connection ${nextConnection.connection.name}`,\n )\n this.currentConnectionIndex++\n this.candidates = null\n this.visitedNodes = null\n return\n }\n if (this.isConnectedToEndGoal(currentCandidate.node, end)) {\n nextConnection.path = this.getBacktrackedPath({\n prevCandidate: currentCandidate,\n node: end,\n f: 0,\n g: 0,\n h: 0,\n })\n\n this.reduceCapacityAlongPath(nextConnection)\n\n this.currentConnectionIndex++\n this.candidates = null\n this.visitedNodes = null\n return\n }\n\n const neighborNodes = this.getNeighboringNodes(currentCandidate.node)\n for (const neighborNode of neighborNodes) {\n if (this.visitedNodes?.has(neighborNode.capacityMeshNodeId)) {\n continue\n }\n if (!this.doesNodeHaveCapacityForTrace(neighborNode)) {\n continue\n }\n const connectionName =\n this.connectionsWithNodes[this.currentConnectionIndex].connection.name\n if (\n neighborNode._containsObstacle &&\n !this.canTravelThroughObstacle(neighborNode, connectionName)\n ) {\n continue\n }\n const g = this.computeG(currentCandidate, neighborNode, end)\n const h = this.computeH(currentCandidate, neighborNode, end)\n const f = g + h * this.GREEDY_MULTIPLIER\n\n this.debug_lastNodeCostMap.set(neighborNode.capacityMeshNodeId, {\n f,\n g,\n h,\n })\n\n const newCandidate = {\n prevCandidate: currentCandidate,\n node: neighborNode,\n f,\n g,\n h,\n }\n this.candidates.push(newCandidate)\n }\n this.visitedNodes!.add(currentCandidate.node.capacityMeshNodeId)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n\n // Visualize each solved connection path (draw a line through each node's center)\n if (this.connectionsWithNodes) {\n for (let i = 0; i < this.connectionsWithNodes.length; i++) {\n const conn = this.connectionsWithNodes[i]\n if (conn.path && conn.path.length > 0) {\n const pathPoints = conn.path.map(({ center: { x, y }, width }) => ({\n // slight offset to allow viewing overlapping paths\n x: x + ((i % 10) + (i % 19)) * (0.01 * width),\n y: y + ((i % 10) + (i % 19)) * (0.01 * width),\n }))\n graphics.lines!.push({\n points: pathPoints,\n strokeColor: this.colorMap[conn.connection.name],\n })\n }\n }\n }\n\n for (const node of this.nodes) {\n const nodeCosts = this.debug_lastNodeCostMap.get(node.capacityMeshNodeId)\n graphics.rects!.push({\n ...createRectFromCapacityNode(node),\n label: [\n `${node.capacityMeshNodeId}`,\n `${this.usedNodeCapacityMap.get(node.capacityMeshNodeId)}/${this.getTotalCapacity(node).toFixed(2)}`,\n `${node.width.toFixed(2)}x${node.height.toFixed(2)}`,\n `g: ${nodeCosts?.g !== undefined ? nodeCosts.g.toFixed(2) : \"?\"}`,\n `h: ${nodeCosts?.h !== undefined ? nodeCosts.h.toFixed(2) : \"?\"}`,\n `f: ${nodeCosts?.f !== undefined ? nodeCosts.f.toFixed(2) : \"?\"}`,\n ].join(\"\\n\"),\n })\n }\n\n // Visualize connection points from each connection as circles\n if (this.connectionsWithNodes) {\n for (const conn of this.connectionsWithNodes) {\n if (conn.connection?.pointsToConnect) {\n for (const point of conn.connection.pointsToConnect) {\n graphics.points!.push({\n x: point.x,\n y: point.y,\n })\n }\n }\n }\n }\n\n // Draw a dashed line from the start node to the end node\n const nextConnection =\n this.connectionsWithNodes[this.currentConnectionIndex]\n if (nextConnection) {\n const [start, end] = nextConnection.connection.pointsToConnect\n graphics.lines!.push({\n points: [\n { x: start.x, y: start.y },\n { x: end.x, y: end.y },\n ],\n strokeColor: \"red\",\n strokeDash: \"10 5\",\n })\n }\n\n // Visualize backtracked path of highest ranked candidate\n if (this.candidates) {\n // Get top 10 candidates\n const topCandidates = this.candidates.slice(0, 5)\n const connectionName =\n this.connectionsWithNodes[this.currentConnectionIndex].connection.name\n\n // Add paths for each candidate with decreasing opacity\n topCandidates.forEach((candidate, index) => {\n const opacity = 0.5 * (1 - index / 5) // Opacity decreases from 0.5 to 0.05\n const backtrackedPath = this.getBacktrackedPath(candidate)\n graphics.lines!.push({\n points: backtrackedPath.map(({ center: { x, y } }) => ({ x, y })),\n strokeColor: safeTransparentize(\n this.colorMap[connectionName] ?? \"red\",\n 1 - opacity,\n ),\n })\n })\n }\n\n return graphics\n }\n}\n","import type { CapacityMeshNode } from \"lib/types\"\nimport { CapacityPathingSolver, type Candidate } from \"./CapacityPathingSolver\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\n\nexport class CapacityPathingSolver5 extends CapacityPathingSolver {\n NEGATIVE_CAPACITY_PENALTY_FACTOR = 1\n REDUCED_CAPACITY_PENALTY_FACTOR = 1\n\n constructor(...args: ConstructorParameters<typeof CapacityPathingSolver>) {\n super(...args)\n this.GREEDY_MULTIPLIER = 2.5\n }\n\n get maxCapacityFactor() {\n return this.hyperParameters.MAX_CAPACITY_FACTOR ?? 1\n }\n\n getTotalCapacity(node: CapacityMeshNode): number {\n return getTunedTotalCapacity1(node, this.maxCapacityFactor)\n }\n\n /**\n * Penalty you pay for using this node\n */\n getNodeCapacityPenalty(node: CapacityMeshNode): number {\n return 0.05\n if (node.availableZ.length === 1) {\n return 0\n }\n\n const totalCapacity = this.getTotalCapacity(node)\n const usedCapacity =\n this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0\n const remainingCapacity = totalCapacity - usedCapacity\n\n const dist = this.activeCandidateStraightLineDistance!\n\n if (remainingCapacity <= 0) {\n // | Total Cap | Remaining Cap | Remaining Cap Ratio | PenaltySLD |\n // | 1 | 0 | (-( 0) + 1) / 1 | 1^2 = 1 |\n // | 1 | -1 | (-(-1) + 1) / 1 | 2^2 = 4 |\n // | 1 | -2 | (-(-2) + 1) / 1 | 3^2 = 9 |\n // | 2 | 0 | (-( 0) + 1) / 2 | 0.5^2 = 0.25 |\n // | 2 | -1 | (-(-1) + 1) / 2 | 1^2 = 1 |\n // | 2 | -2 | (-(-2) + 1) / 2 | 2^2 = 4 |\n // | 2 | -3 | (-(-3) + 1) / 2 | 3^2 = 9 |\n // | 3 | 0 | (-( 0) + 1) / 3 | 0.333^2= 0.111|\n // | 3 | -1 | (-(-1) + 1) / 3 | 0.666^2= 0.444|\n // | 3 | -2 | (-(-2) + 1) / 3 | 1^2 = 1 |\n // | 3 | -3 | (-(-3) + 1) / 3 | 2^2 = 4 |\n const penalty =\n ((-remainingCapacity + 1) / totalCapacity) *\n dist *\n (this.NEGATIVE_CAPACITY_PENALTY_FACTOR / 4)\n\n return penalty ** 2\n }\n\n // This node still has capacity, but penalize as we reduce the capacity\n return (\n ((1 / remainingCapacity) * dist * this.REDUCED_CAPACITY_PENALTY_FACTOR) /\n 8\n )\n }\n\n /**\n * We're rewarding travel into big nodes.\n *\n * To minimize shortest path, you'd want to comment this out.\n */\n getDistanceBetweenNodes(A: CapacityMeshNode, B: CapacityMeshNode) {\n const dx = A.center.x - B.center.x\n const dy = A.center.y - B.center.y\n\n return Math.sqrt(dx ** 2 + dy ** 2)\n\n // REWARD BIG NODE TRAVEL\n // const szx = Math.max(A.width, B.width)\n // const szy = Math.max(A.height, B.height)\n\n // const dist = Math.sqrt(dx ** 2 + dy ** 2) / (szx * szy)\n\n // return dist\n }\n\n computeG(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return (\n prevCandidate.g +\n this.getDistanceBetweenNodes(prevCandidate.node, node) +\n this.getNodeCapacityPenalty(node)\n )\n }\n\n computeH(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return this.getDistanceBetweenNodes(node, endGoal)\n }\n}\n","import { CapacityMeshNode } from \"lib/types/capacity-mesh-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\n\nexport class StrawSolver extends BaseSolver {\n multiLayerNodes: CapacityMeshNode[]\n\n strawNodes: CapacityMeshNode[]\n skippedNodes: CapacityMeshNode[]\n\n unprocessedNodes: CapacityMeshNode[]\n strawSize: number\n\n nodeIdCounter: number\n\n constructor(params: {\n nodes: CapacityMeshNode[]\n strawSize?: number\n }) {\n super()\n this.strawSize = params.strawSize ?? 0.5\n this.multiLayerNodes = []\n this.strawNodes = []\n this.skippedNodes = []\n this.nodeIdCounter = 0\n this.unprocessedNodes = []\n for (const node of params.nodes) {\n if (node.availableZ.length === 1) {\n this.unprocessedNodes.push(node)\n } else {\n this.multiLayerNodes.push(node)\n }\n }\n }\n\n getCapacityOfMultiLayerNodesWithinBounds(bounds: {\n minX: number\n maxX: number\n minY: number\n maxY: number\n }): number {\n let totalCapacity = 0\n\n for (const node of this.multiLayerNodes) {\n // Calculate node bounds\n const nodeMinX = node.center.x - node.width / 2\n const nodeMaxX = node.center.x + node.width / 2\n const nodeMinY = node.center.y - node.height / 2\n const nodeMaxY = node.center.y + node.height / 2\n\n // Calculate overlap area\n const overlapMinX = Math.max(bounds.minX, nodeMinX)\n const overlapMaxX = Math.min(bounds.maxX, nodeMaxX)\n const overlapMinY = Math.max(bounds.minY, nodeMinY)\n const overlapMaxY = Math.min(bounds.maxY, nodeMaxY)\n\n // If there's an overlap\n if (overlapMinX < overlapMaxX && overlapMinY < overlapMaxY) {\n const overlapWidth = overlapMaxX - overlapMinX\n const overlapHeight = overlapMaxY - overlapMinY\n const overlapArea = overlapWidth * overlapHeight\n const nodeArea = node.width * node.height\n\n // Calculate proportion of node that overlaps\n const proportion = overlapArea / nodeArea\n\n // Add proportional capacity to total\n totalCapacity += getTunedTotalCapacity1(node) * proportion\n }\n }\n\n return totalCapacity\n }\n\n getSurroundingCapacities(node: CapacityMeshNode): {\n leftSurroundingCapacity: number\n rightSurroundingCapacity: number\n topSurroundingCapacity: number\n bottomSurroundingCapacity: number\n } {\n const searchDistance = Math.min(node.width, node.height)\n\n const leftSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x - node.width / 2 - searchDistance,\n maxX: node.center.x - node.width / 2,\n minY: node.center.y - node.height / 2,\n maxY: node.center.y + node.height / 2,\n })\n\n const rightSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x + node.width / 2,\n maxX: node.center.x + node.width / 2 + searchDistance,\n minY: node.center.y - node.height / 2,\n maxY: node.center.y + node.height / 2,\n })\n\n const topSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x - node.width / 2,\n maxX: node.center.x + node.width / 2,\n minY: node.center.y - node.height / 2 - searchDistance,\n maxY: node.center.y - node.height / 2,\n })\n\n const bottomSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x - node.width / 2,\n maxX: node.center.x + node.width / 2,\n minY: node.center.y + node.height / 2,\n maxY: node.center.y + node.height / 2 + searchDistance,\n })\n\n return {\n leftSurroundingCapacity,\n rightSurroundingCapacity,\n topSurroundingCapacity,\n bottomSurroundingCapacity,\n }\n }\n /**\n * Creates straw nodes from a single-layer node based on surrounding capacities\n */\n createStrawsForNode(node: CapacityMeshNode): CapacityMeshNode[] {\n const result: CapacityMeshNode[] = []\n const {\n leftSurroundingCapacity,\n rightSurroundingCapacity,\n topSurroundingCapacity,\n bottomSurroundingCapacity,\n } = this.getSurroundingCapacities(node)\n\n // Decide whether to create horizontal or vertical straws\n const horizontalCapacity =\n leftSurroundingCapacity + rightSurroundingCapacity\n const verticalCapacity = topSurroundingCapacity + bottomSurroundingCapacity\n\n // Layer-specific preferred direction\n // Layer 0 (top) prefers horizontal traces, Layer 1 (bottom) prefers vertical\n const layerPrefersFactor = 1 // node.availableZ[0] === 0 ? 1.3 : 0.7\n\n const effectiveHorizontalCapacity = horizontalCapacity * layerPrefersFactor\n\n // Create straws based on dimensions and surrounding capacity\n if (effectiveHorizontalCapacity > verticalCapacity) {\n // Create horizontal straws\n const numStraws = Math.floor(node.height / this.strawSize)\n const strawHeight = node.height / numStraws\n\n for (let i = 0; i < numStraws; i++) {\n const strawCenterY =\n node.center.y - node.height / 2 + i * strawHeight + strawHeight / 2\n\n result.push({\n capacityMeshNodeId: `${node.capacityMeshNodeId}_straw${i}`,\n center: { x: node.center.x, y: strawCenterY },\n width: node.width,\n height: strawHeight,\n layer: node.layer,\n availableZ: [...node.availableZ],\n _depth: node._depth,\n _strawNode: true,\n })\n }\n } else {\n // Create vertical straws\n const numStraws = Math.floor(node.width / this.strawSize)\n const strawWidth = node.width / numStraws\n\n for (let i = 0; i < numStraws; i++) {\n const strawCenterX =\n node.center.x - node.width / 2 + i * strawWidth + strawWidth / 2\n\n result.push({\n capacityMeshNodeId: `${node.capacityMeshNodeId}_straw${i}`,\n center: { x: strawCenterX, y: node.center.y },\n width: strawWidth,\n height: node.height,\n layer: node.layer,\n availableZ: [...node.availableZ],\n _depth: node._depth,\n _strawNode: true,\n })\n }\n }\n\n return result\n }\n\n getResultNodes(): CapacityMeshNode[] {\n return [...this.multiLayerNodes, ...this.strawNodes, ...this.skippedNodes]\n }\n\n _step() {\n const rootNode = this.unprocessedNodes.pop()\n\n if (!rootNode) {\n this.solved = true\n return\n }\n\n // Skip nodes that are too small to subdivide\n if (\n rootNode.width < this.strawSize * 5 &&\n rootNode.height < this.strawSize * 5\n ) {\n this.skippedNodes.push(rootNode)\n return\n }\n\n // Skip target nodes (keep them intact)\n if (rootNode._containsTarget) {\n this.skippedNodes.push(rootNode)\n return\n }\n\n // Create straws for this node\n const strawNodes = this.createStrawsForNode(rootNode)\n this.strawNodes.push(...strawNodes)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n rects: [],\n lines: [],\n points: [],\n circles: [],\n title: \"Straw Solver\",\n }\n\n // Draw unprocessed nodes\n for (const node of this.unprocessedNodes) {\n graphics.rects!.push({\n center: node.center,\n width: node.width,\n height: node.height,\n fill: \"rgba(200, 200, 200, 0.5)\",\n stroke: \"rgba(0, 0, 0, 0.5)\",\n label: `${node.capacityMeshNodeId}\\nUnprocessed\\n${node.width}x${node.height}`,\n })\n }\n\n // Draw straw nodes with different colors based on layer\n for (const node of this.strawNodes) {\n const color =\n node.availableZ[0] === 0\n ? \"rgba(0, 150, 255, 0.5)\"\n : \"rgba(255, 100, 0, 0.5)\"\n\n graphics.rects!.push({\n center: node.center,\n width: node.width,\n height: node.height,\n fill: color,\n stroke: \"rgba(0, 0, 0, 0.5)\",\n label: `${node.capacityMeshNodeId}\\nLayer: ${node.availableZ[0]}\\n${node.width}x${node.height}`,\n })\n }\n\n // Draw multi-layer nodes\n for (const node of this.multiLayerNodes) {\n graphics.rects!.push({\n center: node.center,\n width: node.width * 0.9,\n height: node.height * 0.9,\n fill: \"rgba(100, 255, 100, 0.5)\",\n stroke: \"rgba(0, 0, 0, 0.5)\",\n layer: `z${node.availableZ.join(\",\")}`,\n label: `${node.capacityMeshNodeId}\\nLayers: ${node.availableZ.join(\",\")}\\n${node.width}x${node.height}`,\n })\n }\n\n return graphics\n }\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { areNodesBordering } from \"lib/utils/areNodesBordering\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { createRectFromCapacityNode } from \"lib/utils/createRectFromCapacityNode\"\n\nconst EPSILON = 0.005\n\n/**\n * Merges same layer nodes into larger nodes. Pre-processing stage necessary\n * for \"strawing\".\n */\nexport class SingleLayerNodeMergerSolver extends BaseSolver {\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n currentBatchNodeIds: CapacityMeshNodeId[]\n\n absorbedNodeIds: Set<CapacityMeshNodeId>\n\n nextBatchNodeIds: CapacityMeshNodeId[]\n batchHadModifications: boolean\n\n newNodes: CapacityMeshNode[]\n constructor(nodes: CapacityMeshNode[]) {\n super()\n this.nodeMap = new Map()\n this.MAX_ITERATIONS = 100_000\n for (const node of nodes) {\n this.nodeMap.set(node.capacityMeshNodeId, node)\n }\n this.newNodes = []\n this.absorbedNodeIds = new Set()\n const nodeWithArea: Array<[string, number]> = []\n for (const node of nodes) {\n if (node.availableZ.length > 1) {\n this.newNodes.push(node)\n this.absorbedNodeIds.add(node.capacityMeshNodeId)\n } else {\n nodeWithArea.push([node.capacityMeshNodeId, node.width * node.height])\n }\n }\n nodeWithArea.sort((a, b) => a[1] - b[1])\n this.currentBatchNodeIds = nodeWithArea.map((n) => n[0])\n this.nextBatchNodeIds = []\n this.batchHadModifications = false\n }\n\n getAdjacentSameLayerUnprocessedNodes(rootNode: CapacityMeshNode) {\n const adjacentNodes: CapacityMeshNode[] = []\n for (const unprocessedNodeId of this.currentBatchNodeIds) {\n if (this.absorbedNodeIds.has(unprocessedNodeId)) continue\n const unprocessedNode = this.nodeMap.get(unprocessedNodeId)!\n if (unprocessedNode.availableZ[0] !== rootNode.availableZ[0]) continue\n if (\n unprocessedNode._containsTarget &&\n unprocessedNode._targetConnectionName !== rootNode._targetConnectionName\n )\n continue\n if (!areNodesBordering(rootNode, unprocessedNode)) continue\n adjacentNodes.push(unprocessedNode)\n }\n return adjacentNodes\n }\n\n _step() {\n let rootNodeId = this.currentBatchNodeIds.pop()\n while (rootNodeId && this.absorbedNodeIds.has(rootNodeId)) {\n rootNodeId = this.currentBatchNodeIds.pop()\n }\n\n if (!rootNodeId) {\n if (this.batchHadModifications) {\n this.currentBatchNodeIds = this.nextBatchNodeIds.sort((a, b) => {\n const A = this.nodeMap.get(a)!\n const B = this.nodeMap.get(b)!\n return A.width * A.height - B.width * B.height\n })\n this.nextBatchNodeIds = []\n this.batchHadModifications = false\n return\n }\n\n this.solved = true\n this.newNodes.push(\n ...this.nextBatchNodeIds.map((id) => this.nodeMap.get(id)!),\n )\n return\n }\n\n const rootNode = this.nodeMap.get(rootNodeId)!\n let rootNodeHasGrown = false\n\n const adjacentNodes = this.getAdjacentSameLayerUnprocessedNodes(rootNode)\n\n if (adjacentNodes.length === 0) {\n this.nextBatchNodeIds.push(rootNodeId)\n return\n }\n\n // Handle adjacent nodes to the LEFT\n const adjacentNodesToLeft = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.x < rootNode.center.x &&\n Math.abs(adjNode.center.y - rootNode.center.y) < rootNode.height / 2,\n )\n\n if (adjacentNodesToLeft.length > 0) {\n const { width: leftAdjNodeWidth, height: leftAdjNodeHeight } =\n adjacentNodesToLeft[0]\n const leftAdjNodesAreAllSameSize = adjacentNodesToLeft.every(\n (adjNode) =>\n adjNode.width === leftAdjNodeWidth &&\n adjNode.height === leftAdjNodeHeight,\n )\n\n const leftAdjNodesTakeUpEntireHeight =\n Math.abs(\n adjacentNodesToLeft.reduce((acc, adjNode) => {\n return acc + adjNode.height\n }, 0) - rootNode.height,\n ) < EPSILON\n\n if (leftAdjNodesTakeUpEntireHeight && leftAdjNodesAreAllSameSize) {\n rootNode.width += leftAdjNodeWidth\n rootNode.center.x = rootNode.center.x - leftAdjNodeWidth / 2\n\n for (const adjNode of adjacentNodesToLeft) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n // Handle adjacent nodes to the RIGHT\n const adjacentNodesToRight = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.x > rootNode.center.x &&\n Math.abs(adjNode.center.y - rootNode.center.y) < rootNode.height / 2,\n )\n\n if (adjacentNodesToRight.length > 0 && !rootNodeHasGrown) {\n const { width: rightAdjNodeWidth, height: rightAdjNodeHeight } =\n adjacentNodesToRight[0]\n const rightAdjNodesAreAllSameSize = adjacentNodesToRight.every(\n (adjNode) =>\n adjNode.width === rightAdjNodeWidth &&\n adjNode.height === rightAdjNodeHeight,\n )\n\n const rightAdjNodesTakeUpEntireHeight =\n Math.abs(\n adjacentNodesToRight.reduce((acc, adjNode) => {\n return acc + adjNode.height\n }, 0) - rootNode.height,\n ) < EPSILON\n\n if (rightAdjNodesTakeUpEntireHeight && rightAdjNodesAreAllSameSize) {\n rootNode.width += rightAdjNodeWidth\n rootNode.center.x = rootNode.center.x + rightAdjNodeWidth / 2\n\n for (const adjNode of adjacentNodesToRight) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n // Handle adjacent nodes to the TOP\n const adjacentNodesToTop = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.y > rootNode.center.y &&\n Math.abs(adjNode.center.x - rootNode.center.x) < rootNode.width / 2,\n )\n\n if (adjacentNodesToTop.length > 0 && !rootNodeHasGrown) {\n const { width: topAdjNodeWidth, height: topAdjNodeHeight } =\n adjacentNodesToTop[0]\n const topAdjNodesAreAllSameSize = adjacentNodesToTop.every(\n (adjNode) =>\n adjNode.width === topAdjNodeWidth &&\n adjNode.height === topAdjNodeHeight,\n )\n\n const topAdjNodesTakeUpEntireWidth =\n Math.abs(\n adjacentNodesToTop.reduce((acc, adjNode) => {\n return acc + adjNode.width\n }, 0) - rootNode.width,\n ) < EPSILON\n\n if (topAdjNodesTakeUpEntireWidth && topAdjNodesAreAllSameSize) {\n rootNode.height += topAdjNodeHeight\n rootNode.center.y = rootNode.center.y + topAdjNodeHeight / 2\n\n for (const adjNode of adjacentNodesToTop) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n // Handle adjacent nodes to the BOTTOM\n const adjacentNodesToBottom = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.y < rootNode.center.y &&\n Math.abs(adjNode.center.x - rootNode.center.x) < rootNode.width / 2,\n )\n\n if (adjacentNodesToBottom.length > 0 && !rootNodeHasGrown) {\n const { width: bottomAdjNodeWidth, height: bottomAdjNodeHeight } =\n adjacentNodesToBottom[0]\n const bottomAdjNodesAreAllSameSize = adjacentNodesToBottom.every(\n (adjNode) =>\n adjNode.width === bottomAdjNodeWidth &&\n adjNode.height === bottomAdjNodeHeight,\n )\n\n const bottomAdjNodesTakeUpEntireWidth =\n Math.abs(\n adjacentNodesToBottom.reduce((acc, adjNode) => {\n return acc + adjNode.width\n }, 0) - rootNode.width,\n ) < EPSILON\n\n if (bottomAdjNodesTakeUpEntireWidth && bottomAdjNodesAreAllSameSize) {\n rootNode.height += bottomAdjNodeHeight\n rootNode.center.y = rootNode.center.y - bottomAdjNodeHeight / 2\n\n for (const adjNode of adjacentNodesToBottom) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n if (rootNodeHasGrown) {\n this.batchHadModifications = true\n this.currentBatchNodeIds.push(rootNodeId)\n } else {\n this.nextBatchNodeIds.unshift(rootNodeId)\n // this.processedNodeIds.add(rootNodeId)\n // this.newNodes.push(rootNode)\n }\n }\n\n visualize(): GraphicsObject {\n const graphics = {\n circles: [],\n lines: [],\n points: [],\n rects: [],\n coordinateSystem: \"cartesian\",\n title: \"Same Layer Node Merger\",\n } as Required<GraphicsObject>\n\n for (const node of this.newNodes) {\n graphics.rects.push(createRectFromCapacityNode(node))\n }\n\n const nextNodeIdInBatch =\n this.currentBatchNodeIds[this.currentBatchNodeIds.length - 1]\n let adjacentNodes: CapacityMeshNode[] | undefined\n if (nextNodeIdInBatch) {\n adjacentNodes = this.getAdjacentSameLayerUnprocessedNodes(\n this.nodeMap.get(nextNodeIdInBatch)!,\n )\n }\n\n // Visualize unprocessed nodes with a different style\n for (const nodeId of this.currentBatchNodeIds) {\n const node = this.nodeMap.get(nodeId)\n if (this.absorbedNodeIds.has(nodeId)) continue\n if (node) {\n const rect = createRectFromCapacityNode(node, {\n rectMargin: 0.01,\n })\n if (nodeId === nextNodeIdInBatch) {\n rect.stroke = \"rgba(0, 255, 0, 0.8)\" // Green for next node in batch\n } else if (\n adjacentNodes?.some(\n (adjNode) => adjNode.capacityMeshNodeId === nodeId,\n )\n ) {\n rect.stroke = \"rgba(128, 0, 128, 0.8)\" // Purple for adjacent nodes\n } else {\n rect.stroke = \"rgba(255, 165, 0, 0.8)\" // Orange border for other nodes\n }\n rect.layer = `z${node.availableZ.join(\",\")}`\n rect.label = `${rect.label}\\n(unprocessed)`\n graphics.rects.push(rect)\n }\n }\n\n // Visualize next batch nodes with a different style\n for (const nodeId of this.nextBatchNodeIds) {\n const node = this.nodeMap.get(nodeId)\n if (this.absorbedNodeIds.has(nodeId)) continue\n if (node) {\n const rect = createRectFromCapacityNode(node, {\n rectMargin: 0.01,\n })\n rect.layer = `z${node.availableZ.join(\",\")}`\n rect.stroke = \"rgba(0, 217, 255, 0.8)\" // Green border\n rect.label = `${rect.label}\\nx: ${node.center.x}, y: ${node.center.y}\\n${node.width}x${node.height}\\n(next batch)`\n graphics.rects.push(rect)\n }\n }\n\n return graphics\n }\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport { combineVisualizations } from \"../utils/combineVisualizations\"\nimport type {\n CapacityMeshNode,\n SimpleRouteJson,\n SimplifiedPcbTrace,\n SimplifiedPcbTraces,\n TraceId,\n} from \"../types\"\nimport { BaseSolver } from \"./BaseSolver\"\nimport { CapacityMeshEdgeSolver } from \"./CapacityMeshSolver/CapacityMeshEdgeSolver\"\nimport { CapacityMeshNodeSolver } from \"./CapacityMeshSolver/CapacityMeshNodeSolver1\"\nimport { CapacityMeshNodeSolver2_NodeUnderObstacle } from \"./CapacityMeshSolver/CapacityMeshNodeSolver2_NodesUnderObstacles\"\nimport { CapacityPathingSolver } from \"./CapacityPathingSolver/CapacityPathingSolver\"\nimport { CapacityEdgeToPortSegmentSolver } from \"./CapacityMeshSolver/CapacityEdgeToPortSegmentSolver\"\nimport { getColorMap } from \"./colors\"\nimport { CapacitySegmentToPointSolver } from \"./CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport { HighDensitySolver } from \"./HighDensitySolver/HighDensitySolver\"\nimport type { NodePortSegment } from \"../types/capacity-edges-to-port-segments-types\"\nimport { CapacityPathingSolver2_AvoidLowCapacity } from \"./CapacityPathingSolver/CapacityPathingSolver2_AvoidLowCapacity\"\nimport { CapacityPathingSolver3_FlexibleNegativeCapacity_AvoidLowCapacity } from \"./CapacityPathingSolver/CapacityPathingSolver3_FlexibleNegativeCapacity_AvoidLowCapacity\"\nimport { CapacityPathingSolver4_FlexibleNegativeCapacity } from \"./CapacityPathingSolver/CapacityPathingSolver4_FlexibleNegativeCapacity_AvoidLowCapacity_FixedDistanceCost\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { getConnectivityMapFromSimpleRouteJson } from \"lib/utils/getConnectivityMapFromSimpleRouteJson\"\nimport { CapacityNodeTargetMerger } from \"./CapacityNodeTargetMerger/CapacityNodeTargetMerger\"\nimport { CapacitySegmentPointOptimizer } from \"./CapacitySegmentPointOptimizer/CapacitySegmentPointOptimizer\"\nimport { calculateOptimalCapacityDepth } from \"../utils/getTunedTotalCapacity1\"\nimport { NetToPointPairsSolver } from \"./NetToPointPairsSolver/NetToPointPairsSolver\"\nimport { convertHdRouteToSimplifiedRoute } from \"lib/utils/convertHdRouteToSimplifiedRoute\"\nimport { mergeRouteSegments } from \"lib/utils/mergeRouteSegments\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\nimport { MultipleHighDensityRouteStitchSolver } from \"./RouteStitchingSolver/MultipleHighDensityRouteStitchSolver\"\nimport { convertSrjToGraphicsObject } from \"tests/fixtures/convertSrjToGraphicsObject\"\nimport { UnravelMultiSectionSolver } from \"./UnravelSolver/UnravelMultiSectionSolver\"\nimport { CapacityPathingSolver5 } from \"./CapacityPathingSolver/CapacityPathingSolver5\"\nimport { CapacityMeshNodeSolver3_LargerSingleLayerNodes } from \"./CapacityMeshSolver/CapacityMeshNodeSolver3_LargerSingleLayerNodes\"\nimport { StrawSolver } from \"./StrawSolver/StrawSolver\"\nimport { SingleLayerNodeMergerSolver } from \"./SingleLayerNodeMerger/SingleLayerNodeMergerSolver\"\nimport { CapacityNodeTargetMerger2 } from \"./CapacityNodeTargetMerger/CapacityNodeTargetMerger2\"\n\ninterface CapacityMeshSolverOptions {\n capacityDepth?: number\n targetMinCapacity?: number\n}\n\ntype PipelineStep<T extends new (...args: any[]) => BaseSolver> = {\n solverName: string\n solverClass: T\n getConstructorParams: (\n instance: CapacityMeshSolver,\n ) => ConstructorParameters<T>\n onSolved?: (instance: CapacityMeshSolver) => void\n}\n\nfunction definePipelineStep<\n T extends new (\n ...args: any[]\n ) => BaseSolver,\n const P extends ConstructorParameters<T>,\n>(\n solverName: keyof CapacityMeshSolver,\n solverClass: T,\n getConstructorParams: (instance: CapacityMeshSolver) => P,\n opts: {\n onSolved?: (instance: CapacityMeshSolver) => void\n } = {},\n): PipelineStep<T> {\n return {\n solverName,\n solverClass,\n getConstructorParams,\n onSolved: opts.onSolved,\n }\n}\n\nexport class CapacityMeshSolver extends BaseSolver {\n netToPointPairsSolver?: NetToPointPairsSolver\n nodeSolver?: CapacityMeshNodeSolver\n nodeTargetMerger?: CapacityNodeTargetMerger\n edgeSolver?: CapacityMeshEdgeSolver\n pathingSolver?: CapacityPathingSolver\n edgeToPortSegmentSolver?: CapacityEdgeToPortSegmentSolver\n colorMap: Record<string, string>\n segmentToPointSolver?: CapacitySegmentToPointSolver\n unravelMultiSectionSolver?: UnravelMultiSectionSolver\n segmentToPointOptimizer?: CapacitySegmentPointOptimizer\n highDensityRouteSolver?: HighDensitySolver\n highDensityStitchSolver?: MultipleHighDensityRouteStitchSolver\n singleLayerNodeMerger?: SingleLayerNodeMergerSolver\n strawSolver?: StrawSolver\n\n startTimeOfPhase: Record<string, number>\n endTimeOfPhase: Record<string, number>\n timeSpentOnPhase: Record<string, number>\n\n activeSubSolver?: BaseSolver | null = null\n connMap: ConnectivityMap\n srjWithPointPairs?: SimpleRouteJson\n capacityNodes: CapacityMeshNode[] | null = null\n\n pipelineDef = [\n definePipelineStep(\n \"netToPointPairsSolver\",\n NetToPointPairsSolver,\n (cms) => [cms.srj, cms.colorMap],\n {\n onSolved: (cms) => {\n cms.srjWithPointPairs =\n cms.netToPointPairsSolver?.getNewSimpleRouteJson()\n cms.colorMap = getColorMap(cms.srjWithPointPairs!, this.connMap)\n cms.connMap = getConnectivityMapFromSimpleRouteJson(\n cms.srjWithPointPairs!,\n )\n },\n },\n ),\n // definePipelineStep(\"nodeSolver\", CapacityMeshNodeSolver, (cms) => [\n // cms.netToPointPairsSolver?.getNewSimpleRouteJson() || cms.srj,\n // cms.opts,\n // ]),\n definePipelineStep(\n \"nodeSolver\",\n CapacityMeshNodeSolver2_NodeUnderObstacle,\n (cms) => [\n cms.netToPointPairsSolver?.getNewSimpleRouteJson() || cms.srj,\n cms.opts,\n ],\n ),\n // definePipelineStep(\"nodeTargetMerger\", CapacityNodeTargetMerger, (cms) => [\n // cms.nodeSolver?.finishedNodes || [],\n // cms.srj.obstacles,\n // cms.connMap,\n // ]),\n // definePipelineStep(\"nodeTargetMerger\", CapacityNodeTargetMerger2, (cms) => [\n // cms.nodeSolver?.finishedNodes || [],\n // cms.srj.obstacles,\n // cms.connMap,\n // cms.colorMap,\n // cms.srj.connections,\n // ]),\n definePipelineStep(\n \"singleLayerNodeMerger\",\n SingleLayerNodeMergerSolver,\n (cms) => [cms.nodeSolver?.finishedNodes!],\n ),\n definePipelineStep(\n \"strawSolver\",\n StrawSolver,\n (cms) => [{ nodes: cms.singleLayerNodeMerger?.newNodes! }],\n {\n onSolved: (cms) => {\n cms.capacityNodes = cms.strawSolver?.getResultNodes()!\n },\n },\n ),\n definePipelineStep(\"edgeSolver\", CapacityMeshEdgeSolver, (cms) => [\n cms.capacityNodes!,\n ]),\n definePipelineStep(\"pathingSolver\", CapacityPathingSolver5, (cms) => [\n {\n simpleRouteJson: cms.srjWithPointPairs!,\n nodes: cms.capacityNodes!,\n edges: cms.edgeSolver?.edges || [],\n colorMap: cms.colorMap,\n hyperParameters: {\n MAX_CAPACITY_FACTOR: 1,\n },\n },\n ]),\n definePipelineStep(\n \"edgeToPortSegmentSolver\",\n CapacityEdgeToPortSegmentSolver,\n (cms) => [\n {\n nodes: cms.capacityNodes!,\n edges: cms.edgeSolver?.edges || [],\n capacityPaths: cms.pathingSolver?.getCapacityPaths() || [],\n colorMap: cms.colorMap,\n },\n ],\n ),\n definePipelineStep(\n \"segmentToPointSolver\",\n CapacitySegmentToPointSolver,\n (cms) => {\n const allSegments: NodePortSegment[] = []\n if (cms.edgeToPortSegmentSolver?.nodePortSegments) {\n cms.edgeToPortSegmentSolver.nodePortSegments.forEach((segs) => {\n allSegments.push(...segs)\n })\n }\n return [\n {\n segments: allSegments,\n colorMap: cms.colorMap,\n nodes: cms.capacityNodes!,\n },\n ]\n },\n ),\n // definePipelineStep(\n // \"segmentToPointOptimizer\",\n // CapacitySegmentPointOptimizer,\n // (cms) => [\n // {\n // assignedSegments: cms.segmentToPointSolver?.solvedSegments || [],\n // colorMap: cms.colorMap,\n // nodes: cms.nodeTargetMerger?.newNodes || [],\n // },\n // ],\n // ),\n definePipelineStep(\n \"unravelMultiSectionSolver\",\n UnravelMultiSectionSolver,\n (cms) => [\n {\n assignedSegments: cms.segmentToPointSolver?.solvedSegments || [],\n colorMap: cms.colorMap,\n nodes: cms.capacityNodes!,\n },\n ],\n ),\n definePipelineStep(\"highDensityRouteSolver\", HighDensitySolver, (cms) => [\n {\n nodePortPoints:\n cms.unravelMultiSectionSolver?.getNodesWithPortPoints() ??\n cms.segmentToPointOptimizer?.getNodesWithPortPoints() ??\n [],\n colorMap: cms.colorMap,\n connMap: cms.connMap,\n },\n ]),\n definePipelineStep(\n \"highDensityStitchSolver\",\n MultipleHighDensityRouteStitchSolver,\n (cms) => [\n {\n connections: cms.srjWithPointPairs!.connections,\n hdRoutes: cms.highDensityRouteSolver!.routes,\n layerCount: cms.srj.layerCount,\n },\n ],\n ),\n ]\n\n constructor(\n public srj: SimpleRouteJson,\n public opts: CapacityMeshSolverOptions = {},\n ) {\n super()\n this.MAX_ITERATIONS = 1e6\n\n // If capacityDepth is not provided, calculate it automatically\n if (opts.capacityDepth === undefined) {\n // Calculate max width/height from bounds for initial node size\n const boundsWidth = srj.bounds.maxX - srj.bounds.minX\n const boundsHeight = srj.bounds.maxY - srj.bounds.minY\n const maxWidthHeight = Math.max(boundsWidth, boundsHeight)\n\n // Use the calculateOptimalCapacityDepth function to determine the right depth\n const targetMinCapacity = opts.targetMinCapacity ?? 0.5\n opts.capacityDepth = calculateOptimalCapacityDepth(\n maxWidthHeight,\n targetMinCapacity,\n )\n }\n\n this.connMap = getConnectivityMapFromSimpleRouteJson(srj)\n this.colorMap = getColorMap(srj, this.connMap)\n this.startTimeOfPhase = {}\n this.endTimeOfPhase = {}\n this.timeSpentOnPhase = {}\n }\n\n currentPipelineStepIndex = 0\n _step() {\n const pipelineStepDef = this.pipelineDef[this.currentPipelineStepIndex]\n if (!pipelineStepDef) {\n this.solved = true\n return\n }\n\n if (this.activeSubSolver) {\n this.activeSubSolver.step()\n if (this.activeSubSolver.solved) {\n this.endTimeOfPhase[pipelineStepDef.solverName] = performance.now()\n this.timeSpentOnPhase[pipelineStepDef.solverName] =\n this.endTimeOfPhase[pipelineStepDef.solverName] -\n this.startTimeOfPhase[pipelineStepDef.solverName]\n pipelineStepDef.onSolved?.(this)\n this.activeSubSolver = null\n this.currentPipelineStepIndex++\n } else if (this.activeSubSolver.failed) {\n this.error = this.activeSubSolver?.error\n this.failed = true\n this.activeSubSolver = null\n }\n return\n }\n\n const constructorParams = pipelineStepDef.getConstructorParams(this)\n // @ts-ignore\n this.activeSubSolver = new pipelineStepDef.solverClass(...constructorParams)\n ;(this as any)[pipelineStepDef.solverName] = this.activeSubSolver\n this.timeSpentOnPhase[pipelineStepDef.solverName] = 0\n this.startTimeOfPhase[pipelineStepDef.solverName] = performance.now()\n }\n\n getCurrentPhase(): string {\n return this.pipelineDef[this.currentPipelineStepIndex]?.solverName ?? \"none\"\n }\n\n visualize(): GraphicsObject {\n if (!this.solved && this.activeSubSolver)\n return this.activeSubSolver.visualize()\n const netToPPSolver = this.netToPointPairsSolver?.visualize()\n const nodeViz = this.nodeSolver?.visualize()\n const nodeTargetMergerViz = this.nodeTargetMerger?.visualize()\n const singleLayerNodeMergerViz = this.singleLayerNodeMerger?.visualize()\n const strawSolverViz = this.strawSolver?.visualize()\n const edgeViz = this.edgeSolver?.visualize()\n const pathingViz = this.pathingSolver?.visualize()\n const edgeToPortSegmentViz = this.edgeToPortSegmentSolver?.visualize()\n const segmentToPointViz = this.segmentToPointSolver?.visualize()\n const segmentOptimizationViz =\n this.unravelMultiSectionSolver?.visualize() ??\n this.segmentToPointOptimizer?.visualize()\n const highDensityViz = this.highDensityRouteSolver?.visualize()\n const highDensityStitchViz = this.highDensityStitchSolver?.visualize()\n const problemViz = {\n points: [...this.srj.connections.flatMap((c) => c.pointsToConnect)],\n rects: [\n ...(this.srj.obstacles ?? []).map((o) => ({\n ...o,\n fill: o.layers?.includes(\"top\")\n ? \"rgba(255,0,0,0.25)\"\n : o.layers?.includes(\"bottom\")\n ? \"rgba(0,0,255,0.25)\"\n : \"rgba(255,0,0,0.25)\",\n })),\n ],\n lines: [\n {\n points: [\n // Add five points representing the bounds of the PCB\n {\n x: this.srj.bounds?.minX ?? -50,\n y: this.srj.bounds?.minY ?? -50,\n },\n { x: this.srj.bounds?.maxX ?? 50, y: this.srj.bounds?.minY ?? -50 },\n { x: this.srj.bounds?.maxX ?? 50, y: this.srj.bounds?.maxY ?? 50 },\n { x: this.srj.bounds?.minX ?? -50, y: this.srj.bounds?.maxY ?? 50 },\n {\n x: this.srj.bounds?.minX ?? -50,\n y: this.srj.bounds?.minY ?? -50,\n }, // Close the rectangle\n ],\n strokeColor: \"rgba(255,0,0,0.25)\",\n },\n ],\n } as GraphicsObject\n const visualizations = [\n problemViz,\n netToPPSolver,\n nodeViz,\n nodeTargetMergerViz,\n singleLayerNodeMergerViz,\n strawSolverViz,\n edgeViz,\n pathingViz,\n edgeToPortSegmentViz,\n segmentToPointViz,\n segmentOptimizationViz,\n highDensityViz ? combineVisualizations(problemViz, highDensityViz) : null,\n highDensityStitchViz,\n this.solved\n ? combineVisualizations(\n problemViz,\n convertSrjToGraphicsObject(this.getOutputSimpleRouteJson()),\n )\n : null,\n ].filter(Boolean) as GraphicsObject[]\n // return visualizations[visualizations.length - 1]\n return combineVisualizations(...visualizations)\n }\n\n /**\n * Get original connection name from connection name with MST suffix\n * @param mstConnectionName The MST-suffixed connection name (e.g. \"connection1_mst0\")\n * @returns The original connection name (e.g. \"connection1\")\n */\n private getOriginalConnectionName(mstConnectionName: string): string {\n // MST connections are named like \"connection_mst0\", so extract the original name\n const match = mstConnectionName.match(/^(.+?)_mst\\d+$/)\n return match ? match[1] : mstConnectionName\n }\n\n /**\n * Returns the SimpleRouteJson with routes converted to SimplifiedPcbTraces\n */\n getOutputSimplifiedPcbTraces(): SimplifiedPcbTraces {\n if (!this.solved || !this.highDensityRouteSolver) {\n throw new Error(\"Cannot get output before solving is complete\")\n }\n\n const traces: SimplifiedPcbTraces = []\n\n for (const connection of this.netToPointPairsSolver?.newConnections ?? []) {\n const netConnection = this.srj.connections.find(\n (c) => c.name === connection.netConnectionName,\n )\n\n // Find all the hdRoutes that correspond to this connection\n const hdRoutes = this.highDensityStitchSolver!.mergedHdRoutes.filter(\n (r) => r.connectionName === connection.name,\n )\n\n for (let i = 0; i < hdRoutes.length; i++) {\n const hdRoute = hdRoutes[i]\n const simplifiedPcbTrace: SimplifiedPcbTrace = {\n type: \"pcb_trace\",\n pcb_trace_id: `${connection.name}_${i}`,\n connection_name: this.getOriginalConnectionName(connection.name),\n route: convertHdRouteToSimplifiedRoute(hdRoute, this.srj.layerCount),\n }\n\n traces.push(simplifiedPcbTrace)\n }\n }\n\n return traces\n }\n\n getOutputSimpleRouteJson(): SimpleRouteJson {\n return {\n ...this.srj,\n traces: this.getOutputSimplifiedPcbTraces(),\n }\n }\n}\n"],"mappings":"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","names":["t","e","t","t","_isNativeReflectConstruct","_wrapNativeSuper","t","PolishedError","pxtoFactory","reduceHexValue","isRgb","isRgba","isHsl","isHsla","clamp","node","distance","layerName","nodeId","distance"]}
|
|
1
|
+
{"version":3,"sources":["../lib/utils/combineVisualizations.ts","../lib/solvers/BaseSolver.ts","../node_modules/@tscircuit/math-utils/src/line-intersections.ts","../lib/utils/areNodesBordering.ts","../lib/solvers/CapacityMeshSolver/CapacityMeshEdgeSolver.ts","../node_modules/@babel/runtime/helpers/esm/extends.js","../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/isNativeFunction.js","../node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js","../node_modules/@babel/runtime/helpers/esm/construct.js","../node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js","../node_modules/polished/dist/polished.esm.js","../lib/solvers/colors.ts","../lib/utils/isPointInRect.ts","../lib/utils/doRectsOverlap.ts","../lib/utils/mapLayerNameToZ.ts","../lib/solvers/CapacityMeshSolver/CapacityMeshNodeSolver1.ts","../lib/solvers/CapacityMeshSolver/CapacityMeshNodeSolver2_NodesUnderObstacles.ts","../lib/solvers/CapacityMeshSolver/getNodeEdgeMap.ts","../lib/solvers/CapacityMeshSolver/CapacityEdgeToPortSegmentSolver.ts","../lib/solvers/CapacityMeshSolver/CapacitySegmentToPointSolver.ts","../lib/solvers/HighDensitySolver/SingleHighDensityRouteSolver.ts","../lib/solvers/HighDensitySolver/SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost.ts","../lib/utils/cloneAndShuffleArray.ts","../lib/utils/getBoundsFromNodeWithPortPoints.ts","../lib/utils/getMinDistBetweenEnteringPoints.ts","../lib/solvers/HighDensitySolver/IntraNodeSolver.ts","../lib/solvers/HyperParameterSupervisorSolver.ts","../lib/solvers/HyperHighDensitySolver/HyperSingleIntraNodeSolver.ts","../lib/utils/mergeRouteSegments.ts","../lib/solvers/HighDensitySolver/HighDensitySolver.ts","../node_modules/circuit-json-to-connectivity-map/src/findConnectedNetworks.ts","../node_modules/circuit-json-to-connectivity-map/src/ConnectivityMap.ts","../node_modules/circuit-json-to-connectivity-map/src/getSourcePortConnectivityMapFromCircuitJson.ts","../node_modules/circuit-json-to-connectivity-map/src/getFullConnectivityMapFromCircuitJson.ts","../node_modules/circuit-json-to-connectivity-map/src/PcbConnectivityMap.ts","../lib/utils/getConnectivityMapFromSimpleRouteJson.ts","../lib/utils/getTunedTotalCapacity1.ts","../lib/solvers/NetToPointPairsSolver/buildMinimumSpanningTree.ts","../lib/solvers/NetToPointPairsSolver/NetToPointPairsSolver.ts","../lib/utils/mapZToLayerName.ts","../lib/utils/convertHdRouteToSimplifiedRoute.ts","../lib/solvers/RouteStitchingSolver/SingleHighDensityRouteStitchSolver.ts","../lib/solvers/RouteStitchingSolver/MultipleHighDensityRouteStitchSolver.ts","../tests/fixtures/convertSrjToGraphicsObject.ts","../lib/solvers/UnravelSolver/getNodesNearNode.ts","../lib/solvers/UnravelSolver/createPointModificationsHash.ts","../lib/solvers/UnravelSolver/hasZRangeOverlap.ts","../lib/solvers/UnravelSolver/getIssuesInSection.ts","../lib/solvers/UnravelSolver/getLogProbability.ts","../lib/solvers/UnravelSolver/applyOperationToPointModifications.ts","../lib/solvers/UnravelSolver/createSegmentPointMap.ts","../lib/solvers/UnravelSolver/UnravelSectionSolver.ts","../lib/solvers/UnravelSolver/getDedupedSegments.ts","../lib/utils/getIntraNodeCrossingsFromSegments.ts","../lib/solvers/UnravelSolver/calculateCrossingProbabilityOfFailure.ts","../lib/solvers/UnravelSolver/UnravelMultiSectionSolver.ts","../lib/utils/createRectFromCapacityNode.ts","../lib/solvers/CapacityPathingSolver/CapacityPathingSolver.ts","../lib/solvers/CapacityPathingSolver/CapacityPathingSolver5.ts","../lib/solvers/StrawSolver/StrawSolver.ts","../lib/solvers/SingleLayerNodeMerger/SingleLayerNodeMergerSolver.ts","../lib/solvers/AutoroutingPipelineSolver.ts"],"sourcesContent":["import type { GraphicsObject } from \"graphics-debug\"\n\nexport const combineVisualizations = (\n ...visualizations: GraphicsObject[]\n): GraphicsObject => {\n const combined: GraphicsObject = {\n points: [],\n lines: [],\n circles: [],\n rects: [],\n }\n\n visualizations.forEach((viz, i) => {\n if (viz.lines) {\n combined.lines = [\n ...(combined.lines || []),\n ...viz.lines.map((l) => ({ ...l, step: i })),\n ]\n }\n if (viz.points) {\n combined.points = [\n ...(combined.points || []),\n ...viz.points.map((p) => ({ ...p, step: i })),\n ]\n }\n if (viz.circles) {\n combined.circles = [\n ...(combined.circles || []),\n ...viz.circles.map((c) => ({ ...c, step: i })),\n ]\n }\n if (viz.rects) {\n combined.rects = [\n ...(combined.rects || []),\n ...viz.rects.map((r) => ({ ...r, step: i })),\n ]\n }\n })\n\n return combined\n}\n","import type { GraphicsObject } from \"graphics-debug\"\n\nexport class BaseSolver {\n MAX_ITERATIONS = 1000\n solved = false\n failed = false\n iterations = 0\n progress = 0\n error: string | null = null\n activeSubSolver?: BaseSolver | null\n failedSubSolvers?: BaseSolver[]\n timeToSolve?: number\n\n /** DO NOT OVERRIDE! Override _step() instead */\n step() {\n if (this.solved) return\n if (this.failed) return\n this.iterations++\n try {\n this._step()\n } catch (e) {\n this.error = `${this.constructor.name} error: ${e}`\n console.error(this.error)\n this.failed = true\n throw e\n }\n if (!this.solved && this.iterations > this.MAX_ITERATIONS) {\n this.error = `${this.constructor.name} did not converge`\n console.error(this.error)\n this.failed = true\n }\n }\n\n _step() {}\n\n solve() {\n const startTime = Date.now()\n while (!this.solved && !this.failed) {\n this.step()\n }\n const endTime = Date.now()\n this.timeToSolve = endTime - startTime\n }\n\n visualize(): GraphicsObject {\n return {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n }\n}\n","import type { Point } from \"./common\"\n\n/**\n * Returns true if the two lines intersect.\n */\nexport function doesLineIntersectLine(\n [a1, a2]: [Point, Point],\n [b1, b2]: [Point, Point],\n {\n lineThickness = 0,\n }: {\n lineThickness?: number\n } = {},\n): boolean {\n if (lineThickness === 0) {\n return doSegmentsIntersect(a1, a2, b1, b2)\n }\n const minDist = segmentsDistance(a1, a2, b1, b2)\n return minDist <= lineThickness\n}\n\n/**\n * Returns true if the two segments intersect.\n */\nexport function doSegmentsIntersect(\n p1: Point,\n q1: Point,\n p2: Point,\n q2: Point,\n): boolean {\n const o1 = orientation(p1, q1, p2)\n const o2 = orientation(p1, q1, q2)\n const o3 = orientation(p2, q2, p1)\n const o4 = orientation(p2, q2, q1)\n\n // General case\n if (o1 !== o2 && o3 !== o4) {\n return true\n }\n\n // Special Cases\n if (o1 === 0 && onSegment(p1, p2, q1)) return true\n if (o2 === 0 && onSegment(p1, q2, q1)) return true\n if (o3 === 0 && onSegment(p2, p1, q2)) return true\n if (o4 === 0 && onSegment(p2, q1, q2)) return true\n\n return false\n}\n\n/**\n * Returns 0 if the points are colinear, 1 if they are clockwise, and 2 if they are counterclockwise.\n */\nexport function orientation(p: Point, q: Point, r: Point): number {\n const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y)\n if (val === 0) return 0 // colinear\n return val > 0 ? 1 : 2 // clock or counterclock wise\n}\n\n/**\n * Returns true if q is on the segment p->r.\n */\nexport function onSegment(p: Point, q: Point, r: Point): boolean {\n return (\n q.x <= Math.max(p.x, r.x) &&\n q.x >= Math.min(p.x, r.x) &&\n q.y <= Math.max(p.y, r.y) &&\n q.y >= Math.min(p.y, r.y)\n )\n}\n\n/**\n * Returns the minimum distance between two segments.\n */\nfunction segmentsDistance(a1: Point, a2: Point, b1: Point, b2: Point): number {\n // Handle degenerate cases: segments of zero length\n if (a1.x === a2.x && a1.y === a2.y) {\n return pointToSegmentDistance(a1, b1, b2)\n }\n if (b1.x === b2.x && b1.y === b2.y) {\n return pointToSegmentDistance(b1, a1, a2)\n }\n\n // Check if segments intersect\n if (doSegmentsIntersect(a1, a2, b1, b2)) {\n return 0\n }\n\n // Compute the minimum distance between the segments\n const distances = [\n pointToSegmentDistance(a1, b1, b2),\n pointToSegmentDistance(a2, b1, b2),\n pointToSegmentDistance(b1, a1, a2),\n pointToSegmentDistance(b2, a1, a2),\n ]\n\n return Math.min(...distances)\n}\n\n/**\n * Returns the minimum distance between a point and a segment.\n */\nexport function pointToSegmentDistance(p: Point, v: Point, w: Point): number {\n const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2\n if (l2 === 0) return distance(p, v)\n\n let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2\n t = Math.max(0, Math.min(1, t))\n\n const projection = {\n x: v.x + t * (w.x - v.x),\n y: v.y + t * (w.y - v.y),\n }\n\n return distance(p, projection)\n}\n\n/**\n * Returns the distance between two points.\n */\nexport function distance(p1: Point, p2: Point): number {\n const dx = p1.x - p2.x\n const dy = p1.y - p2.y\n return Math.sqrt(dx * dx + dy * dy)\n}\n","import { CapacityMeshNode } from \"../types\"\n\nexport function areNodesBordering(\n node1: CapacityMeshNode,\n node2: CapacityMeshNode,\n): boolean {\n const n1Left = node1.center.x - node1.width / 2\n const n1Right = node1.center.x + node1.width / 2\n const n1Top = node1.center.y - node1.height / 2\n const n1Bottom = node1.center.y + node1.height / 2\n\n const n2Left = node2.center.x - node2.width / 2\n const n2Right = node2.center.x + node2.width / 2\n const n2Top = node2.center.y - node2.height / 2\n const n2Bottom = node2.center.y + node2.height / 2\n\n const epsilon = 0.001\n\n const shareVerticalBorder =\n (Math.abs(n1Right - n2Left) < epsilon ||\n Math.abs(n1Left - n2Right) < epsilon) &&\n Math.min(n1Bottom, n2Bottom) - Math.max(n1Top, n2Top) >= epsilon\n\n const shareHorizontalBorder =\n (Math.abs(n1Bottom - n2Top) < epsilon ||\n Math.abs(n1Top - n2Bottom) < epsilon) &&\n Math.min(n1Right, n2Right) - Math.max(n1Left, n2Left) >= epsilon\n\n return shareVerticalBorder || shareHorizontalBorder\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n} from \"../../types/capacity-mesh-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { distance } from \"@tscircuit/math-utils\"\nimport { areNodesBordering } from \"lib/utils/areNodesBordering\"\n\nexport class CapacityMeshEdgeSolver extends BaseSolver {\n public edges: Array<CapacityMeshEdge>\n\n constructor(public nodes: CapacityMeshNode[]) {\n super()\n this.edges = []\n }\n\n getNextCapacityMeshEdgeId() {\n return `ce${this.edges.length}`\n }\n\n step() {\n this.edges = []\n for (let i = 0; i < this.nodes.length; i++) {\n for (let j = i + 1; j < this.nodes.length; j++) {\n if (\n !(this.nodes[i]._strawNode && this.nodes[j]._strawNode) &&\n areNodesBordering(this.nodes[i], this.nodes[j]) &&\n this.doNodesHaveSharedLayer(this.nodes[i], this.nodes[j])\n ) {\n this.edges.push({\n capacityMeshEdgeId: this.getNextCapacityMeshEdgeId(),\n nodeIds: [\n this.nodes[i].capacityMeshNodeId,\n this.nodes[j].capacityMeshNodeId,\n ],\n })\n }\n }\n }\n\n // If a target node is not connected to any other node, then it is \"inside\n // an obstacle\" (this is the case almost 100% of the time when we place\n // targets inside of PCB pads)\n // To fix this we connect it to the nearest nodes without obstacles\n const targetNodes = this.nodes.filter((node) => node._containsTarget)\n for (const targetNode of targetNodes) {\n const hasEdge = this.edges.some((edge) =>\n edge.nodeIds.includes(targetNode.capacityMeshNodeId),\n )\n if (hasEdge) continue\n\n let nearestNode: CapacityMeshNode | null = null\n let nearestDistance = Infinity\n for (const node of this.nodes) {\n if (node._containsObstacle) continue\n if (node._containsTarget) continue\n const dist = distance(targetNode.center, node.center)\n if (dist < nearestDistance) {\n nearestDistance = dist\n nearestNode = node\n }\n }\n if (nearestNode) {\n this.edges.push({\n capacityMeshEdgeId: this.getNextCapacityMeshEdgeId(),\n nodeIds: [\n targetNode.capacityMeshNodeId,\n nearestNode.capacityMeshNodeId,\n ],\n })\n }\n }\n\n this.solved = true\n }\n\n private doNodesHaveSharedLayer(\n node1: CapacityMeshNode,\n node2: CapacityMeshNode,\n ): boolean {\n return node1.availableZ.some((z) => node2.availableZ.includes(z))\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: this.nodes.map((node) => {\n const lowestZ = Math.min(...node.availableZ)\n return {\n width: Math.max(node.width - 2, node.width * 0.8),\n height: Math.max(node.height - 2, node.height * 0.8),\n center: {\n x: node.center.x + lowestZ * node.width * 0.05,\n y: node.center.y - lowestZ * node.width * 0.05,\n },\n fill: node._containsObstacle\n ? \"rgba(255,0,0,0.1)\"\n : ({\n \"0,1\": \"rgba(0,0,0,0.1)\",\n \"0\": \"rgba(0,200,200, 0.1)\",\n \"1\": \"rgba(0,0,200, 0.1)\",\n }[node.availableZ.join(\",\")] ?? \"rgba(0,200,200,0.1)\"),\n label: [\n node.capacityMeshNodeId,\n `availableZ: ${node.availableZ.join(\",\")}`,\n `target? ${node._containsTarget ?? false}`,\n `obs? ${node._containsObstacle ?? false}`,\n ].join(\"\\n\"),\n }\n }),\n circles: [],\n }\n for (const edge of this.edges) {\n const node1 = this.nodes.find(\n (node) => node.capacityMeshNodeId === edge.nodeIds[0],\n )\n const node2 = this.nodes.find(\n (node) => node.capacityMeshNodeId === edge.nodeIds[1],\n )\n if (node1?.center && node2?.center) {\n const lowestZ1 = Math.min(...node1.availableZ)\n const lowestZ2 = Math.min(...node2.availableZ)\n const nodeCenter1Adj = {\n x: node1.center.x + lowestZ1 * node1.width * 0.05,\n y: node1.center.y - lowestZ1 * node1.width * 0.05,\n }\n const nodeCenter2Adj = {\n x: node2.center.x + lowestZ2 * node2.width * 0.05,\n y: node2.center.y - lowestZ2 * node2.width * 0.05,\n }\n graphics.lines!.push({\n points: [nodeCenter1Adj, nodeCenter2Adj],\n strokeDash:\n node1.availableZ.join(\",\") === node2.availableZ.join(\",\")\n ? undefined\n : \"10 5\",\n })\n }\n }\n return graphics\n }\n}\n","function _extends() {\n return _extends = Object.assign ? Object.assign.bind() : function (n) {\n for (var e = 1; e < arguments.length; e++) {\n var t = arguments[e];\n for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);\n }\n return n;\n }, _extends.apply(null, arguments);\n}\nexport { _extends as default };","function _assertThisInitialized(e) {\n if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n return e;\n}\nexport { _assertThisInitialized as default };","function _setPrototypeOf(t, e) {\n return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {\n return t.__proto__ = e, t;\n }, _setPrototypeOf(t, e);\n}\nexport { _setPrototypeOf as default };","import setPrototypeOf from \"./setPrototypeOf.js\";\nfunction _inheritsLoose(t, o) {\n t.prototype = Object.create(o.prototype), t.prototype.constructor = t, setPrototypeOf(t, o);\n}\nexport { _inheritsLoose as default };","function _getPrototypeOf(t) {\n return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {\n return t.__proto__ || Object.getPrototypeOf(t);\n }, _getPrototypeOf(t);\n}\nexport { _getPrototypeOf as default };","function _isNativeFunction(t) {\n try {\n return -1 !== Function.toString.call(t).indexOf(\"[native code]\");\n } catch (n) {\n return \"function\" == typeof t;\n }\n}\nexport { _isNativeFunction as default };","function _isNativeReflectConstruct() {\n try {\n var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n } catch (t) {}\n return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {\n return !!t;\n })();\n}\nexport { _isNativeReflectConstruct as default };","import isNativeReflectConstruct from \"./isNativeReflectConstruct.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nfunction _construct(t, e, r) {\n if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);\n var o = [null];\n o.push.apply(o, e);\n var p = new (t.bind.apply(t, o))();\n return r && setPrototypeOf(p, r.prototype), p;\n}\nexport { _construct as default };","import getPrototypeOf from \"./getPrototypeOf.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeFunction from \"./isNativeFunction.js\";\nimport construct from \"./construct.js\";\nfunction _wrapNativeSuper(t) {\n var r = \"function\" == typeof Map ? new Map() : void 0;\n return _wrapNativeSuper = function _wrapNativeSuper(t) {\n if (null === t || !isNativeFunction(t)) return t;\n if (\"function\" != typeof t) throw new TypeError(\"Super expression must either be null or a function\");\n if (void 0 !== r) {\n if (r.has(t)) return r.get(t);\n r.set(t, Wrapper);\n }\n function Wrapper() {\n return construct(t, arguments, getPrototypeOf(this).constructor);\n }\n return Wrapper.prototype = Object.create(t.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: !1,\n writable: !0,\n configurable: !0\n }\n }), setPrototypeOf(Wrapper, t);\n }, _wrapNativeSuper(t);\n}\nexport { _wrapNativeSuper as default };","import _extends from '@babel/runtime/helpers/esm/extends';\nimport _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized';\nimport _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';\nimport _wrapNativeSuper from '@babel/runtime/helpers/esm/wrapNativeSuper';\nimport _taggedTemplateLiteralLoose from '@babel/runtime/helpers/esm/taggedTemplateLiteralLoose';\n\nfunction last() {\n var _ref;\n return _ref = arguments.length - 1, _ref < 0 || arguments.length <= _ref ? undefined : arguments[_ref];\n}\nfunction negation(a) {\n return -a;\n}\nfunction addition(a, b) {\n return a + b;\n}\nfunction subtraction(a, b) {\n return a - b;\n}\nfunction multiplication(a, b) {\n return a * b;\n}\nfunction division(a, b) {\n return a / b;\n}\nfunction max() {\n return Math.max.apply(Math, arguments);\n}\nfunction min() {\n return Math.min.apply(Math, arguments);\n}\nfunction comma() {\n return Array.of.apply(Array, arguments);\n}\nvar defaultSymbols = {\n symbols: {\n '*': {\n infix: {\n symbol: '*',\n f: multiplication,\n notation: 'infix',\n precedence: 4,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: '*',\n regSymbol: '\\\\*'\n },\n '/': {\n infix: {\n symbol: '/',\n f: division,\n notation: 'infix',\n precedence: 4,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: '/',\n regSymbol: '/'\n },\n '+': {\n infix: {\n symbol: '+',\n f: addition,\n notation: 'infix',\n precedence: 2,\n rightToLeft: 0,\n argCount: 2\n },\n prefix: {\n symbol: '+',\n f: last,\n notation: 'prefix',\n precedence: 3,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '+',\n regSymbol: '\\\\+'\n },\n '-': {\n infix: {\n symbol: '-',\n f: subtraction,\n notation: 'infix',\n precedence: 2,\n rightToLeft: 0,\n argCount: 2\n },\n prefix: {\n symbol: '-',\n f: negation,\n notation: 'prefix',\n precedence: 3,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '-',\n regSymbol: '-'\n },\n ',': {\n infix: {\n symbol: ',',\n f: comma,\n notation: 'infix',\n precedence: 1,\n rightToLeft: 0,\n argCount: 2\n },\n symbol: ',',\n regSymbol: ','\n },\n '(': {\n prefix: {\n symbol: '(',\n f: last,\n notation: 'prefix',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: '(',\n regSymbol: '\\\\('\n },\n ')': {\n postfix: {\n symbol: ')',\n f: undefined,\n notation: 'postfix',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: ')',\n regSymbol: '\\\\)'\n },\n min: {\n func: {\n symbol: 'min',\n f: min,\n notation: 'func',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: 'min',\n regSymbol: 'min\\\\b'\n },\n max: {\n func: {\n symbol: 'max',\n f: max,\n notation: 'func',\n precedence: 0,\n rightToLeft: 0,\n argCount: 1\n },\n symbol: 'max',\n regSymbol: 'max\\\\b'\n }\n }\n};\nvar defaultSymbolMap = defaultSymbols;\n\n// based on https://github.com/styled-components/styled-components/blob/fcf6f3804c57a14dd7984dfab7bc06ee2edca044/src/utils/error.js\n/**\n * Parse errors.md and turn it into a simple hash of code: message\n * @private\n */\nvar ERRORS = {\n \"1\": \"Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\\n\\n\",\n \"2\": \"Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\\n\\n\",\n \"3\": \"Passed an incorrect argument to a color function, please pass a string representation of a color.\\n\\n\",\n \"4\": \"Couldn't generate valid rgb string from %s, it returned %s.\\n\\n\",\n \"5\": \"Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\\n\\n\",\n \"6\": \"Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\\n\\n\",\n \"7\": \"Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\\n\\n\",\n \"8\": \"Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\\n\\n\",\n \"9\": \"Please provide a number of steps to the modularScale helper.\\n\\n\",\n \"10\": \"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\\n\\n\",\n \"11\": \"Invalid value passed as base to modularScale, expected number or em string but got \\\"%s\\\"\\n\\n\",\n \"12\": \"Expected a string ending in \\\"px\\\" or a number passed as the first argument to %s(), got \\\"%s\\\" instead.\\n\\n\",\n \"13\": \"Expected a string ending in \\\"px\\\" or a number passed as the second argument to %s(), got \\\"%s\\\" instead.\\n\\n\",\n \"14\": \"Passed invalid pixel value (\\\"%s\\\") to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"15\": \"Passed invalid base value (\\\"%s\\\") to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"16\": \"You must provide a template to this method.\\n\\n\",\n \"17\": \"You passed an unsupported selector state to this method.\\n\\n\",\n \"18\": \"minScreen and maxScreen must be provided as stringified numbers with the same units.\\n\\n\",\n \"19\": \"fromSize and toSize must be provided as stringified numbers with the same units.\\n\\n\",\n \"20\": \"expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\\n\\n\",\n \"21\": \"expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\\n\\n\",\n \"22\": \"expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\\n\\n\",\n \"23\": \"fontFace expects a name of a font-family.\\n\\n\",\n \"24\": \"fontFace expects either the path to the font file(s) or a name of a local copy.\\n\\n\",\n \"25\": \"fontFace expects localFonts to be an array.\\n\\n\",\n \"26\": \"fontFace expects fileFormats to be an array.\\n\\n\",\n \"27\": \"radialGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"28\": \"Please supply a filename to retinaImage() as the first argument.\\n\\n\",\n \"29\": \"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\\n\\n\",\n \"30\": \"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\\n\\n\",\n \"31\": \"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\\n\\n\",\n \"32\": \"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\\n\\n\",\n \"33\": \"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\\n\\n\",\n \"34\": \"borderRadius expects a radius value as a string or number as the second argument.\\n\\n\",\n \"35\": \"borderRadius expects one of \\\"top\\\", \\\"bottom\\\", \\\"left\\\" or \\\"right\\\" as the first argument.\\n\\n\",\n \"36\": \"Property must be a string value.\\n\\n\",\n \"37\": \"Syntax Error at %s.\\n\\n\",\n \"38\": \"Formula contains a function that needs parentheses at %s.\\n\\n\",\n \"39\": \"Formula is missing closing parenthesis at %s.\\n\\n\",\n \"40\": \"Formula has too many closing parentheses at %s.\\n\\n\",\n \"41\": \"All values in a formula must have the same unit or be unitless.\\n\\n\",\n \"42\": \"Please provide a number of steps to the modularScale helper.\\n\\n\",\n \"43\": \"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\\n\\n\",\n \"44\": \"Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\\n\\n\",\n \"45\": \"Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\\n\\n\",\n \"46\": \"Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\\n\\n\",\n \"47\": \"minScreen and maxScreen must be provided as stringified numbers with the same units.\\n\\n\",\n \"48\": \"fromSize and toSize must be provided as stringified numbers with the same units.\\n\\n\",\n \"49\": \"Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\\n\\n\",\n \"50\": \"Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\\n\\n\",\n \"51\": \"Expects the first argument object to have the properties prop, fromSize, and toSize.\\n\\n\",\n \"52\": \"fontFace expects either the path to the font file(s) or a name of a local copy.\\n\\n\",\n \"53\": \"fontFace expects localFonts to be an array.\\n\\n\",\n \"54\": \"fontFace expects fileFormats to be an array.\\n\\n\",\n \"55\": \"fontFace expects a name of a font-family.\\n\\n\",\n \"56\": \"linearGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"57\": \"radialGradient requries at least 2 color-stops to properly render.\\n\\n\",\n \"58\": \"Please supply a filename to retinaImage() as the first argument.\\n\\n\",\n \"59\": \"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\\n\\n\",\n \"60\": \"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\\n\\n\",\n \"61\": \"Property must be a string value.\\n\\n\",\n \"62\": \"borderRadius expects a radius value as a string or number as the second argument.\\n\\n\",\n \"63\": \"borderRadius expects one of \\\"top\\\", \\\"bottom\\\", \\\"left\\\" or \\\"right\\\" as the first argument.\\n\\n\",\n \"64\": \"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\\n\\n\",\n \"65\": \"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\\n\\n\",\n \"66\": \"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\\n\\n\",\n \"67\": \"You must provide a template to this method.\\n\\n\",\n \"68\": \"You passed an unsupported selector state to this method.\\n\\n\",\n \"69\": \"Expected a string ending in \\\"px\\\" or a number passed as the first argument to %s(), got %s instead.\\n\\n\",\n \"70\": \"Expected a string ending in \\\"px\\\" or a number passed as the second argument to %s(), got %s instead.\\n\\n\",\n \"71\": \"Passed invalid pixel value %s to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"72\": \"Passed invalid base value %s to %s(), please pass a value like \\\"12px\\\" or 12.\\n\\n\",\n \"73\": \"Please provide a valid CSS variable.\\n\\n\",\n \"74\": \"CSS variable not found and no default was provided.\\n\\n\",\n \"75\": \"important requires a valid style object, got a %s instead.\\n\\n\",\n \"76\": \"fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\\n\\n\",\n \"77\": \"remToPx expects a value in \\\"rem\\\" but you provided it in \\\"%s\\\".\\n\\n\",\n \"78\": \"base must be set in \\\"px\\\" or \\\"%\\\" but you set it in \\\"%s\\\".\\n\"\n};\n\n/**\n * super basic version of sprintf\n * @private\n */\nfunction format() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n var a = args[0];\n var b = [];\n var c;\n for (c = 1; c < args.length; c += 1) {\n b.push(args[c]);\n }\n b.forEach(function (d) {\n a = a.replace(/%[a-z]/, d);\n });\n return a;\n}\n\n/**\n * Create an error file out of errors.md for development and a simple web link to the full errors\n * in production mode.\n * @private\n */\nvar PolishedError = /*#__PURE__*/function (_Error) {\n _inheritsLoose(PolishedError, _Error);\n function PolishedError(code) {\n var _this;\n if (process.env.NODE_ENV === 'production') {\n _this = _Error.call(this, \"An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#\" + code + \" for more information.\") || this;\n } else {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n _this = _Error.call(this, format.apply(void 0, [ERRORS[code]].concat(args))) || this;\n }\n return _assertThisInitialized(_this);\n }\n return PolishedError;\n}( /*#__PURE__*/_wrapNativeSuper(Error));\n\nvar unitRegExp = /((?!\\w)a|na|hc|mc|dg|me[r]?|xe|ni(?![a-zA-Z])|mm|cp|tp|xp|q(?!s)|hv|xamv|nimv|wv|sm|s(?!\\D|$)|ged|darg?|nrut)/g;\n\n// Merges additional math functionality into the defaults.\nfunction mergeSymbolMaps(additionalSymbols) {\n var symbolMap = {};\n symbolMap.symbols = additionalSymbols ? _extends({}, defaultSymbolMap.symbols, additionalSymbols.symbols) : _extends({}, defaultSymbolMap.symbols);\n return symbolMap;\n}\nfunction exec(operators, values) {\n var _ref;\n var op = operators.pop();\n values.push(op.f.apply(op, (_ref = []).concat.apply(_ref, values.splice(-op.argCount))));\n return op.precedence;\n}\nfunction calculate(expression, additionalSymbols) {\n var symbolMap = mergeSymbolMaps(additionalSymbols);\n var match;\n var operators = [symbolMap.symbols['('].prefix];\n var values = [];\n var pattern = new RegExp( // Pattern for numbers\n \"\\\\d+(?:\\\\.\\\\d+)?|\" +\n // ...and patterns for individual operators/function names\n Object.keys(symbolMap.symbols).map(function (key) {\n return symbolMap.symbols[key];\n })\n // longer symbols should be listed first\n // $FlowFixMe\n .sort(function (a, b) {\n return b.symbol.length - a.symbol.length;\n })\n // $FlowFixMe\n .map(function (val) {\n return val.regSymbol;\n }).join('|') + \"|(\\\\S)\", 'g');\n pattern.lastIndex = 0; // Reset regular expression object\n\n var afterValue = false;\n do {\n match = pattern.exec(expression);\n var _ref2 = match || [')', undefined],\n token = _ref2[0],\n bad = _ref2[1];\n var notNumber = symbolMap.symbols[token];\n var notNewValue = notNumber && !notNumber.prefix && !notNumber.func;\n var notAfterValue = !notNumber || !notNumber.postfix && !notNumber.infix;\n\n // Check for syntax errors:\n if (bad || (afterValue ? notAfterValue : notNewValue)) {\n throw new PolishedError(37, match ? match.index : expression.length, expression);\n }\n if (afterValue) {\n // We either have an infix or postfix operator (they should be mutually exclusive)\n var curr = notNumber.postfix || notNumber.infix;\n do {\n var prev = operators[operators.length - 1];\n if ((curr.precedence - prev.precedence || prev.rightToLeft) > 0) break;\n // Apply previous operator, since it has precedence over current one\n } while (exec(operators, values)); // Exit loop after executing an opening parenthesis or function\n afterValue = curr.notation === 'postfix';\n if (curr.symbol !== ')') {\n operators.push(curr);\n // Postfix always has precedence over any operator that follows after it\n if (afterValue) exec(operators, values);\n }\n } else if (notNumber) {\n // prefix operator or function\n operators.push(notNumber.prefix || notNumber.func);\n if (notNumber.func) {\n // Require an opening parenthesis\n match = pattern.exec(expression);\n if (!match || match[0] !== '(') {\n throw new PolishedError(38, match ? match.index : expression.length, expression);\n }\n }\n } else {\n // number\n values.push(+token);\n afterValue = true;\n }\n } while (match && operators.length);\n if (operators.length) {\n throw new PolishedError(39, match ? match.index : expression.length, expression);\n } else if (match) {\n throw new PolishedError(40, match ? match.index : expression.length, expression);\n } else {\n return values.pop();\n }\n}\nfunction reverseString(str) {\n return str.split('').reverse().join('');\n}\n\n/**\n * Helper for doing math with CSS Units. Accepts a formula as a string. All values in the formula must have the same unit (or be unitless). Supports complex formulas utliziing addition, subtraction, multiplication, division, square root, powers, factorial, min, max, as well as parentheses for order of operation.\n *\n *In cases where you need to do calculations with mixed units where one unit is a [relative length unit](https://developer.mozilla.org/en-US/docs/Web/CSS/length#Relative_length_units), you will want to use [CSS Calc](https://developer.mozilla.org/en-US/docs/Web/CSS/calc).\n *\n * *warning* While we've done everything possible to ensure math safely evalutes formulas expressed as strings, you should always use extreme caution when passing `math` user provided values.\n * @example\n * // Styles as object usage\n * const styles = {\n * fontSize: math('12rem + 8rem'),\n * fontSize: math('(12px + 2px) * 3'),\n * fontSize: math('3px^2 + sqrt(4)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * fontSize: ${math('12rem + 8rem')};\n * fontSize: ${math('(12px + 2px) * 3')};\n * fontSize: ${math('3px^2 + sqrt(4)')};\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * fontSize: '20rem',\n * fontSize: '42px',\n * fontSize: '11px',\n * }\n */\nfunction math(formula, additionalSymbols) {\n var reversedFormula = reverseString(formula);\n var formulaMatch = reversedFormula.match(unitRegExp);\n\n // Check that all units are the same\n if (formulaMatch && !formulaMatch.every(function (unit) {\n return unit === formulaMatch[0];\n })) {\n throw new PolishedError(41);\n }\n var cleanFormula = reverseString(reversedFormula.replace(unitRegExp, ''));\n return \"\" + calculate(cleanFormula, additionalSymbols) + (formulaMatch ? reverseString(formulaMatch[0]) : '');\n}\n\nvar cssVariableRegex = /--[\\S]*/g;\n\n/**\n * Fetches the value of a passed CSS Variable in the :root scope, or otherwise returns a defaultValue if provided.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'background': cssVar('--background-color'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${cssVar('--background-color')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'background': 'red'\n * }\n */\nfunction cssVar(cssVariable, defaultValue) {\n if (!cssVariable || !cssVariable.match(cssVariableRegex)) {\n throw new PolishedError(73);\n }\n var variableValue;\n\n /* eslint-disable */\n /* istanbul ignore next */\n if (typeof document !== 'undefined' && document.documentElement !== null) {\n variableValue = getComputedStyle(document.documentElement).getPropertyValue(cssVariable);\n }\n /* eslint-enable */\n\n if (variableValue) {\n return variableValue.trim();\n } else if (defaultValue) {\n return defaultValue;\n }\n throw new PolishedError(74);\n}\n\n// @private\nfunction capitalizeString(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nvar positionMap$1 = ['Top', 'Right', 'Bottom', 'Left'];\nfunction generateProperty(property, position) {\n if (!property) return position.toLowerCase();\n var splitProperty = property.split('-');\n if (splitProperty.length > 1) {\n splitProperty.splice(1, 0, position);\n return splitProperty.reduce(function (acc, val) {\n return \"\" + acc + capitalizeString(val);\n });\n }\n var joinedProperty = property.replace(/([a-z])([A-Z])/g, \"$1\" + position + \"$2\");\n return property === joinedProperty ? \"\" + property + position : joinedProperty;\n}\nfunction generateStyles(property, valuesWithDefaults) {\n var styles = {};\n for (var i = 0; i < valuesWithDefaults.length; i += 1) {\n if (valuesWithDefaults[i] || valuesWithDefaults[i] === 0) {\n styles[generateProperty(property, positionMap$1[i])] = valuesWithDefaults[i];\n }\n }\n return styles;\n}\n\n/**\n * Enables shorthand for direction-based properties. It accepts a property (hyphenated or camelCased) and up to four values that map to top, right, bottom, and left, respectively. You can optionally pass an empty string to get only the directional values as properties. You can also optionally pass a null argument for a directional value to ignore it.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...directionalProperty('padding', '12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${directionalProperty('padding', '12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'paddingTop': '12px',\n * 'paddingRight': '24px',\n * 'paddingBottom': '36px',\n * 'paddingLeft': '48px'\n * }\n */\nfunction directionalProperty(property) {\n for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n values[_key - 1] = arguments[_key];\n }\n // prettier-ignore\n var firstValue = values[0],\n _values$ = values[1],\n secondValue = _values$ === void 0 ? firstValue : _values$,\n _values$2 = values[2],\n thirdValue = _values$2 === void 0 ? firstValue : _values$2,\n _values$3 = values[3],\n fourthValue = _values$3 === void 0 ? secondValue : _values$3;\n var valuesWithDefaults = [firstValue, secondValue, thirdValue, fourthValue];\n return generateStyles(property, valuesWithDefaults);\n}\n\n/**\n * Check if a string ends with something\n * @private\n */\nfunction endsWith(string, suffix) {\n return string.substr(-suffix.length) === suffix;\n}\n\nvar cssRegex$1 = /^([+-]?(?:\\d+|\\d*\\.\\d+))([a-z]*|%)$/;\n\n/**\n * Returns a given CSS value minus its unit of measure.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * '--dimension': stripUnit('100px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * --dimension: ${stripUnit('100px')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * '--dimension': 100\n * }\n */\nfunction stripUnit(value) {\n if (typeof value !== 'string') return value;\n var matchedValue = value.match(cssRegex$1);\n return matchedValue ? parseFloat(value) : value;\n}\n\n/**\n * Factory function that creates pixel-to-x converters\n * @private\n */\nvar pxtoFactory = function pxtoFactory(to) {\n return function (pxval, base) {\n if (base === void 0) {\n base = '16px';\n }\n var newPxval = pxval;\n var newBase = base;\n if (typeof pxval === 'string') {\n if (!endsWith(pxval, 'px')) {\n throw new PolishedError(69, to, pxval);\n }\n newPxval = stripUnit(pxval);\n }\n if (typeof base === 'string') {\n if (!endsWith(base, 'px')) {\n throw new PolishedError(70, to, base);\n }\n newBase = stripUnit(base);\n }\n if (typeof newPxval === 'string') {\n throw new PolishedError(71, pxval, to);\n }\n if (typeof newBase === 'string') {\n throw new PolishedError(72, base, to);\n }\n return \"\" + newPxval / newBase + to;\n };\n};\nvar pixelsto = pxtoFactory;\n\n/**\n * Convert pixel value to ems. The default base value is 16px, but can be changed by passing a\n * second argument to the function.\n * @function\n * @param {string|number} pxval\n * @param {string|number} [base='16px']\n * @example\n * // Styles as object usage\n * const styles = {\n * 'height': em('16px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * height: ${em('16px')}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'height': '1em'\n * }\n */\nvar em = pixelsto('em');\nvar em$1 = em;\n\nvar cssRegex = /^([+-]?(?:\\d+|\\d*\\.\\d+))([a-z]*|%)$/;\n\n/**\n * Returns a given CSS value and its unit as elements of an array.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * '--dimension': getValueAndUnit('100px')[0],\n * '--unit': getValueAndUnit('100px')[1],\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * --dimension: ${getValueAndUnit('100px')[0]};\n * --unit: ${getValueAndUnit('100px')[1]};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * '--dimension': 100,\n * '--unit': 'px',\n * }\n */\nfunction getValueAndUnit(value) {\n if (typeof value !== 'string') return [value, ''];\n var matchedValue = value.match(cssRegex);\n if (matchedValue) return [parseFloat(value), matchedValue[2]];\n return [value, undefined];\n}\n\n/**\n * Helper for targeting rules in a style block generated by polished modules that need !important-level specificity. Can optionally specify a rule (or rules) to target specific rules.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...important(cover())\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${important(cover())}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * 'position': 'absolute !important',\n * 'top': '0 !important',\n * 'right: '0 !important',\n * 'bottom': '0 !important',\n * 'left: '0 !important'\n * }\n */\nfunction important(styleBlock, rules) {\n if (typeof styleBlock !== 'object' || styleBlock === null) {\n throw new PolishedError(75, typeof styleBlock);\n }\n var newStyleBlock = {};\n Object.keys(styleBlock).forEach(function (key) {\n if (typeof styleBlock[key] === 'object' && styleBlock[key] !== null) {\n newStyleBlock[key] = important(styleBlock[key], rules);\n } else if (!rules || rules && (rules === key || rules.indexOf(key) >= 0)) {\n newStyleBlock[key] = styleBlock[key] + \" !important\";\n } else {\n newStyleBlock[key] = styleBlock[key];\n }\n });\n return newStyleBlock;\n}\n\nvar ratioNames = {\n minorSecond: 1.067,\n majorSecond: 1.125,\n minorThird: 1.2,\n majorThird: 1.25,\n perfectFourth: 1.333,\n augFourth: 1.414,\n perfectFifth: 1.5,\n minorSixth: 1.6,\n goldenSection: 1.618,\n majorSixth: 1.667,\n minorSeventh: 1.778,\n majorSeventh: 1.875,\n octave: 2,\n majorTenth: 2.5,\n majorEleventh: 2.667,\n majorTwelfth: 3,\n doubleOctave: 4\n};\nfunction getRatio(ratioName) {\n return ratioNames[ratioName];\n}\n\n/**\n * Establish consistent measurements and spacial relationships throughout your projects by incrementing an em or rem value up or down a defined scale. We provide a list of commonly used scales as pre-defined variables.\n * @example\n * // Styles as object usage\n * const styles = {\n * // Increment two steps up the default scale\n * 'fontSize': modularScale(2)\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * // Increment two steps up the default scale\n * fontSize: ${modularScale(2)}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'fontSize': '1.77689em'\n * }\n */\nfunction modularScale(steps, base, ratio) {\n if (base === void 0) {\n base = '1em';\n }\n if (ratio === void 0) {\n ratio = 1.333;\n }\n if (typeof steps !== 'number') {\n throw new PolishedError(42);\n }\n if (typeof ratio === 'string' && !ratioNames[ratio]) {\n throw new PolishedError(43);\n }\n var _ref = typeof base === 'string' ? getValueAndUnit(base) : [base, ''],\n realBase = _ref[0],\n unit = _ref[1];\n var realRatio = typeof ratio === 'string' ? getRatio(ratio) : ratio;\n if (typeof realBase === 'string') {\n throw new PolishedError(44, base);\n }\n return \"\" + realBase * Math.pow(realRatio, steps) + (unit || '');\n}\n\n/**\n * Convert pixel value to rems. The default base value is 16px, but can be changed by passing a\n * second argument to the function.\n * @function\n * @param {string|number} pxval\n * @param {string|number} [base='16px']\n * @example\n * // Styles as object usage\n * const styles = {\n * 'height': rem('16px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * height: ${rem('16px')}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'height': '1rem'\n * }\n */\nvar rem = pixelsto('rem');\nvar rem$1 = rem;\n\nvar defaultFontSize = 16;\nfunction convertBase(base) {\n var deconstructedValue = getValueAndUnit(base);\n if (deconstructedValue[1] === 'px') {\n return parseFloat(base);\n }\n if (deconstructedValue[1] === '%') {\n return parseFloat(base) / 100 * defaultFontSize;\n }\n throw new PolishedError(78, deconstructedValue[1]);\n}\nfunction getBaseFromDoc() {\n /* eslint-disable */\n /* istanbul ignore next */\n if (typeof document !== 'undefined' && document.documentElement !== null) {\n var rootFontSize = getComputedStyle(document.documentElement).fontSize;\n return rootFontSize ? convertBase(rootFontSize) : defaultFontSize;\n }\n /* eslint-enable */\n /* istanbul ignore next */\n return defaultFontSize;\n}\n\n/**\n * Convert rem values to px. By default, the base value is pulled from the font-size property on the root element (if it is set in % or px). It defaults to 16px if not found on the root. You can also override the base value by providing your own base in % or px.\n * @example\n * // Styles as object usage\n * const styles = {\n * 'height': remToPx('1.6rem')\n * 'height': remToPx('1.6rem', '10px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * height: ${remToPx('1.6rem')}\n * height: ${remToPx('1.6rem', '10px')}\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * 'height': '25.6px',\n * 'height': '16px',\n * }\n */\nfunction remToPx(value, base) {\n var deconstructedValue = getValueAndUnit(value);\n if (deconstructedValue[1] !== 'rem' && deconstructedValue[1] !== '') {\n throw new PolishedError(77, deconstructedValue[1]);\n }\n var newBase = base ? convertBase(base) : getBaseFromDoc();\n return deconstructedValue[0] * newBase + \"px\";\n}\n\nvar functionsMap$3 = {\n back: 'cubic-bezier(0.600, -0.280, 0.735, 0.045)',\n circ: 'cubic-bezier(0.600, 0.040, 0.980, 0.335)',\n cubic: 'cubic-bezier(0.550, 0.055, 0.675, 0.190)',\n expo: 'cubic-bezier(0.950, 0.050, 0.795, 0.035)',\n quad: 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n quart: 'cubic-bezier(0.895, 0.030, 0.685, 0.220)',\n quint: 'cubic-bezier(0.755, 0.050, 0.855, 0.060)',\n sine: 'cubic-bezier(0.470, 0.000, 0.745, 0.715)'\n};\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': easeIn('quad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${easeIn('quad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n * }\n */\nfunction easeIn(functionName) {\n return functionsMap$3[functionName.toLowerCase().trim()];\n}\n\nvar functionsMap$2 = {\n back: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)',\n circ: 'cubic-bezier(0.785, 0.135, 0.150, 0.860)',\n cubic: 'cubic-bezier(0.645, 0.045, 0.355, 1.000)',\n expo: 'cubic-bezier(1.000, 0.000, 0.000, 1.000)',\n quad: 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',\n quart: 'cubic-bezier(0.770, 0.000, 0.175, 1.000)',\n quint: 'cubic-bezier(0.860, 0.000, 0.070, 1.000)',\n sine: 'cubic-bezier(0.445, 0.050, 0.550, 0.950)'\n};\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': easeInOut('quad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${easeInOut('quad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',\n * }\n */\nfunction easeInOut(functionName) {\n return functionsMap$2[functionName.toLowerCase().trim()];\n}\n\nvar functionsMap$1 = {\n back: 'cubic-bezier(0.175, 0.885, 0.320, 1.275)',\n cubic: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',\n circ: 'cubic-bezier(0.075, 0.820, 0.165, 1.000)',\n expo: 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',\n quad: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',\n quart: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)',\n quint: 'cubic-bezier(0.230, 1.000, 0.320, 1.000)',\n sine: 'cubic-bezier(0.390, 0.575, 0.565, 1.000)'\n};\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': easeOut('quad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${easeOut('quad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',\n * }\n */\nfunction easeOut(functionName) {\n return functionsMap$1[functionName.toLowerCase().trim()];\n}\n\n/**\n * Returns a CSS calc formula for linear interpolation of a property between two values. Accepts optional minScreen (defaults to '320px') and maxScreen (defaults to '1200px').\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * fontSize: between('20px', '100px', '400px', '1000px'),\n * fontSize: between('20px', '100px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * fontSize: ${between('20px', '100px', '400px', '1000px')};\n * fontSize: ${between('20px', '100px')}\n * `\n *\n * // CSS as JS Output\n *\n * h1: {\n * 'fontSize': 'calc(-33.33333333333334px + 13.333333333333334vw)',\n * 'fontSize': 'calc(-9.090909090909093px + 9.090909090909092vw)'\n * }\n */\nfunction between(fromSize, toSize, minScreen, maxScreen) {\n if (minScreen === void 0) {\n minScreen = '320px';\n }\n if (maxScreen === void 0) {\n maxScreen = '1200px';\n }\n var _getValueAndUnit = getValueAndUnit(fromSize),\n unitlessFromSize = _getValueAndUnit[0],\n fromSizeUnit = _getValueAndUnit[1];\n var _getValueAndUnit2 = getValueAndUnit(toSize),\n unitlessToSize = _getValueAndUnit2[0],\n toSizeUnit = _getValueAndUnit2[1];\n var _getValueAndUnit3 = getValueAndUnit(minScreen),\n unitlessMinScreen = _getValueAndUnit3[0],\n minScreenUnit = _getValueAndUnit3[1];\n var _getValueAndUnit4 = getValueAndUnit(maxScreen),\n unitlessMaxScreen = _getValueAndUnit4[0],\n maxScreenUnit = _getValueAndUnit4[1];\n if (typeof unitlessMinScreen !== 'number' || typeof unitlessMaxScreen !== 'number' || !minScreenUnit || !maxScreenUnit || minScreenUnit !== maxScreenUnit) {\n throw new PolishedError(47);\n }\n if (typeof unitlessFromSize !== 'number' || typeof unitlessToSize !== 'number' || fromSizeUnit !== toSizeUnit) {\n throw new PolishedError(48);\n }\n if (fromSizeUnit !== minScreenUnit || toSizeUnit !== maxScreenUnit) {\n throw new PolishedError(76);\n }\n var slope = (unitlessFromSize - unitlessToSize) / (unitlessMinScreen - unitlessMaxScreen);\n var base = unitlessToSize - slope * unitlessMaxScreen;\n return \"calc(\" + base.toFixed(2) + (fromSizeUnit || '') + \" + \" + (100 * slope).toFixed(2) + \"vw)\";\n}\n\n/**\n * CSS to contain a float (credit to CSSMojo).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...clearFix(),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${clearFix()}\n * `\n *\n * // CSS as JS Output\n *\n * '&::after': {\n * 'clear': 'both',\n * 'content': '\"\"',\n * 'display': 'table'\n * }\n */\nfunction clearFix(parent) {\n var _ref;\n if (parent === void 0) {\n parent = '&';\n }\n var pseudoSelector = parent + \"::after\";\n return _ref = {}, _ref[pseudoSelector] = {\n clear: 'both',\n content: '\"\"',\n display: 'table'\n }, _ref;\n}\n\n/**\n * CSS to fully cover an area. Can optionally be passed an offset to act as a \"padding\".\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...cover()\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${cover()}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * 'position': 'absolute',\n * 'top': '0',\n * 'right: '0',\n * 'bottom': '0',\n * 'left: '0'\n * }\n */\nfunction cover(offset) {\n if (offset === void 0) {\n offset = 0;\n }\n return {\n position: 'absolute',\n top: offset,\n right: offset,\n bottom: offset,\n left: offset\n };\n}\n\n/**\n * CSS to represent truncated text with an ellipsis. You can optionally pass a max-width and number of lines before truncating.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...ellipsis('250px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${ellipsis('250px')}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * 'display': 'inline-block',\n * 'maxWidth': '250px',\n * 'overflow': 'hidden',\n * 'textOverflow': 'ellipsis',\n * 'whiteSpace': 'nowrap',\n * 'wordWrap': 'normal'\n * }\n */\nfunction ellipsis(width, lines) {\n if (lines === void 0) {\n lines = 1;\n }\n var styles = {\n display: 'inline-block',\n maxWidth: width || '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n wordWrap: 'normal'\n };\n return lines > 1 ? _extends({}, styles, {\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: lines,\n display: '-webkit-box',\n whiteSpace: 'normal'\n }) : styles;\n}\n\nfunction _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\n/**\n * Returns a set of media queries that resizes a property (or set of properties) between a provided fromSize and toSize. Accepts optional minScreen (defaults to '320px') and maxScreen (defaults to '1200px') to constrain the interpolation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...fluidRange(\n * {\n * prop: 'padding',\n * fromSize: '20px',\n * toSize: '100px',\n * },\n * '400px',\n * '1000px',\n * )\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${fluidRange(\n * {\n * prop: 'padding',\n * fromSize: '20px',\n * toSize: '100px',\n * },\n * '400px',\n * '1000px',\n * )}\n * `\n *\n * // CSS as JS Output\n *\n * div: {\n * \"@media (min-width: 1000px)\": Object {\n * \"padding\": \"100px\",\n * },\n * \"@media (min-width: 400px)\": Object {\n * \"padding\": \"calc(-33.33333333333334px + 13.333333333333334vw)\",\n * },\n * \"padding\": \"20px\",\n * }\n */\nfunction fluidRange(cssProp, minScreen, maxScreen) {\n if (minScreen === void 0) {\n minScreen = '320px';\n }\n if (maxScreen === void 0) {\n maxScreen = '1200px';\n }\n if (!Array.isArray(cssProp) && typeof cssProp !== 'object' || cssProp === null) {\n throw new PolishedError(49);\n }\n if (Array.isArray(cssProp)) {\n var mediaQueries = {};\n var fallbacks = {};\n for (var _iterator = _createForOfIteratorHelperLoose(cssProp), _step; !(_step = _iterator()).done;) {\n var _extends2, _extends3;\n var obj = _step.value;\n if (!obj.prop || !obj.fromSize || !obj.toSize) {\n throw new PolishedError(50);\n }\n fallbacks[obj.prop] = obj.fromSize;\n mediaQueries[\"@media (min-width: \" + minScreen + \")\"] = _extends({}, mediaQueries[\"@media (min-width: \" + minScreen + \")\"], (_extends2 = {}, _extends2[obj.prop] = between(obj.fromSize, obj.toSize, minScreen, maxScreen), _extends2));\n mediaQueries[\"@media (min-width: \" + maxScreen + \")\"] = _extends({}, mediaQueries[\"@media (min-width: \" + maxScreen + \")\"], (_extends3 = {}, _extends3[obj.prop] = obj.toSize, _extends3));\n }\n return _extends({}, fallbacks, mediaQueries);\n } else {\n var _ref, _ref2, _ref3;\n if (!cssProp.prop || !cssProp.fromSize || !cssProp.toSize) {\n throw new PolishedError(51);\n }\n return _ref3 = {}, _ref3[cssProp.prop] = cssProp.fromSize, _ref3[\"@media (min-width: \" + minScreen + \")\"] = (_ref = {}, _ref[cssProp.prop] = between(cssProp.fromSize, cssProp.toSize, minScreen, maxScreen), _ref), _ref3[\"@media (min-width: \" + maxScreen + \")\"] = (_ref2 = {}, _ref2[cssProp.prop] = cssProp.toSize, _ref2), _ref3;\n }\n}\n\nvar dataURIRegex = /^\\s*data:([a-z]+\\/[a-z-]+(;[a-z-]+=[a-z-]+)?)?(;charset=[a-z0-9-]+)?(;base64)?,[a-z0-9!$&',()*+,;=\\-._~:@/?%\\s]*\\s*$/i;\nvar formatHintMap = {\n woff: 'woff',\n woff2: 'woff2',\n ttf: 'truetype',\n otf: 'opentype',\n eot: 'embedded-opentype',\n svg: 'svg',\n svgz: 'svg'\n};\nfunction generateFormatHint(format, formatHint) {\n if (!formatHint) return '';\n return \" format(\\\"\" + formatHintMap[format] + \"\\\")\";\n}\nfunction isDataURI(fontFilePath) {\n return !!fontFilePath.replace(/\\s+/g, ' ').match(dataURIRegex);\n}\nfunction generateFileReferences(fontFilePath, fileFormats, formatHint) {\n if (isDataURI(fontFilePath)) {\n return \"url(\\\"\" + fontFilePath + \"\\\")\" + generateFormatHint(fileFormats[0], formatHint);\n }\n var fileFontReferences = fileFormats.map(function (format) {\n return \"url(\\\"\" + fontFilePath + \".\" + format + \"\\\")\" + generateFormatHint(format, formatHint);\n });\n return fileFontReferences.join(', ');\n}\nfunction generateLocalReferences(localFonts) {\n var localFontReferences = localFonts.map(function (font) {\n return \"local(\\\"\" + font + \"\\\")\";\n });\n return localFontReferences.join(', ');\n}\nfunction generateSources(fontFilePath, localFonts, fileFormats, formatHint) {\n var fontReferences = [];\n if (localFonts) fontReferences.push(generateLocalReferences(localFonts));\n if (fontFilePath) {\n fontReferences.push(generateFileReferences(fontFilePath, fileFormats, formatHint));\n }\n return fontReferences.join(', ');\n}\n\n/**\n * CSS for a @font-face declaration. Defaults to check for local copies of the font on the user's machine. You can disable this by passing `null` to localFonts.\n *\n * @example\n * // Styles as object basic usage\n * const styles = {\n * ...fontFace({\n * 'fontFamily': 'Sans-Pro',\n * 'fontFilePath': 'path/to/file'\n * })\n * }\n *\n * // styled-components basic usage\n * const GlobalStyle = createGlobalStyle`${\n * fontFace({\n * 'fontFamily': 'Sans-Pro',\n * 'fontFilePath': 'path/to/file'\n * }\n * )}`\n *\n * // CSS as JS Output\n *\n * '@font-face': {\n * 'fontFamily': 'Sans-Pro',\n * 'src': 'url(\"path/to/file.eot\"), url(\"path/to/file.woff2\"), url(\"path/to/file.woff\"), url(\"path/to/file.ttf\"), url(\"path/to/file.svg\")',\n * }\n */\n\nfunction fontFace(_ref) {\n var fontFamily = _ref.fontFamily,\n fontFilePath = _ref.fontFilePath,\n fontStretch = _ref.fontStretch,\n fontStyle = _ref.fontStyle,\n fontVariant = _ref.fontVariant,\n fontWeight = _ref.fontWeight,\n _ref$fileFormats = _ref.fileFormats,\n fileFormats = _ref$fileFormats === void 0 ? ['eot', 'woff2', 'woff', 'ttf', 'svg'] : _ref$fileFormats,\n _ref$formatHint = _ref.formatHint,\n formatHint = _ref$formatHint === void 0 ? false : _ref$formatHint,\n _ref$localFonts = _ref.localFonts,\n localFonts = _ref$localFonts === void 0 ? [fontFamily] : _ref$localFonts,\n unicodeRange = _ref.unicodeRange,\n fontDisplay = _ref.fontDisplay,\n fontVariationSettings = _ref.fontVariationSettings,\n fontFeatureSettings = _ref.fontFeatureSettings;\n // Error Handling\n if (!fontFamily) throw new PolishedError(55);\n if (!fontFilePath && !localFonts) {\n throw new PolishedError(52);\n }\n if (localFonts && !Array.isArray(localFonts)) {\n throw new PolishedError(53);\n }\n if (!Array.isArray(fileFormats)) {\n throw new PolishedError(54);\n }\n var fontFaceDeclaration = {\n '@font-face': {\n fontFamily: fontFamily,\n src: generateSources(fontFilePath, localFonts, fileFormats, formatHint),\n unicodeRange: unicodeRange,\n fontStretch: fontStretch,\n fontStyle: fontStyle,\n fontVariant: fontVariant,\n fontWeight: fontWeight,\n fontDisplay: fontDisplay,\n fontVariationSettings: fontVariationSettings,\n fontFeatureSettings: fontFeatureSettings\n }\n };\n\n // Removes undefined fields for cleaner css object.\n return JSON.parse(JSON.stringify(fontFaceDeclaration));\n}\n\n/**\n * CSS to hide text to show a background image in a SEO-friendly way.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'backgroundImage': 'url(logo.png)',\n * ...hideText(),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * backgroundImage: url(logo.png);\n * ${hideText()};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'backgroundImage': 'url(logo.png)',\n * 'textIndent': '101%',\n * 'overflow': 'hidden',\n * 'whiteSpace': 'nowrap',\n * }\n */\nfunction hideText() {\n return {\n textIndent: '101%',\n overflow: 'hidden',\n whiteSpace: 'nowrap'\n };\n}\n\n/**\n * CSS to hide content visually but remain accessible to screen readers.\n * from [HTML5 Boilerplate](https://github.com/h5bp/html5-boilerplate/blob/9a176f57af1cfe8ec70300da4621fb9b07e5fa31/src/css/main.css#L121)\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...hideVisually(),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${hideVisually()};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'border': '0',\n * 'clip': 'rect(0 0 0 0)',\n * 'height': '1px',\n * 'margin': '-1px',\n * 'overflow': 'hidden',\n * 'padding': '0',\n * 'position': 'absolute',\n * 'whiteSpace': 'nowrap',\n * 'width': '1px',\n * }\n */\nfunction hideVisually() {\n return {\n border: '0',\n clip: 'rect(0 0 0 0)',\n height: '1px',\n margin: '-1px',\n overflow: 'hidden',\n padding: '0',\n position: 'absolute',\n whiteSpace: 'nowrap',\n width: '1px'\n };\n}\n\n/**\n * Generates a media query to target HiDPI devices.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * [hiDPI(1.5)]: {\n * width: 200px;\n * }\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${hiDPI(1.5)} {\n * width: 200px;\n * }\n * `\n *\n * // CSS as JS Output\n *\n * '@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n * only screen and (min--moz-device-pixel-ratio: 1.5),\n * only screen and (-o-min-device-pixel-ratio: 1.5/1),\n * only screen and (min-resolution: 144dpi),\n * only screen and (min-resolution: 1.5dppx)': {\n * 'width': '200px',\n * }\n */\nfunction hiDPI(ratio) {\n if (ratio === void 0) {\n ratio = 1.3;\n }\n return \"\\n @media only screen and (-webkit-min-device-pixel-ratio: \" + ratio + \"),\\n only screen and (min--moz-device-pixel-ratio: \" + ratio + \"),\\n only screen and (-o-min-device-pixel-ratio: \" + ratio + \"/1),\\n only screen and (min-resolution: \" + Math.round(ratio * 96) + \"dpi),\\n only screen and (min-resolution: \" + ratio + \"dppx)\\n \";\n}\n\nfunction constructGradientValue(literals) {\n var template = '';\n for (var _len = arguments.length, substitutions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n substitutions[_key - 1] = arguments[_key];\n }\n for (var i = 0; i < literals.length; i += 1) {\n template += literals[i];\n if (i === substitutions.length - 1 && substitutions[i]) {\n var definedValues = substitutions.filter(function (substitute) {\n return !!substitute;\n });\n // Adds leading coma if properties preceed color-stops\n if (definedValues.length > 1) {\n template = template.slice(0, -1);\n template += \", \" + substitutions[i];\n // No trailing space if color-stops is the only param provided\n } else if (definedValues.length === 1) {\n template += \"\" + substitutions[i];\n }\n } else if (substitutions[i]) {\n template += substitutions[i] + \" \";\n }\n }\n return template.trim();\n}\n\nvar _templateObject$1;\n/**\n * CSS for declaring a linear gradient, including a fallback background-color. The fallback is either the first color-stop or an explicitly passed fallback color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...linearGradient({\n colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n toDirection: 'to top right',\n fallback: '#FFF',\n })\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${linearGradient({\n colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n toDirection: 'to top right',\n fallback: '#FFF',\n })}\n *`\n *\n * // CSS as JS Output\n *\n * div: {\n * 'backgroundColor': '#FFF',\n * 'backgroundImage': 'linear-gradient(to top right, #00FFFF 0%, rgba(0, 0, 255, 0) 50%, #0000FF 95%)',\n * }\n */\nfunction linearGradient(_ref) {\n var colorStops = _ref.colorStops,\n fallback = _ref.fallback,\n _ref$toDirection = _ref.toDirection,\n toDirection = _ref$toDirection === void 0 ? '' : _ref$toDirection;\n if (!colorStops || colorStops.length < 2) {\n throw new PolishedError(56);\n }\n return {\n backgroundColor: fallback || colorStops[0].replace(/,\\s+/g, ',').split(' ')[0].replace(/,(?=\\S)/g, ', '),\n backgroundImage: constructGradientValue(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteralLoose([\"linear-gradient(\", \"\", \")\"])), toDirection, colorStops.join(', ').replace(/,(?=\\S)/g, ', '))\n };\n}\n\n/**\n * CSS to normalize abnormalities across browsers (normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css)\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...normalize(),\n * }\n *\n * // styled-components usage\n * const GlobalStyle = createGlobalStyle`${normalize()}`\n *\n * // CSS as JS Output\n *\n * html {\n * lineHeight: 1.15,\n * textSizeAdjust: 100%,\n * } ...\n */\nfunction normalize() {\n var _ref;\n return [(_ref = {\n html: {\n lineHeight: '1.15',\n textSizeAdjust: '100%'\n },\n body: {\n margin: '0'\n },\n main: {\n display: 'block'\n },\n h1: {\n fontSize: '2em',\n margin: '0.67em 0'\n },\n hr: {\n boxSizing: 'content-box',\n height: '0',\n overflow: 'visible'\n },\n pre: {\n fontFamily: 'monospace, monospace',\n fontSize: '1em'\n },\n a: {\n backgroundColor: 'transparent'\n },\n 'abbr[title]': {\n borderBottom: 'none',\n textDecoration: 'underline'\n }\n }, _ref[\"b,\\n strong\"] = {\n fontWeight: 'bolder'\n }, _ref[\"code,\\n kbd,\\n samp\"] = {\n fontFamily: 'monospace, monospace',\n fontSize: '1em'\n }, _ref.small = {\n fontSize: '80%'\n }, _ref[\"sub,\\n sup\"] = {\n fontSize: '75%',\n lineHeight: '0',\n position: 'relative',\n verticalAlign: 'baseline'\n }, _ref.sub = {\n bottom: '-0.25em'\n }, _ref.sup = {\n top: '-0.5em'\n }, _ref.img = {\n borderStyle: 'none'\n }, _ref[\"button,\\n input,\\n optgroup,\\n select,\\n textarea\"] = {\n fontFamily: 'inherit',\n fontSize: '100%',\n lineHeight: '1.15',\n margin: '0'\n }, _ref[\"button,\\n input\"] = {\n overflow: 'visible'\n }, _ref[\"button,\\n select\"] = {\n textTransform: 'none'\n }, _ref[\"button,\\n html [type=\\\"button\\\"],\\n [type=\\\"reset\\\"],\\n [type=\\\"submit\\\"]\"] = {\n WebkitAppearance: 'button'\n }, _ref[\"button::-moz-focus-inner,\\n [type=\\\"button\\\"]::-moz-focus-inner,\\n [type=\\\"reset\\\"]::-moz-focus-inner,\\n [type=\\\"submit\\\"]::-moz-focus-inner\"] = {\n borderStyle: 'none',\n padding: '0'\n }, _ref[\"button:-moz-focusring,\\n [type=\\\"button\\\"]:-moz-focusring,\\n [type=\\\"reset\\\"]:-moz-focusring,\\n [type=\\\"submit\\\"]:-moz-focusring\"] = {\n outline: '1px dotted ButtonText'\n }, _ref.fieldset = {\n padding: '0.35em 0.625em 0.75em'\n }, _ref.legend = {\n boxSizing: 'border-box',\n color: 'inherit',\n display: 'table',\n maxWidth: '100%',\n padding: '0',\n whiteSpace: 'normal'\n }, _ref.progress = {\n verticalAlign: 'baseline'\n }, _ref.textarea = {\n overflow: 'auto'\n }, _ref[\"[type=\\\"checkbox\\\"],\\n [type=\\\"radio\\\"]\"] = {\n boxSizing: 'border-box',\n padding: '0'\n }, _ref[\"[type=\\\"number\\\"]::-webkit-inner-spin-button,\\n [type=\\\"number\\\"]::-webkit-outer-spin-button\"] = {\n height: 'auto'\n }, _ref['[type=\"search\"]'] = {\n WebkitAppearance: 'textfield',\n outlineOffset: '-2px'\n }, _ref['[type=\"search\"]::-webkit-search-decoration'] = {\n WebkitAppearance: 'none'\n }, _ref['::-webkit-file-upload-button'] = {\n WebkitAppearance: 'button',\n font: 'inherit'\n }, _ref.details = {\n display: 'block'\n }, _ref.summary = {\n display: 'list-item'\n }, _ref.template = {\n display: 'none'\n }, _ref['[hidden]'] = {\n display: 'none'\n }, _ref), {\n 'abbr[title]': {\n textDecoration: 'underline dotted'\n }\n }];\n}\n\nvar _templateObject;\n/**\n * CSS for declaring a radial gradient, including a fallback background-color. The fallback is either the first color-stop or an explicitly passed fallback color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...radialGradient({\n * colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n * extent: 'farthest-corner at 45px 45px',\n * position: 'center',\n * shape: 'ellipse',\n * })\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${radialGradient({\n * colorStops: ['#00FFFF 0%', 'rgba(0, 0, 255, 0) 50%', '#0000FF 95%'],\n * extent: 'farthest-corner at 45px 45px',\n * position: 'center',\n * shape: 'ellipse',\n * })}\n *`\n *\n * // CSS as JS Output\n *\n * div: {\n * 'backgroundColor': '#00FFFF',\n * 'backgroundImage': 'radial-gradient(center ellipse farthest-corner at 45px 45px, #00FFFF 0%, rgba(0, 0, 255, 0) 50%, #0000FF 95%)',\n * }\n */\nfunction radialGradient(_ref) {\n var colorStops = _ref.colorStops,\n _ref$extent = _ref.extent,\n extent = _ref$extent === void 0 ? '' : _ref$extent,\n fallback = _ref.fallback,\n _ref$position = _ref.position,\n position = _ref$position === void 0 ? '' : _ref$position,\n _ref$shape = _ref.shape,\n shape = _ref$shape === void 0 ? '' : _ref$shape;\n if (!colorStops || colorStops.length < 2) {\n throw new PolishedError(57);\n }\n return {\n backgroundColor: fallback || colorStops[0].split(' ')[0],\n backgroundImage: constructGradientValue(_templateObject || (_templateObject = _taggedTemplateLiteralLoose([\"radial-gradient(\", \"\", \"\", \"\", \")\"])), position, shape, extent, colorStops.join(', '))\n };\n}\n\n/**\n * A helper to generate a retina background image and non-retina\n * background image. The retina background image will output to a HiDPI media query. The mixin uses\n * a _2x.png filename suffix by default.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...retinaImage('my-img')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${retinaImage('my-img')}\n * `\n *\n * // CSS as JS Output\n * div {\n * backgroundImage: 'url(my-img.png)',\n * '@media only screen and (-webkit-min-device-pixel-ratio: 1.3),\n * only screen and (min--moz-device-pixel-ratio: 1.3),\n * only screen and (-o-min-device-pixel-ratio: 1.3/1),\n * only screen and (min-resolution: 144dpi),\n * only screen and (min-resolution: 1.5dppx)': {\n * backgroundImage: 'url(my-img_2x.png)',\n * }\n * }\n */\nfunction retinaImage(filename, backgroundSize, extension, retinaFilename, retinaSuffix) {\n var _ref;\n if (extension === void 0) {\n extension = 'png';\n }\n if (retinaSuffix === void 0) {\n retinaSuffix = '_2x';\n }\n if (!filename) {\n throw new PolishedError(58);\n }\n // Replace the dot at the beginning of the passed extension if one exists\n var ext = extension.replace(/^\\./, '');\n var rFilename = retinaFilename ? retinaFilename + \".\" + ext : \"\" + filename + retinaSuffix + \".\" + ext;\n return _ref = {\n backgroundImage: \"url(\" + filename + \".\" + ext + \")\"\n }, _ref[hiDPI()] = _extends({\n backgroundImage: \"url(\" + rFilename + \")\"\n }, backgroundSize ? {\n backgroundSize: backgroundSize\n } : {}), _ref;\n}\n\n/* eslint-disable key-spacing */\nvar functionsMap = {\n easeInBack: 'cubic-bezier(0.600, -0.280, 0.735, 0.045)',\n easeInCirc: 'cubic-bezier(0.600, 0.040, 0.980, 0.335)',\n easeInCubic: 'cubic-bezier(0.550, 0.055, 0.675, 0.190)',\n easeInExpo: 'cubic-bezier(0.950, 0.050, 0.795, 0.035)',\n easeInQuad: 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n easeInQuart: 'cubic-bezier(0.895, 0.030, 0.685, 0.220)',\n easeInQuint: 'cubic-bezier(0.755, 0.050, 0.855, 0.060)',\n easeInSine: 'cubic-bezier(0.470, 0.000, 0.745, 0.715)',\n easeOutBack: 'cubic-bezier(0.175, 0.885, 0.320, 1.275)',\n easeOutCubic: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',\n easeOutCirc: 'cubic-bezier(0.075, 0.820, 0.165, 1.000)',\n easeOutExpo: 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',\n easeOutQuad: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',\n easeOutQuart: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)',\n easeOutQuint: 'cubic-bezier(0.230, 1.000, 0.320, 1.000)',\n easeOutSine: 'cubic-bezier(0.390, 0.575, 0.565, 1.000)',\n easeInOutBack: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)',\n easeInOutCirc: 'cubic-bezier(0.785, 0.135, 0.150, 0.860)',\n easeInOutCubic: 'cubic-bezier(0.645, 0.045, 0.355, 1.000)',\n easeInOutExpo: 'cubic-bezier(1.000, 0.000, 0.000, 1.000)',\n easeInOutQuad: 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',\n easeInOutQuart: 'cubic-bezier(0.770, 0.000, 0.175, 1.000)',\n easeInOutQuint: 'cubic-bezier(0.860, 0.000, 0.070, 1.000)',\n easeInOutSine: 'cubic-bezier(0.445, 0.050, 0.550, 0.950)'\n};\n/* eslint-enable key-spacing */\n\nfunction getTimingFunction(functionName) {\n return functionsMap[functionName];\n}\n\n/**\n * String to represent common easing functions as demonstrated here: (github.com/jaukia/easie).\n *\n * @deprecated - This will be deprecated in v5 in favor of `easeIn`, `easeOut`, `easeInOut`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * 'transitionTimingFunction': timingFunctions('easeInQuad')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * transitionTimingFunction: ${timingFunctions('easeInQuad')};\n * `\n *\n * // CSS as JS Output\n *\n * 'div': {\n * 'transitionTimingFunction': 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n * }\n */\n\nfunction timingFunctions(timingFunction) {\n return getTimingFunction(timingFunction);\n}\n\nvar getBorderWidth = function getBorderWidth(pointingDirection, height, width) {\n var fullWidth = \"\" + width[0] + (width[1] || '');\n var halfWidth = \"\" + width[0] / 2 + (width[1] || '');\n var fullHeight = \"\" + height[0] + (height[1] || '');\n var halfHeight = \"\" + height[0] / 2 + (height[1] || '');\n switch (pointingDirection) {\n case 'top':\n return \"0 \" + halfWidth + \" \" + fullHeight + \" \" + halfWidth;\n case 'topLeft':\n return fullWidth + \" \" + fullHeight + \" 0 0\";\n case 'left':\n return halfHeight + \" \" + fullWidth + \" \" + halfHeight + \" 0\";\n case 'bottomLeft':\n return fullWidth + \" 0 0 \" + fullHeight;\n case 'bottom':\n return fullHeight + \" \" + halfWidth + \" 0 \" + halfWidth;\n case 'bottomRight':\n return \"0 0 \" + fullWidth + \" \" + fullHeight;\n case 'right':\n return halfHeight + \" 0 \" + halfHeight + \" \" + fullWidth;\n case 'topRight':\n default:\n return \"0 \" + fullWidth + \" \" + fullHeight + \" 0\";\n }\n};\nvar getBorderColor = function getBorderColor(pointingDirection, foregroundColor) {\n switch (pointingDirection) {\n case 'top':\n case 'bottomRight':\n return {\n borderBottomColor: foregroundColor\n };\n case 'right':\n case 'bottomLeft':\n return {\n borderLeftColor: foregroundColor\n };\n case 'bottom':\n case 'topLeft':\n return {\n borderTopColor: foregroundColor\n };\n case 'left':\n case 'topRight':\n return {\n borderRightColor: foregroundColor\n };\n default:\n throw new PolishedError(59);\n }\n};\n\n/**\n * CSS to represent triangle with any pointing direction with an optional background color.\n *\n * @example\n * // Styles as object usage\n *\n * const styles = {\n * ...triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' })\n * }\n *\n *\n * // styled-components usage\n * const div = styled.div`\n * ${triangle({ pointingDirection: 'right', width: '100px', height: '100px', foregroundColor: 'red' })}\n *\n *\n * // CSS as JS Output\n *\n * div: {\n * 'borderColor': 'transparent transparent transparent red',\n * 'borderStyle': 'solid',\n * 'borderWidth': '50px 0 50px 100px',\n * 'height': '0',\n * 'width': '0',\n * }\n */\nfunction triangle(_ref) {\n var pointingDirection = _ref.pointingDirection,\n height = _ref.height,\n width = _ref.width,\n foregroundColor = _ref.foregroundColor,\n _ref$backgroundColor = _ref.backgroundColor,\n backgroundColor = _ref$backgroundColor === void 0 ? 'transparent' : _ref$backgroundColor;\n var widthAndUnit = getValueAndUnit(width);\n var heightAndUnit = getValueAndUnit(height);\n if (isNaN(heightAndUnit[0]) || isNaN(widthAndUnit[0])) {\n throw new PolishedError(60);\n }\n return _extends({\n width: '0',\n height: '0',\n borderColor: backgroundColor\n }, getBorderColor(pointingDirection, foregroundColor), {\n borderStyle: 'solid',\n borderWidth: getBorderWidth(pointingDirection, heightAndUnit, widthAndUnit)\n });\n}\n\n/**\n * Provides an easy way to change the `wordWrap` property.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...wordWrap('break-word')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${wordWrap('break-word')}\n * `\n *\n * // CSS as JS Output\n *\n * const styles = {\n * overflowWrap: 'break-word',\n * wordWrap: 'break-word',\n * wordBreak: 'break-all',\n * }\n */\nfunction wordWrap(wrap) {\n if (wrap === void 0) {\n wrap = 'break-word';\n }\n var wordBreak = wrap === 'break-word' ? 'break-all' : wrap;\n return {\n overflowWrap: wrap,\n wordWrap: wrap,\n wordBreak: wordBreak\n };\n}\n\nfunction colorToInt(color) {\n return Math.round(color * 255);\n}\nfunction convertToInt(red, green, blue) {\n return colorToInt(red) + \",\" + colorToInt(green) + \",\" + colorToInt(blue);\n}\nfunction hslToRgb(hue, saturation, lightness, convert) {\n if (convert === void 0) {\n convert = convertToInt;\n }\n if (saturation === 0) {\n // achromatic\n return convert(lightness, lightness, lightness);\n }\n\n // formulae from https://en.wikipedia.org/wiki/HSL_and_HSV\n var huePrime = (hue % 360 + 360) % 360 / 60;\n var chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;\n var secondComponent = chroma * (1 - Math.abs(huePrime % 2 - 1));\n var red = 0;\n var green = 0;\n var blue = 0;\n if (huePrime >= 0 && huePrime < 1) {\n red = chroma;\n green = secondComponent;\n } else if (huePrime >= 1 && huePrime < 2) {\n red = secondComponent;\n green = chroma;\n } else if (huePrime >= 2 && huePrime < 3) {\n green = chroma;\n blue = secondComponent;\n } else if (huePrime >= 3 && huePrime < 4) {\n green = secondComponent;\n blue = chroma;\n } else if (huePrime >= 4 && huePrime < 5) {\n red = secondComponent;\n blue = chroma;\n } else if (huePrime >= 5 && huePrime < 6) {\n red = chroma;\n blue = secondComponent;\n }\n var lightnessModification = lightness - chroma / 2;\n var finalRed = red + lightnessModification;\n var finalGreen = green + lightnessModification;\n var finalBlue = blue + lightnessModification;\n return convert(finalRed, finalGreen, finalBlue);\n}\n\nvar namedColorMap = {\n aliceblue: 'f0f8ff',\n antiquewhite: 'faebd7',\n aqua: '00ffff',\n aquamarine: '7fffd4',\n azure: 'f0ffff',\n beige: 'f5f5dc',\n bisque: 'ffe4c4',\n black: '000',\n blanchedalmond: 'ffebcd',\n blue: '0000ff',\n blueviolet: '8a2be2',\n brown: 'a52a2a',\n burlywood: 'deb887',\n cadetblue: '5f9ea0',\n chartreuse: '7fff00',\n chocolate: 'd2691e',\n coral: 'ff7f50',\n cornflowerblue: '6495ed',\n cornsilk: 'fff8dc',\n crimson: 'dc143c',\n cyan: '00ffff',\n darkblue: '00008b',\n darkcyan: '008b8b',\n darkgoldenrod: 'b8860b',\n darkgray: 'a9a9a9',\n darkgreen: '006400',\n darkgrey: 'a9a9a9',\n darkkhaki: 'bdb76b',\n darkmagenta: '8b008b',\n darkolivegreen: '556b2f',\n darkorange: 'ff8c00',\n darkorchid: '9932cc',\n darkred: '8b0000',\n darksalmon: 'e9967a',\n darkseagreen: '8fbc8f',\n darkslateblue: '483d8b',\n darkslategray: '2f4f4f',\n darkslategrey: '2f4f4f',\n darkturquoise: '00ced1',\n darkviolet: '9400d3',\n deeppink: 'ff1493',\n deepskyblue: '00bfff',\n dimgray: '696969',\n dimgrey: '696969',\n dodgerblue: '1e90ff',\n firebrick: 'b22222',\n floralwhite: 'fffaf0',\n forestgreen: '228b22',\n fuchsia: 'ff00ff',\n gainsboro: 'dcdcdc',\n ghostwhite: 'f8f8ff',\n gold: 'ffd700',\n goldenrod: 'daa520',\n gray: '808080',\n green: '008000',\n greenyellow: 'adff2f',\n grey: '808080',\n honeydew: 'f0fff0',\n hotpink: 'ff69b4',\n indianred: 'cd5c5c',\n indigo: '4b0082',\n ivory: 'fffff0',\n khaki: 'f0e68c',\n lavender: 'e6e6fa',\n lavenderblush: 'fff0f5',\n lawngreen: '7cfc00',\n lemonchiffon: 'fffacd',\n lightblue: 'add8e6',\n lightcoral: 'f08080',\n lightcyan: 'e0ffff',\n lightgoldenrodyellow: 'fafad2',\n lightgray: 'd3d3d3',\n lightgreen: '90ee90',\n lightgrey: 'd3d3d3',\n lightpink: 'ffb6c1',\n lightsalmon: 'ffa07a',\n lightseagreen: '20b2aa',\n lightskyblue: '87cefa',\n lightslategray: '789',\n lightslategrey: '789',\n lightsteelblue: 'b0c4de',\n lightyellow: 'ffffe0',\n lime: '0f0',\n limegreen: '32cd32',\n linen: 'faf0e6',\n magenta: 'f0f',\n maroon: '800000',\n mediumaquamarine: '66cdaa',\n mediumblue: '0000cd',\n mediumorchid: 'ba55d3',\n mediumpurple: '9370db',\n mediumseagreen: '3cb371',\n mediumslateblue: '7b68ee',\n mediumspringgreen: '00fa9a',\n mediumturquoise: '48d1cc',\n mediumvioletred: 'c71585',\n midnightblue: '191970',\n mintcream: 'f5fffa',\n mistyrose: 'ffe4e1',\n moccasin: 'ffe4b5',\n navajowhite: 'ffdead',\n navy: '000080',\n oldlace: 'fdf5e6',\n olive: '808000',\n olivedrab: '6b8e23',\n orange: 'ffa500',\n orangered: 'ff4500',\n orchid: 'da70d6',\n palegoldenrod: 'eee8aa',\n palegreen: '98fb98',\n paleturquoise: 'afeeee',\n palevioletred: 'db7093',\n papayawhip: 'ffefd5',\n peachpuff: 'ffdab9',\n peru: 'cd853f',\n pink: 'ffc0cb',\n plum: 'dda0dd',\n powderblue: 'b0e0e6',\n purple: '800080',\n rebeccapurple: '639',\n red: 'f00',\n rosybrown: 'bc8f8f',\n royalblue: '4169e1',\n saddlebrown: '8b4513',\n salmon: 'fa8072',\n sandybrown: 'f4a460',\n seagreen: '2e8b57',\n seashell: 'fff5ee',\n sienna: 'a0522d',\n silver: 'c0c0c0',\n skyblue: '87ceeb',\n slateblue: '6a5acd',\n slategray: '708090',\n slategrey: '708090',\n snow: 'fffafa',\n springgreen: '00ff7f',\n steelblue: '4682b4',\n tan: 'd2b48c',\n teal: '008080',\n thistle: 'd8bfd8',\n tomato: 'ff6347',\n turquoise: '40e0d0',\n violet: 'ee82ee',\n wheat: 'f5deb3',\n white: 'fff',\n whitesmoke: 'f5f5f5',\n yellow: 'ff0',\n yellowgreen: '9acd32'\n};\n\n/**\n * Checks if a string is a CSS named color and returns its equivalent hex value, otherwise returns the original color.\n * @private\n */\nfunction nameToHex(color) {\n if (typeof color !== 'string') return color;\n var normalizedColorName = color.toLowerCase();\n return namedColorMap[normalizedColorName] ? \"#\" + namedColorMap[normalizedColorName] : color;\n}\n\nvar hexRegex = /^#[a-fA-F0-9]{6}$/;\nvar hexRgbaRegex = /^#[a-fA-F0-9]{8}$/;\nvar reducedHexRegex = /^#[a-fA-F0-9]{3}$/;\nvar reducedRgbaHexRegex = /^#[a-fA-F0-9]{4}$/;\nvar rgbRegex = /^rgb\\(\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*\\)$/i;\nvar rgbaRegex = /^rgb(?:a)?\\(\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*(?:,)?\\s*(\\d{1,3})\\s*(?:,|\\/)\\s*([-+]?\\d*[.]?\\d+[%]?)\\s*\\)$/i;\nvar hslRegex = /^hsl\\(\\s*(\\d{0,3}[.]?[0-9]+(?:deg)?)\\s*(?:,)?\\s*(\\d{1,3}[.]?[0-9]?)%\\s*(?:,)?\\s*(\\d{1,3}[.]?[0-9]?)%\\s*\\)$/i;\nvar hslaRegex = /^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;\n\n/**\n * Returns an RgbColor or RgbaColor object. This utility function is only useful\n * if want to extract a color component. With the color util `toColorString` you\n * can convert a RgbColor or RgbaColor object back to a string.\n *\n * @example\n * // Assigns `{ red: 255, green: 0, blue: 0 }` to color1\n * const color1 = parseToRgb('rgb(255, 0, 0)');\n * // Assigns `{ red: 92, green: 102, blue: 112, alpha: 0.75 }` to color2\n * const color2 = parseToRgb('hsla(210, 10%, 40%, 0.75)');\n */\nfunction parseToRgb(color) {\n if (typeof color !== 'string') {\n throw new PolishedError(3);\n }\n var normalizedColor = nameToHex(color);\n if (normalizedColor.match(hexRegex)) {\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[2], 16),\n green: parseInt(\"\" + normalizedColor[3] + normalizedColor[4], 16),\n blue: parseInt(\"\" + normalizedColor[5] + normalizedColor[6], 16)\n };\n }\n if (normalizedColor.match(hexRgbaRegex)) {\n var alpha = parseFloat((parseInt(\"\" + normalizedColor[7] + normalizedColor[8], 16) / 255).toFixed(2));\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[2], 16),\n green: parseInt(\"\" + normalizedColor[3] + normalizedColor[4], 16),\n blue: parseInt(\"\" + normalizedColor[5] + normalizedColor[6], 16),\n alpha: alpha\n };\n }\n if (normalizedColor.match(reducedHexRegex)) {\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[1], 16),\n green: parseInt(\"\" + normalizedColor[2] + normalizedColor[2], 16),\n blue: parseInt(\"\" + normalizedColor[3] + normalizedColor[3], 16)\n };\n }\n if (normalizedColor.match(reducedRgbaHexRegex)) {\n var _alpha = parseFloat((parseInt(\"\" + normalizedColor[4] + normalizedColor[4], 16) / 255).toFixed(2));\n return {\n red: parseInt(\"\" + normalizedColor[1] + normalizedColor[1], 16),\n green: parseInt(\"\" + normalizedColor[2] + normalizedColor[2], 16),\n blue: parseInt(\"\" + normalizedColor[3] + normalizedColor[3], 16),\n alpha: _alpha\n };\n }\n var rgbMatched = rgbRegex.exec(normalizedColor);\n if (rgbMatched) {\n return {\n red: parseInt(\"\" + rgbMatched[1], 10),\n green: parseInt(\"\" + rgbMatched[2], 10),\n blue: parseInt(\"\" + rgbMatched[3], 10)\n };\n }\n var rgbaMatched = rgbaRegex.exec(normalizedColor.substring(0, 50));\n if (rgbaMatched) {\n return {\n red: parseInt(\"\" + rgbaMatched[1], 10),\n green: parseInt(\"\" + rgbaMatched[2], 10),\n blue: parseInt(\"\" + rgbaMatched[3], 10),\n alpha: parseFloat(\"\" + rgbaMatched[4]) > 1 ? parseFloat(\"\" + rgbaMatched[4]) / 100 : parseFloat(\"\" + rgbaMatched[4])\n };\n }\n var hslMatched = hslRegex.exec(normalizedColor);\n if (hslMatched) {\n var hue = parseInt(\"\" + hslMatched[1], 10);\n var saturation = parseInt(\"\" + hslMatched[2], 10) / 100;\n var lightness = parseInt(\"\" + hslMatched[3], 10) / 100;\n var rgbColorString = \"rgb(\" + hslToRgb(hue, saturation, lightness) + \")\";\n var hslRgbMatched = rgbRegex.exec(rgbColorString);\n if (!hslRgbMatched) {\n throw new PolishedError(4, normalizedColor, rgbColorString);\n }\n return {\n red: parseInt(\"\" + hslRgbMatched[1], 10),\n green: parseInt(\"\" + hslRgbMatched[2], 10),\n blue: parseInt(\"\" + hslRgbMatched[3], 10)\n };\n }\n var hslaMatched = hslaRegex.exec(normalizedColor.substring(0, 50));\n if (hslaMatched) {\n var _hue = parseInt(\"\" + hslaMatched[1], 10);\n var _saturation = parseInt(\"\" + hslaMatched[2], 10) / 100;\n var _lightness = parseInt(\"\" + hslaMatched[3], 10) / 100;\n var _rgbColorString = \"rgb(\" + hslToRgb(_hue, _saturation, _lightness) + \")\";\n var _hslRgbMatched = rgbRegex.exec(_rgbColorString);\n if (!_hslRgbMatched) {\n throw new PolishedError(4, normalizedColor, _rgbColorString);\n }\n return {\n red: parseInt(\"\" + _hslRgbMatched[1], 10),\n green: parseInt(\"\" + _hslRgbMatched[2], 10),\n blue: parseInt(\"\" + _hslRgbMatched[3], 10),\n alpha: parseFloat(\"\" + hslaMatched[4]) > 1 ? parseFloat(\"\" + hslaMatched[4]) / 100 : parseFloat(\"\" + hslaMatched[4])\n };\n }\n throw new PolishedError(5);\n}\n\nfunction rgbToHsl(color) {\n // make sure rgb are contained in a set of [0, 255]\n var red = color.red / 255;\n var green = color.green / 255;\n var blue = color.blue / 255;\n var max = Math.max(red, green, blue);\n var min = Math.min(red, green, blue);\n var lightness = (max + min) / 2;\n if (max === min) {\n // achromatic\n if (color.alpha !== undefined) {\n return {\n hue: 0,\n saturation: 0,\n lightness: lightness,\n alpha: color.alpha\n };\n } else {\n return {\n hue: 0,\n saturation: 0,\n lightness: lightness\n };\n }\n }\n var hue;\n var delta = max - min;\n var saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n switch (max) {\n case red:\n hue = (green - blue) / delta + (green < blue ? 6 : 0);\n break;\n case green:\n hue = (blue - red) / delta + 2;\n break;\n default:\n // blue case\n hue = (red - green) / delta + 4;\n break;\n }\n hue *= 60;\n if (color.alpha !== undefined) {\n return {\n hue: hue,\n saturation: saturation,\n lightness: lightness,\n alpha: color.alpha\n };\n }\n return {\n hue: hue,\n saturation: saturation,\n lightness: lightness\n };\n}\n\n/**\n * Returns an HslColor or HslaColor object. This utility function is only useful\n * if want to extract a color component. With the color util `toColorString` you\n * can convert a HslColor or HslaColor object back to a string.\n *\n * @example\n * // Assigns `{ hue: 0, saturation: 1, lightness: 0.5 }` to color1\n * const color1 = parseToHsl('rgb(255, 0, 0)');\n * // Assigns `{ hue: 128, saturation: 1, lightness: 0.5, alpha: 0.75 }` to color2\n * const color2 = parseToHsl('hsla(128, 100%, 50%, 0.75)');\n */\nfunction parseToHsl(color) {\n // Note: At a later stage we can optimize this function as right now a hsl\n // color would be parsed converted to rgb values and converted back to hsl.\n return rgbToHsl(parseToRgb(color));\n}\n\n/**\n * Reduces hex values if possible e.g. #ff8866 to #f86\n * @private\n */\nvar reduceHexValue = function reduceHexValue(value) {\n if (value.length === 7 && value[1] === value[2] && value[3] === value[4] && value[5] === value[6]) {\n return \"#\" + value[1] + value[3] + value[5];\n }\n return value;\n};\nvar reduceHexValue$1 = reduceHexValue;\n\nfunction numberToHex(value) {\n var hex = value.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n}\n\nfunction colorToHex(color) {\n return numberToHex(Math.round(color * 255));\n}\nfunction convertToHex(red, green, blue) {\n return reduceHexValue$1(\"#\" + colorToHex(red) + colorToHex(green) + colorToHex(blue));\n}\nfunction hslToHex(hue, saturation, lightness) {\n return hslToRgb(hue, saturation, lightness, convertToHex);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible hex notation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: hsl(359, 0.75, 0.4),\n * background: hsl({ hue: 360, saturation: 0.75, lightness: 0.4 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${hsl(359, 0.75, 0.4)};\n * background: ${hsl({ hue: 360, saturation: 0.75, lightness: 0.4 })};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#b3191c\";\n * background: \"#b3191c\";\n * }\n */\nfunction hsl(value, saturation, lightness) {\n if (typeof value === 'number' && typeof saturation === 'number' && typeof lightness === 'number') {\n return hslToHex(value, saturation, lightness);\n } else if (typeof value === 'object' && saturation === undefined && lightness === undefined) {\n return hslToHex(value.hue, value.saturation, value.lightness);\n }\n throw new PolishedError(1);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible rgba or hex notation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: hsla(359, 0.75, 0.4, 0.7),\n * background: hsla({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0,7 }),\n * background: hsla(359, 0.75, 0.4, 1),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${hsla(359, 0.75, 0.4, 0.7)};\n * background: ${hsla({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0,7 })};\n * background: ${hsla(359, 0.75, 0.4, 1)};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"rgba(179,25,28,0.7)\";\n * background: \"rgba(179,25,28,0.7)\";\n * background: \"#b3191c\";\n * }\n */\nfunction hsla(value, saturation, lightness, alpha) {\n if (typeof value === 'number' && typeof saturation === 'number' && typeof lightness === 'number' && typeof alpha === 'number') {\n return alpha >= 1 ? hslToHex(value, saturation, lightness) : \"rgba(\" + hslToRgb(value, saturation, lightness) + \",\" + alpha + \")\";\n } else if (typeof value === 'object' && saturation === undefined && lightness === undefined && alpha === undefined) {\n return value.alpha >= 1 ? hslToHex(value.hue, value.saturation, value.lightness) : \"rgba(\" + hslToRgb(value.hue, value.saturation, value.lightness) + \",\" + value.alpha + \")\";\n }\n throw new PolishedError(2);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible hex notation.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: rgb(255, 205, 100),\n * background: rgb({ red: 255, green: 205, blue: 100 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${rgb(255, 205, 100)};\n * background: ${rgb({ red: 255, green: 205, blue: 100 })};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#ffcd64\";\n * background: \"#ffcd64\";\n * }\n */\nfunction rgb(value, green, blue) {\n if (typeof value === 'number' && typeof green === 'number' && typeof blue === 'number') {\n return reduceHexValue$1(\"#\" + numberToHex(value) + numberToHex(green) + numberToHex(blue));\n } else if (typeof value === 'object' && green === undefined && blue === undefined) {\n return reduceHexValue$1(\"#\" + numberToHex(value.red) + numberToHex(value.green) + numberToHex(value.blue));\n }\n throw new PolishedError(6);\n}\n\n/**\n * Returns a string value for the color. The returned result is the smallest possible rgba or hex notation.\n *\n * Can also be used to fade a color by passing a hex value or named CSS color along with an alpha value.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: rgba(255, 205, 100, 0.7),\n * background: rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 }),\n * background: rgba(255, 205, 100, 1),\n * background: rgba('#ffffff', 0.4),\n * background: rgba('black', 0.7),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${rgba(255, 205, 100, 0.7)};\n * background: ${rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 })};\n * background: ${rgba(255, 205, 100, 1)};\n * background: ${rgba('#ffffff', 0.4)};\n * background: ${rgba('black', 0.7)};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"rgba(255,205,100,0.7)\";\n * background: \"rgba(255,205,100,0.7)\";\n * background: \"#ffcd64\";\n * background: \"rgba(255,255,255,0.4)\";\n * background: \"rgba(0,0,0,0.7)\";\n * }\n */\nfunction rgba(firstValue, secondValue, thirdValue, fourthValue) {\n if (typeof firstValue === 'string' && typeof secondValue === 'number') {\n var rgbValue = parseToRgb(firstValue);\n return \"rgba(\" + rgbValue.red + \",\" + rgbValue.green + \",\" + rgbValue.blue + \",\" + secondValue + \")\";\n } else if (typeof firstValue === 'number' && typeof secondValue === 'number' && typeof thirdValue === 'number' && typeof fourthValue === 'number') {\n return fourthValue >= 1 ? rgb(firstValue, secondValue, thirdValue) : \"rgba(\" + firstValue + \",\" + secondValue + \",\" + thirdValue + \",\" + fourthValue + \")\";\n } else if (typeof firstValue === 'object' && secondValue === undefined && thirdValue === undefined && fourthValue === undefined) {\n return firstValue.alpha >= 1 ? rgb(firstValue.red, firstValue.green, firstValue.blue) : \"rgba(\" + firstValue.red + \",\" + firstValue.green + \",\" + firstValue.blue + \",\" + firstValue.alpha + \")\";\n }\n throw new PolishedError(7);\n}\n\nvar isRgb = function isRgb(color) {\n return typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number' && (typeof color.alpha !== 'number' || typeof color.alpha === 'undefined');\n};\nvar isRgba = function isRgba(color) {\n return typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number' && typeof color.alpha === 'number';\n};\nvar isHsl = function isHsl(color) {\n return typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number' && (typeof color.alpha !== 'number' || typeof color.alpha === 'undefined');\n};\nvar isHsla = function isHsla(color) {\n return typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number' && typeof color.alpha === 'number';\n};\n\n/**\n * Converts a RgbColor, RgbaColor, HslColor or HslaColor object to a color string.\n * This util is useful in case you only know on runtime which color object is\n * used. Otherwise we recommend to rely on `rgb`, `rgba`, `hsl` or `hsla`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: toColorString({ red: 255, green: 205, blue: 100 }),\n * background: toColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 }),\n * background: toColorString({ hue: 240, saturation: 1, lightness: 0.5 }),\n * background: toColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${toColorString({ red: 255, green: 205, blue: 100 })};\n * background: ${toColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 })};\n * background: ${toColorString({ hue: 240, saturation: 1, lightness: 0.5 })};\n * background: ${toColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 })};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#ffcd64\";\n * background: \"rgba(255,205,100,0.72)\";\n * background: \"#00f\";\n * background: \"rgba(179,25,25,0.72)\";\n * }\n */\n\nfunction toColorString(color) {\n if (typeof color !== 'object') throw new PolishedError(8);\n if (isRgba(color)) return rgba(color);\n if (isRgb(color)) return rgb(color);\n if (isHsla(color)) return hsla(color);\n if (isHsl(color)) return hsl(color);\n throw new PolishedError(8);\n}\n\n// Type definitions taken from https://github.com/gcanti/flow-static-land/blob/master/src/Fun.js\n// eslint-disable-next-line no-unused-vars\n// eslint-disable-next-line no-unused-vars\n// eslint-disable-next-line no-redeclare\nfunction curried(f, length, acc) {\n return function fn() {\n // eslint-disable-next-line prefer-rest-params\n var combined = acc.concat(Array.prototype.slice.call(arguments));\n return combined.length >= length ? f.apply(this, combined) : curried(f, length, combined);\n };\n}\n\n// eslint-disable-next-line no-redeclare\nfunction curry(f) {\n // eslint-disable-line no-redeclare\n return curried(f, f.length, []);\n}\n\n/**\n * Changes the hue of the color. Hue is a number between 0 to 360. The first\n * argument for adjustHue is the amount of degrees the color is rotated around\n * the color wheel, always producing a positive hue value.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: adjustHue(180, '#448'),\n * background: adjustHue('180', 'rgba(101,100,205,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${adjustHue(180, '#448')};\n * background: ${adjustHue('180', 'rgba(101,100,205,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#888844\";\n * background: \"rgba(136,136,68,0.7)\";\n * }\n */\nfunction adjustHue(degree, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n hue: hslColor.hue + parseFloat(degree)\n }));\n}\n\n// prettier-ignore\nvar curriedAdjustHue = curry /* ::<number | string, string, string> */(adjustHue);\nvar curriedAdjustHue$1 = curriedAdjustHue;\n\n/**\n * Returns the complement of the provided color. This is identical to adjustHue(180, <color>).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: complement('#448'),\n * background: complement('rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${complement('#448')};\n * background: ${complement('rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#884\";\n * background: \"rgba(153,153,153,0.7)\";\n * }\n */\nfunction complement(color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n hue: (hslColor.hue + 180) % 360\n }));\n}\n\nfunction guard(lowerBoundary, upperBoundary, value) {\n return Math.max(lowerBoundary, Math.min(upperBoundary, value));\n}\n\n/**\n * Returns a string value for the darkened color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: darken(0.2, '#FFCD64'),\n * background: darken('0.2', 'rgba(255,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${darken(0.2, '#FFCD64')};\n * background: ${darken('0.2', 'rgba(255,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#ffbd31\";\n * background: \"rgba(255,189,49,0.7)\";\n * }\n */\nfunction darken(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n lightness: guard(0, 1, hslColor.lightness - parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedDarken = curry /* ::<number | string, string, string> */(darken);\nvar curriedDarken$1 = curriedDarken;\n\n/**\n * Decreases the intensity of a color. Its range is between 0 to 1. The first\n * argument of the desaturate function is the amount by how much the color\n * intensity should be decreased.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: desaturate(0.2, '#CCCD64'),\n * background: desaturate('0.2', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${desaturate(0.2, '#CCCD64')};\n * background: ${desaturate('0.2', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#b8b979\";\n * background: \"rgba(184,185,121,0.7)\";\n * }\n */\nfunction desaturate(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n saturation: guard(0, 1, hslColor.saturation - parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedDesaturate = curry /* ::<number | string, string, string> */(desaturate);\nvar curriedDesaturate$1 = curriedDesaturate;\n\n/**\n * Returns a number (float) representing the luminance of a color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: getLuminance('#CCCD64') >= getLuminance('#0000ff') ? '#CCCD64' : '#0000ff',\n * background: getLuminance('rgba(58, 133, 255, 1)') >= getLuminance('rgba(255, 57, 149, 1)') ?\n * 'rgba(58, 133, 255, 1)' :\n * 'rgba(255, 57, 149, 1)',\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${getLuminance('#CCCD64') >= getLuminance('#0000ff') ? '#CCCD64' : '#0000ff'};\n * background: ${getLuminance('rgba(58, 133, 255, 1)') >= getLuminance('rgba(255, 57, 149, 1)') ?\n * 'rgba(58, 133, 255, 1)' :\n * 'rgba(255, 57, 149, 1)'};\n *\n * // CSS in JS Output\n *\n * div {\n * background: \"#CCCD64\";\n * background: \"rgba(58, 133, 255, 1)\";\n * }\n */\nfunction getLuminance(color) {\n if (color === 'transparent') return 0;\n var rgbColor = parseToRgb(color);\n var _Object$keys$map = Object.keys(rgbColor).map(function (key) {\n var channel = rgbColor[key] / 255;\n return channel <= 0.03928 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);\n }),\n r = _Object$keys$map[0],\n g = _Object$keys$map[1],\n b = _Object$keys$map[2];\n return parseFloat((0.2126 * r + 0.7152 * g + 0.0722 * b).toFixed(3));\n}\n\n/**\n * Returns the contrast ratio between two colors based on\n * [W3's recommended equation for calculating contrast](http://www.w3.org/TR/WCAG20/#contrast-ratiodef).\n *\n * @example\n * const contrastRatio = getContrast('#444', '#fff');\n */\nfunction getContrast(color1, color2) {\n var luminance1 = getLuminance(color1);\n var luminance2 = getLuminance(color2);\n return parseFloat((luminance1 > luminance2 ? (luminance1 + 0.05) / (luminance2 + 0.05) : (luminance2 + 0.05) / (luminance1 + 0.05)).toFixed(2));\n}\n\n/**\n * Converts the color to a grayscale, by reducing its saturation to 0.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: grayscale('#CCCD64'),\n * background: grayscale('rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${grayscale('#CCCD64')};\n * background: ${grayscale('rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#999\";\n * background: \"rgba(153,153,153,0.7)\";\n * }\n */\nfunction grayscale(color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n saturation: 0\n }));\n}\n\n/**\n * Converts a HslColor or HslaColor object to a color string.\n * This util is useful in case you only know on runtime which color object is\n * used. Otherwise we recommend to rely on `hsl` or `hsla`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: hslToColorString({ hue: 240, saturation: 1, lightness: 0.5 }),\n * background: hslToColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${hslToColorString({ hue: 240, saturation: 1, lightness: 0.5 })};\n * background: ${hslToColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 })};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#00f\";\n * background: \"rgba(179,25,25,0.72)\";\n * }\n */\nfunction hslToColorString(color) {\n if (typeof color === 'object' && typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number') {\n if (color.alpha && typeof color.alpha === 'number') {\n return hsla({\n hue: color.hue,\n saturation: color.saturation,\n lightness: color.lightness,\n alpha: color.alpha\n });\n }\n return hsl({\n hue: color.hue,\n saturation: color.saturation,\n lightness: color.lightness\n });\n }\n throw new PolishedError(45);\n}\n\n/**\n * Inverts the red, green and blue values of a color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: invert('#CCCD64'),\n * background: invert('rgba(101,100,205,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${invert('#CCCD64')};\n * background: ${invert('rgba(101,100,205,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#33329b\";\n * background: \"rgba(154,155,50,0.7)\";\n * }\n */\nfunction invert(color) {\n if (color === 'transparent') return color;\n // parse color string to rgb\n var value = parseToRgb(color);\n return toColorString(_extends({}, value, {\n red: 255 - value.red,\n green: 255 - value.green,\n blue: 255 - value.blue\n }));\n}\n\n/**\n * Returns a string value for the lightened color.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: lighten(0.2, '#CCCD64'),\n * background: lighten('0.2', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${lighten(0.2, '#FFCD64')};\n * background: ${lighten('0.2', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#e5e6b1\";\n * background: \"rgba(229,230,177,0.7)\";\n * }\n */\nfunction lighten(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n lightness: guard(0, 1, hslColor.lightness + parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedLighten = curry /* ::<number | string, string, string> */(lighten);\nvar curriedLighten$1 = curriedLighten;\n\n/**\n * Determines which contrast guidelines have been met for two colors.\n * Based on the [contrast calculations recommended by W3](https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced.html).\n *\n * @example\n * const scores = meetsContrastGuidelines('#444', '#fff');\n */\nfunction meetsContrastGuidelines(color1, color2) {\n var contrastRatio = getContrast(color1, color2);\n return {\n AA: contrastRatio >= 4.5,\n AALarge: contrastRatio >= 3,\n AAA: contrastRatio >= 7,\n AAALarge: contrastRatio >= 4.5\n };\n}\n\n/**\n * Mixes the two provided colors together by calculating the average of each of the RGB components weighted to the first color by the provided weight.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: mix(0.5, '#f00', '#00f')\n * background: mix(0.25, '#f00', '#00f')\n * background: mix('0.5', 'rgba(255, 0, 0, 0.5)', '#00f')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${mix(0.5, '#f00', '#00f')};\n * background: ${mix(0.25, '#f00', '#00f')};\n * background: ${mix('0.5', 'rgba(255, 0, 0, 0.5)', '#00f')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#7f007f\";\n * background: \"#3f00bf\";\n * background: \"rgba(63, 0, 191, 0.75)\";\n * }\n */\nfunction mix(weight, color, otherColor) {\n if (color === 'transparent') return otherColor;\n if (otherColor === 'transparent') return color;\n if (weight === 0) return otherColor;\n var parsedColor1 = parseToRgb(color);\n var color1 = _extends({}, parsedColor1, {\n alpha: typeof parsedColor1.alpha === 'number' ? parsedColor1.alpha : 1\n });\n var parsedColor2 = parseToRgb(otherColor);\n var color2 = _extends({}, parsedColor2, {\n alpha: typeof parsedColor2.alpha === 'number' ? parsedColor2.alpha : 1\n });\n\n // The formula is copied from the original Sass implementation:\n // http://sass-lang.com/documentation/Sass/Script/Functions.html#mix-instance_method\n var alphaDelta = color1.alpha - color2.alpha;\n var x = parseFloat(weight) * 2 - 1;\n var y = x * alphaDelta === -1 ? x : x + alphaDelta;\n var z = 1 + x * alphaDelta;\n var weight1 = (y / z + 1) / 2.0;\n var weight2 = 1 - weight1;\n var mixedColor = {\n red: Math.floor(color1.red * weight1 + color2.red * weight2),\n green: Math.floor(color1.green * weight1 + color2.green * weight2),\n blue: Math.floor(color1.blue * weight1 + color2.blue * weight2),\n alpha: color1.alpha * parseFloat(weight) + color2.alpha * (1 - parseFloat(weight))\n };\n return rgba(mixedColor);\n}\n\n// prettier-ignore\nvar curriedMix = curry /* ::<number | string, string, string, string> */(mix);\nvar mix$1 = curriedMix;\n\n/**\n * Increases the opacity of a color. Its range for the amount is between 0 to 1.\n *\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: opacify(0.1, 'rgba(255, 255, 255, 0.9)');\n * background: opacify(0.2, 'hsla(0, 0%, 100%, 0.5)'),\n * background: opacify('0.5', 'rgba(255, 0, 0, 0.2)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${opacify(0.1, 'rgba(255, 255, 255, 0.9)')};\n * background: ${opacify(0.2, 'hsla(0, 0%, 100%, 0.5)')},\n * background: ${opacify('0.5', 'rgba(255, 0, 0, 0.2)')},\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#fff\";\n * background: \"rgba(255,255,255,0.7)\";\n * background: \"rgba(255,0,0,0.7)\";\n * }\n */\nfunction opacify(amount, color) {\n if (color === 'transparent') return color;\n var parsedColor = parseToRgb(color);\n var alpha = typeof parsedColor.alpha === 'number' ? parsedColor.alpha : 1;\n var colorWithAlpha = _extends({}, parsedColor, {\n alpha: guard(0, 1, (alpha * 100 + parseFloat(amount) * 100) / 100)\n });\n return rgba(colorWithAlpha);\n}\n\n// prettier-ignore\nvar curriedOpacify = curry /* ::<number | string, string, string> */(opacify);\nvar curriedOpacify$1 = curriedOpacify;\n\nvar defaultReturnIfLightColor = '#000';\nvar defaultReturnIfDarkColor = '#fff';\n\n/**\n * Returns black or white (or optional passed colors) for best\n * contrast depending on the luminosity of the given color.\n * When passing custom return colors, strict mode ensures that the\n * return color always meets or exceeds WCAG level AA or greater. If this test\n * fails, the default return color (black or white) is returned in place of the\n * custom return color. You can optionally turn off strict mode.\n *\n * Follows [W3C specs for readability](https://www.w3.org/TR/WCAG20-TECHS/G18.html).\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * color: readableColor('#000'),\n * color: readableColor('black', '#001', '#ff8'),\n * color: readableColor('white', '#001', '#ff8'),\n * color: readableColor('red', '#333', '#ddd', true)\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * color: ${readableColor('#000')};\n * color: ${readableColor('black', '#001', '#ff8')};\n * color: ${readableColor('white', '#001', '#ff8')};\n * color: ${readableColor('red', '#333', '#ddd', true)};\n * `\n *\n * // CSS in JS Output\n * element {\n * color: \"#fff\";\n * color: \"#ff8\";\n * color: \"#001\";\n * color: \"#000\";\n * }\n */\nfunction readableColor(color, returnIfLightColor, returnIfDarkColor, strict) {\n if (returnIfLightColor === void 0) {\n returnIfLightColor = defaultReturnIfLightColor;\n }\n if (returnIfDarkColor === void 0) {\n returnIfDarkColor = defaultReturnIfDarkColor;\n }\n if (strict === void 0) {\n strict = true;\n }\n var isColorLight = getLuminance(color) > 0.179;\n var preferredReturnColor = isColorLight ? returnIfLightColor : returnIfDarkColor;\n if (!strict || getContrast(color, preferredReturnColor) >= 4.5) {\n return preferredReturnColor;\n }\n return isColorLight ? defaultReturnIfLightColor : defaultReturnIfDarkColor;\n}\n\n/**\n * Converts a RgbColor or RgbaColor object to a color string.\n * This util is useful in case you only know on runtime which color object is\n * used. Otherwise we recommend to rely on `rgb` or `rgba`.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: rgbToColorString({ red: 255, green: 205, blue: 100 }),\n * background: rgbToColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 }),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${rgbToColorString({ red: 255, green: 205, blue: 100 })};\n * background: ${rgbToColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 })};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#ffcd64\";\n * background: \"rgba(255,205,100,0.72)\";\n * }\n */\nfunction rgbToColorString(color) {\n if (typeof color === 'object' && typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number') {\n if (typeof color.alpha === 'number') {\n return rgba({\n red: color.red,\n green: color.green,\n blue: color.blue,\n alpha: color.alpha\n });\n }\n return rgb({\n red: color.red,\n green: color.green,\n blue: color.blue\n });\n }\n throw new PolishedError(46);\n}\n\n/**\n * Increases the intensity of a color. Its range is between 0 to 1. The first\n * argument of the saturate function is the amount by how much the color\n * intensity should be increased.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: saturate(0.2, '#CCCD64'),\n * background: saturate('0.2', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${saturate(0.2, '#FFCD64')};\n * background: ${saturate('0.2', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#e0e250\";\n * background: \"rgba(224,226,80,0.7)\";\n * }\n */\nfunction saturate(amount, color) {\n if (color === 'transparent') return color;\n var hslColor = parseToHsl(color);\n return toColorString(_extends({}, hslColor, {\n saturation: guard(0, 1, hslColor.saturation + parseFloat(amount))\n }));\n}\n\n// prettier-ignore\nvar curriedSaturate = curry /* ::<number | string, string, string> */(saturate);\nvar curriedSaturate$1 = curriedSaturate;\n\n/**\n * Sets the hue of a color to the provided value. The hue range can be\n * from 0 and 359.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: setHue(42, '#CCCD64'),\n * background: setHue('244', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${setHue(42, '#CCCD64')};\n * background: ${setHue('244', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#cdae64\";\n * background: \"rgba(107,100,205,0.7)\";\n * }\n */\nfunction setHue(hue, color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n hue: parseFloat(hue)\n }));\n}\n\n// prettier-ignore\nvar curriedSetHue = curry /* ::<number | string, string, string> */(setHue);\nvar curriedSetHue$1 = curriedSetHue;\n\n/**\n * Sets the lightness of a color to the provided value. The lightness range can be\n * from 0 and 1.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: setLightness(0.2, '#CCCD64'),\n * background: setLightness('0.75', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${setLightness(0.2, '#CCCD64')};\n * background: ${setLightness('0.75', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#4d4d19\";\n * background: \"rgba(223,224,159,0.7)\";\n * }\n */\nfunction setLightness(lightness, color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n lightness: parseFloat(lightness)\n }));\n}\n\n// prettier-ignore\nvar curriedSetLightness = curry /* ::<number | string, string, string> */(setLightness);\nvar curriedSetLightness$1 = curriedSetLightness;\n\n/**\n * Sets the saturation of a color to the provided value. The saturation range can be\n * from 0 and 1.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: setSaturation(0.2, '#CCCD64'),\n * background: setSaturation('0.75', 'rgba(204,205,100,0.7)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${setSaturation(0.2, '#CCCD64')};\n * background: ${setSaturation('0.75', 'rgba(204,205,100,0.7)')};\n * `\n *\n * // CSS in JS Output\n * element {\n * background: \"#adad84\";\n * background: \"rgba(228,229,76,0.7)\";\n * }\n */\nfunction setSaturation(saturation, color) {\n if (color === 'transparent') return color;\n return toColorString(_extends({}, parseToHsl(color), {\n saturation: parseFloat(saturation)\n }));\n}\n\n// prettier-ignore\nvar curriedSetSaturation = curry /* ::<number | string, string, string> */(setSaturation);\nvar curriedSetSaturation$1 = curriedSetSaturation;\n\n/**\n * Shades a color by mixing it with black. `shade` can produce\n * hue shifts, where as `darken` manipulates the luminance channel and therefore\n * doesn't produce hue shifts.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: shade(0.25, '#00f')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${shade(0.25, '#00f')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#00003f\";\n * }\n */\n\nfunction shade(percentage, color) {\n if (color === 'transparent') return color;\n return mix$1(parseFloat(percentage), 'rgb(0, 0, 0)', color);\n}\n\n// prettier-ignore\nvar curriedShade = curry /* ::<number | string, string, string> */(shade);\nvar curriedShade$1 = curriedShade;\n\n/**\n * Tints a color by mixing it with white. `tint` can produce\n * hue shifts, where as `lighten` manipulates the luminance channel and therefore\n * doesn't produce hue shifts.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: tint(0.25, '#00f')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${tint(0.25, '#00f')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"#bfbfff\";\n * }\n */\n\nfunction tint(percentage, color) {\n if (color === 'transparent') return color;\n return mix$1(parseFloat(percentage), 'rgb(255, 255, 255)', color);\n}\n\n// prettier-ignore\nvar curriedTint = curry /* ::<number | string, string, string> */(tint);\nvar curriedTint$1 = curriedTint;\n\n/**\n * Decreases the opacity of a color. Its range for the amount is between 0 to 1.\n *\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * background: transparentize(0.1, '#fff'),\n * background: transparentize(0.2, 'hsl(0, 0%, 100%)'),\n * background: transparentize('0.5', 'rgba(255, 0, 0, 0.8)'),\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * background: ${transparentize(0.1, '#fff')};\n * background: ${transparentize(0.2, 'hsl(0, 0%, 100%)')};\n * background: ${transparentize('0.5', 'rgba(255, 0, 0, 0.8)')};\n * `\n *\n * // CSS in JS Output\n *\n * element {\n * background: \"rgba(255,255,255,0.9)\";\n * background: \"rgba(255,255,255,0.8)\";\n * background: \"rgba(255,0,0,0.3)\";\n * }\n */\nfunction transparentize(amount, color) {\n if (color === 'transparent') return color;\n var parsedColor = parseToRgb(color);\n var alpha = typeof parsedColor.alpha === 'number' ? parsedColor.alpha : 1;\n var colorWithAlpha = _extends({}, parsedColor, {\n alpha: guard(0, 1, +(alpha * 100 - parseFloat(amount) * 100).toFixed(2) / 100)\n });\n return rgba(colorWithAlpha);\n}\n\n// prettier-ignore\nvar curriedTransparentize = curry /* ::<number | string, string, string> */(transparentize);\nvar curriedTransparentize$1 = curriedTransparentize;\n\n/**\n * Shorthand for easily setting the animation property. Allows either multiple arrays with animations\n * or a single animation spread over the arguments.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...animation(['rotate', '1s', 'ease-in-out'], ['colorchange', '2s'])\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${animation(['rotate', '1s', 'ease-in-out'], ['colorchange', '2s'])}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'animation': 'rotate 1s ease-in-out, colorchange 2s'\n * }\n * @example\n * // Styles as object usage\n * const styles = {\n * ...animation('rotate', '1s', 'ease-in-out')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${animation('rotate', '1s', 'ease-in-out')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'animation': 'rotate 1s ease-in-out'\n * }\n */\nfunction animation() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n // Allow single or multiple animations passed\n var multiMode = Array.isArray(args[0]);\n if (!multiMode && args.length > 8) {\n throw new PolishedError(64);\n }\n var code = args.map(function (arg) {\n if (multiMode && !Array.isArray(arg) || !multiMode && Array.isArray(arg)) {\n throw new PolishedError(65);\n }\n if (Array.isArray(arg) && arg.length > 8) {\n throw new PolishedError(66);\n }\n return Array.isArray(arg) ? arg.join(' ') : arg;\n }).join(', ');\n return {\n animation: code\n };\n}\n\n/**\n * Shorthand that accepts any number of backgroundImage values as parameters for creating a single background statement.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...backgroundImages('url(\"/image/background.jpg\")', 'linear-gradient(red, green)')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${backgroundImages('url(\"/image/background.jpg\")', 'linear-gradient(red, green)')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'backgroundImage': 'url(\"/image/background.jpg\"), linear-gradient(red, green)'\n * }\n */\nfunction backgroundImages() {\n for (var _len = arguments.length, properties = new Array(_len), _key = 0; _key < _len; _key++) {\n properties[_key] = arguments[_key];\n }\n return {\n backgroundImage: properties.join(', ')\n };\n}\n\n/**\n * Shorthand that accepts any number of background values as parameters for creating a single background statement.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...backgrounds('url(\"/image/background.jpg\")', 'linear-gradient(red, green)', 'center no-repeat')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${backgrounds('url(\"/image/background.jpg\")', 'linear-gradient(red, green)', 'center no-repeat')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'background': 'url(\"/image/background.jpg\"), linear-gradient(red, green), center no-repeat'\n * }\n */\nfunction backgrounds() {\n for (var _len = arguments.length, properties = new Array(_len), _key = 0; _key < _len; _key++) {\n properties[_key] = arguments[_key];\n }\n return {\n background: properties.join(', ')\n };\n}\n\nvar sideMap = ['top', 'right', 'bottom', 'left'];\n\n/**\n * Shorthand for the border property that splits out individual properties for use with tools like Fela and Styletron. A side keyword can optionally be passed to target only one side's border properties.\n *\n * @example\n * // Styles as object usage\n * const styles = {\n * ...border('1px', 'solid', 'red')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${border('1px', 'solid', 'red')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderColor': 'red',\n * 'borderStyle': 'solid',\n * 'borderWidth': `1px`,\n * }\n *\n * // Styles as object usage\n * const styles = {\n * ...border('top', '1px', 'solid', 'red')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${border('top', '1px', 'solid', 'red')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopColor': 'red',\n * 'borderTopStyle': 'solid',\n * 'borderTopWidth': `1px`,\n * }\n */\n\nfunction border(sideKeyword) {\n for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n values[_key - 1] = arguments[_key];\n }\n if (typeof sideKeyword === 'string' && sideMap.indexOf(sideKeyword) >= 0) {\n var _ref;\n return _ref = {}, _ref[\"border\" + capitalizeString(sideKeyword) + \"Width\"] = values[0], _ref[\"border\" + capitalizeString(sideKeyword) + \"Style\"] = values[1], _ref[\"border\" + capitalizeString(sideKeyword) + \"Color\"] = values[2], _ref;\n } else {\n values.unshift(sideKeyword);\n return {\n borderWidth: values[0],\n borderStyle: values[1],\n borderColor: values[2]\n };\n }\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderColor('red', 'green', 'blue', 'yellow')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderColor('red', 'green', 'blue', 'yellow')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopColor': 'red',\n * 'borderRightColor': 'green',\n * 'borderBottomColor': 'blue',\n * 'borderLeftColor': 'yellow'\n * }\n */\nfunction borderColor() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['borderColor'].concat(values));\n}\n\n/**\n * Shorthand that accepts a value for side and a value for radius and applies the radius value to both corners of the side.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderRadius('top', '5px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderRadius('top', '5px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopRightRadius': '5px',\n * 'borderTopLeftRadius': '5px',\n * }\n */\nfunction borderRadius(side, radius) {\n var uppercaseSide = capitalizeString(side);\n if (!radius && radius !== 0) {\n throw new PolishedError(62);\n }\n if (uppercaseSide === 'Top' || uppercaseSide === 'Bottom') {\n var _ref;\n return _ref = {}, _ref[\"border\" + uppercaseSide + \"RightRadius\"] = radius, _ref[\"border\" + uppercaseSide + \"LeftRadius\"] = radius, _ref;\n }\n if (uppercaseSide === 'Left' || uppercaseSide === 'Right') {\n var _ref2;\n return _ref2 = {}, _ref2[\"borderTop\" + uppercaseSide + \"Radius\"] = radius, _ref2[\"borderBottom\" + uppercaseSide + \"Radius\"] = radius, _ref2;\n }\n throw new PolishedError(63);\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderStyle('solid', 'dashed', 'dotted', 'double')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderStyle('solid', 'dashed', 'dotted', 'double')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopStyle': 'solid',\n * 'borderRightStyle': 'dashed',\n * 'borderBottomStyle': 'dotted',\n * 'borderLeftStyle': 'double'\n * }\n */\nfunction borderStyle() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['borderStyle'].concat(values));\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...borderWidth('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${borderWidth('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'borderTopWidth': '12px',\n * 'borderRightWidth': '24px',\n * 'borderBottomWidth': '36px',\n * 'borderLeftWidth': '48px'\n * }\n */\nfunction borderWidth() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['borderWidth'].concat(values));\n}\n\nfunction generateSelectors(template, state) {\n var stateSuffix = state ? \":\" + state : '';\n return template(stateSuffix);\n}\n\n/**\n * Function helper that adds an array of states to a template of selectors. Used in textInputs and buttons.\n * @private\n */\nfunction statefulSelectors(states, template, stateMap) {\n if (!template) throw new PolishedError(67);\n if (states.length === 0) return generateSelectors(template, null);\n var selectors = [];\n for (var i = 0; i < states.length; i += 1) {\n if (stateMap && stateMap.indexOf(states[i]) < 0) {\n throw new PolishedError(68);\n }\n selectors.push(generateSelectors(template, states[i]));\n }\n selectors = selectors.join(',');\n return selectors;\n}\n\nvar stateMap$1 = [undefined, null, 'active', 'focus', 'hover'];\nfunction template$1(state) {\n return \"button\" + state + \",\\n input[type=\\\"button\\\"]\" + state + \",\\n input[type=\\\"reset\\\"]\" + state + \",\\n input[type=\\\"submit\\\"]\" + state;\n}\n\n/**\n * Populates selectors that target all buttons. You can pass optional states to append to the selectors.\n * @example\n * // Styles as object usage\n * const styles = {\n * [buttons('active')]: {\n * 'border': 'none'\n * }\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * > ${buttons('active')} {\n * border: none;\n * }\n * `\n *\n * // CSS in JS Output\n *\n * 'button:active,\n * 'input[type=\"button\"]:active,\n * 'input[type=\\\"reset\\\"]:active,\n * 'input[type=\\\"submit\\\"]:active: {\n * 'border': 'none'\n * }\n */\nfunction buttons() {\n for (var _len = arguments.length, states = new Array(_len), _key = 0; _key < _len; _key++) {\n states[_key] = arguments[_key];\n }\n return statefulSelectors(states, template$1, stateMap$1);\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...margin('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${margin('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'marginTop': '12px',\n * 'marginRight': '24px',\n * 'marginBottom': '36px',\n * 'marginLeft': '48px'\n * }\n */\nfunction margin() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['margin'].concat(values));\n}\n\n/**\n * Shorthand that accepts up to four values, including null to skip a value, and maps them to their respective directions.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...padding('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${padding('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'paddingTop': '12px',\n * 'paddingRight': '24px',\n * 'paddingBottom': '36px',\n * 'paddingLeft': '48px'\n * }\n */\nfunction padding() {\n for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {\n values[_key] = arguments[_key];\n }\n return directionalProperty.apply(void 0, ['padding'].concat(values));\n}\n\nvar positionMap = ['absolute', 'fixed', 'relative', 'static', 'sticky'];\n\n/**\n * Shorthand accepts up to five values, including null to skip a value, and maps them to their respective directions. The first value can optionally be a position keyword.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...position('12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${position('12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'top': '12px',\n * 'right': '24px',\n * 'bottom': '36px',\n * 'left': '48px'\n * }\n *\n * // Styles as object usage\n * const styles = {\n * ...position('absolute', '12px', '24px', '36px', '48px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${position('absolute', '12px', '24px', '36px', '48px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'position': 'absolute',\n * 'top': '12px',\n * 'right': '24px',\n * 'bottom': '36px',\n * 'left': '48px'\n * }\n */\nfunction position(firstValue) {\n for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n values[_key - 1] = arguments[_key];\n }\n if (positionMap.indexOf(firstValue) >= 0 && firstValue) {\n return _extends({}, directionalProperty.apply(void 0, [''].concat(values)), {\n position: firstValue\n });\n } else {\n return directionalProperty.apply(void 0, ['', firstValue].concat(values));\n }\n}\n\n/**\n * Shorthand to set the height and width properties in a single statement.\n * @example\n * // Styles as object usage\n * const styles = {\n * ...size('300px', '250px')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${size('300px', '250px')}\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'height': '300px',\n * 'width': '250px',\n * }\n */\nfunction size(height, width) {\n if (width === void 0) {\n width = height;\n }\n return {\n height: height,\n width: width\n };\n}\n\nvar stateMap = [undefined, null, 'active', 'focus', 'hover'];\nfunction template(state) {\n return \"input[type=\\\"color\\\"]\" + state + \",\\n input[type=\\\"date\\\"]\" + state + \",\\n input[type=\\\"datetime\\\"]\" + state + \",\\n input[type=\\\"datetime-local\\\"]\" + state + \",\\n input[type=\\\"email\\\"]\" + state + \",\\n input[type=\\\"month\\\"]\" + state + \",\\n input[type=\\\"number\\\"]\" + state + \",\\n input[type=\\\"password\\\"]\" + state + \",\\n input[type=\\\"search\\\"]\" + state + \",\\n input[type=\\\"tel\\\"]\" + state + \",\\n input[type=\\\"text\\\"]\" + state + \",\\n input[type=\\\"time\\\"]\" + state + \",\\n input[type=\\\"url\\\"]\" + state + \",\\n input[type=\\\"week\\\"]\" + state + \",\\n input:not([type])\" + state + \",\\n textarea\" + state;\n}\n\n/**\n * Populates selectors that target all text inputs. You can pass optional states to append to the selectors.\n * @example\n * // Styles as object usage\n * const styles = {\n * [textInputs('active')]: {\n * 'border': 'none'\n * }\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * > ${textInputs('active')} {\n * border: none;\n * }\n * `\n *\n * // CSS in JS Output\n *\n * 'input[type=\"color\"]:active,\n * input[type=\"date\"]:active,\n * input[type=\"datetime\"]:active,\n * input[type=\"datetime-local\"]:active,\n * input[type=\"email\"]:active,\n * input[type=\"month\"]:active,\n * input[type=\"number\"]:active,\n * input[type=\"password\"]:active,\n * input[type=\"search\"]:active,\n * input[type=\"tel\"]:active,\n * input[type=\"text\"]:active,\n * input[type=\"time\"]:active,\n * input[type=\"url\"]:active,\n * input[type=\"week\"]:active,\n * input:not([type]):active,\n * textarea:active': {\n * 'border': 'none'\n * }\n */\nfunction textInputs() {\n for (var _len = arguments.length, states = new Array(_len), _key = 0; _key < _len; _key++) {\n states[_key] = arguments[_key];\n }\n return statefulSelectors(states, template, stateMap);\n}\n\n/**\n * Accepts any number of transition values as parameters for creating a single transition statement. You may also pass an array of properties as the first parameter that you would like to apply the same transition values to (second parameter).\n * @example\n * // Styles as object usage\n * const styles = {\n * ...transitions('opacity 1.0s ease-in 0s', 'width 2.0s ease-in 2s'),\n * ...transitions(['color', 'background-color'], '2.0s ease-in 2s')\n * }\n *\n * // styled-components usage\n * const div = styled.div`\n * ${transitions('opacity 1.0s ease-in 0s', 'width 2.0s ease-in 2s')};\n * ${transitions(['color', 'background-color'], '2.0s ease-in 2s'),};\n * `\n *\n * // CSS as JS Output\n *\n * div {\n * 'transition': 'opacity 1.0s ease-in 0s, width 2.0s ease-in 2s'\n * 'transition': 'color 2.0s ease-in 2s, background-color 2.0s ease-in 2s',\n * }\n */\nfunction transitions() {\n for (var _len = arguments.length, properties = new Array(_len), _key = 0; _key < _len; _key++) {\n properties[_key] = arguments[_key];\n }\n if (Array.isArray(properties[0]) && properties.length === 2) {\n var value = properties[1];\n if (typeof value !== 'string') {\n throw new PolishedError(61);\n }\n var transitionsString = properties[0].map(function (property) {\n return property + \" \" + value;\n }).join(', ');\n return {\n transition: transitionsString\n };\n } else {\n return {\n transition: properties.join(', ')\n };\n }\n}\n\nexport { curriedAdjustHue$1 as adjustHue, animation, backgroundImages, backgrounds, between, border, borderColor, borderRadius, borderStyle, borderWidth, buttons, clearFix, complement, cover, cssVar, curriedDarken$1 as darken, curriedDesaturate$1 as desaturate, directionalProperty, easeIn, easeInOut, easeOut, ellipsis, em$1 as em, fluidRange, fontFace, getContrast, getLuminance, getValueAndUnit, grayscale, hiDPI, hideText, hideVisually, hsl, hslToColorString, hsla, important, invert, curriedLighten$1 as lighten, linearGradient, margin, math, meetsContrastGuidelines, mix$1 as mix, modularScale, normalize, curriedOpacify$1 as opacify, padding, parseToHsl, parseToRgb, position, radialGradient, readableColor, rem$1 as rem, remToPx, retinaImage, rgb, rgbToColorString, rgba, curriedSaturate$1 as saturate, curriedSetHue$1 as setHue, curriedSetLightness$1 as setLightness, curriedSetSaturation$1 as setSaturation, curriedShade$1 as shade, size, stripUnit, textInputs, timingFunctions, curriedTint$1 as tint, toColorString, transitions, curriedTransparentize$1 as transparentize, triangle, wordWrap };\n","import { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport type { SimpleRouteJson } from \"../types\"\nimport { transparentize } from \"polished\"\n\nexport const COLORS = [\n \"blue\",\n \"orange\",\n \"purple\",\n \"cyan\",\n \"magenta\",\n \"yellowgreen\",\n \"darkgoldenrod\",\n \"deeppink\",\n]\n\nexport const getColorMap = (\n srj: SimpleRouteJson,\n connMap?: ConnectivityMap,\n) => {\n const colorMap: Record<string, string> = {}\n for (let i = 0; i < srj.connections.length; i++) {\n const connection = srj.connections[i]\n const netName = connMap?.getNetConnectedToId(connection.name)\n\n if (netName && !colorMap[netName]) {\n colorMap[netName] =\n `hsl(${(i * 300) / srj.connections.length}, 100%, 50%)`\n }\n\n colorMap[connection.name] =\n (netName ? colorMap[netName] : null) ??\n `hsl(${(i * 340) / srj.connections.length}, 100%, 50%)`\n }\n return colorMap\n}\n\nexport const safeTransparentize = (color: string, amount: number) => {\n try {\n return transparentize(amount, color)\n } catch (e) {\n console.error(e)\n return color\n }\n}\n","export function isPointInRect(\n point: { x: number; y: number },\n rect: { center: { x: number; y: number }; width: number; height: number },\n) {\n return (\n point.x >= rect.center.x - rect.width / 2 &&\n point.x <= rect.center.x + rect.width / 2 &&\n point.y >= rect.center.y - rect.height / 2 &&\n point.y <= rect.center.y + rect.height / 2\n )\n}\n","export function doRectsOverlap(\n rect1: { center: { x: number; y: number }; width: number; height: number },\n rect2: { center: { x: number; y: number }; width: number; height: number },\n) {\n const rect1Left = rect1.center.x - rect1.width / 2\n const rect1Right = rect1.center.x + rect1.width / 2\n const rect1Top = rect1.center.y - rect1.height / 2\n const rect1Bottom = rect1.center.y + rect1.height / 2\n\n const rect2Left = rect2.center.x - rect2.width / 2\n const rect2Right = rect2.center.x + rect2.width / 2\n const rect2Top = rect2.center.y - rect2.height / 2\n const rect2Bottom = rect2.center.y + rect2.height / 2\n\n return (\n rect1Left <= rect2Right &&\n rect1Right >= rect2Left &&\n rect1Top <= rect2Bottom &&\n rect1Bottom >= rect2Top\n )\n}\n","export const mapLayerNameToZ = (layerName: string, layerCount: number) => {\n if (layerName === \"top\") return 0\n if (layerName === \"bottom\") return layerCount - 1\n return parseInt(layerName.slice(5))\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n Obstacle,\n SimpleRouteJson,\n} from \"../../types\"\nimport { COLORS } from \"../colors\"\nimport { isPointInRect } from \"lib/utils/isPointInRect\"\nimport { doRectsOverlap } from \"lib/utils/doRectsOverlap\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\n\ninterface CapacityMeshNodeSolverOptions {\n capacityDepth?: number\n}\n\ninterface Target {\n x: number\n y: number\n connectionName: string\n availableZ: number[]\n}\n\nexport class CapacityMeshNodeSolver extends BaseSolver {\n unfinishedNodes: CapacityMeshNode[]\n finishedNodes: CapacityMeshNode[]\n\n nodeToXYOverlappingObstaclesMap: Map<CapacityMeshNodeId, Obstacle[]>\n layerCount: number\n\n // targetObstacleMap: Record<string, { obstacle: Obstacle, node: CapacityMeshNode }>\n\n MAX_DEPTH = 4\n\n targets: Target[]\n\n constructor(\n public srj: SimpleRouteJson,\n public opts: CapacityMeshNodeSolverOptions = {},\n ) {\n super()\n this.MAX_DEPTH = opts?.capacityDepth ?? this.MAX_DEPTH\n this.MAX_ITERATIONS = 100_000\n this.layerCount = srj.layerCount ?? 2\n\n for (const obstacle of srj.obstacles) {\n if (!obstacle.zLayers) {\n const zLayers: number[] = []\n for (const layer of obstacle.layers) {\n zLayers.push(mapLayerNameToZ(layer, srj.layerCount))\n }\n obstacle.zLayers = zLayers\n }\n }\n\n const boundsCenter = {\n x: (srj.bounds.minX + srj.bounds.maxX) / 2,\n y: (srj.bounds.minY + srj.bounds.maxY) / 2,\n }\n const boundsSize = {\n width: srj.bounds.maxX - srj.bounds.minX,\n height: srj.bounds.maxY - srj.bounds.minY,\n }\n const maxWidthHeight = Math.max(boundsSize.width, boundsSize.height)\n this.unfinishedNodes = [\n {\n capacityMeshNodeId: this.getNextNodeId(),\n center: boundsCenter,\n width: maxWidthHeight,\n height: maxWidthHeight,\n layer: \"top\",\n availableZ: [0, 1],\n _depth: 0,\n _containsTarget: true,\n _containsObstacle: true,\n _completelyInsideObstacle: false,\n },\n ]\n this.finishedNodes = []\n this.nodeToXYOverlappingObstaclesMap = new Map()\n this.targets = this.srj.connections.flatMap((c) =>\n c.pointsToConnect.map((p) => ({\n ...p,\n connectionName: c.name,\n availableZ: p.layer === \"top\" ? [0] : [1],\n })),\n )\n }\n\n _nextNodeCounter = 0\n getNextNodeId(): string {\n return `cn${this._nextNodeCounter++}`\n }\n\n getCapacityFromDepth(depth: number): number {\n return (this.MAX_DEPTH - depth + 1) ** 2\n }\n\n getTargetIfNodeContainsTarget(node: CapacityMeshNode): Target | null {\n const overlappingObstacles = this.getXYOverlappingObstacles(node)\n for (const target of this.targets) {\n // if (target.layer !== node.layer) continue\n if (!target.availableZ.some((z) => node.availableZ.includes(z))) continue\n\n const targetObstacle = overlappingObstacles.find((o) =>\n isPointInRect(target, o),\n )\n\n if (targetObstacle) {\n if (doRectsOverlap(node, targetObstacle)) {\n return target\n }\n }\n\n if (\n target.x >= node.center.x - node.width / 2 &&\n target.x <= node.center.x + node.width / 2 &&\n target.y >= node.center.y - node.height / 2 &&\n target.y <= node.center.y + node.height / 2\n ) {\n return target\n }\n }\n return null\n }\n\n getXYOverlappingObstacles(node: CapacityMeshNode): Obstacle[] {\n const cachedObstacles = this.nodeToXYOverlappingObstaclesMap.get(\n node.capacityMeshNodeId,\n )\n if (cachedObstacles) {\n return cachedObstacles\n }\n const overlappingObstacles: Obstacle[] = []\n\n // Compute node bounds\n const nodeLeft = node.center.x - node.width / 2\n const nodeRight = node.center.x + node.width / 2\n const nodeTop = node.center.y - node.height / 2\n const nodeBottom = node.center.y + node.height / 2\n\n const obstacles = node._parent\n ? this.getXYOverlappingObstacles(node._parent)\n : this.srj.obstacles\n for (const obstacle of obstacles) {\n const obsLeft = obstacle.center.x - obstacle.width / 2\n const obsRight = obstacle.center.x + obstacle.width / 2\n const obsTop = obstacle.center.y - obstacle.height / 2\n const obsBottom = obstacle.center.y + obstacle.height / 2\n\n // Check for intersection.\n if (\n nodeRight >= obsLeft &&\n nodeLeft <= obsRight &&\n nodeBottom >= obsTop &&\n nodeTop <= obsBottom\n ) {\n overlappingObstacles.push(obstacle)\n continue\n }\n\n // Check if the node is completely within the obstacle\n if (\n nodeLeft >= obsLeft &&\n nodeRight <= obsRight &&\n nodeTop >= obsTop &&\n nodeBottom <= obsBottom\n ) {\n // Node is completely inside the obstacle\n overlappingObstacles.push(obstacle)\n continue\n }\n\n // Check if obstacle is completely within node\n if (\n obsLeft >= nodeLeft &&\n obsRight <= nodeRight &&\n obsTop >= nodeTop &&\n obsBottom <= nodeBottom\n ) {\n overlappingObstacles.push(obstacle)\n }\n }\n\n this.nodeToXYOverlappingObstaclesMap.set(\n node.capacityMeshNodeId,\n overlappingObstacles,\n )\n\n return overlappingObstacles\n }\n\n getXYZOverlappingObstacles(node: CapacityMeshNode): Obstacle[] {\n const xyOverlappingObstacles = this.getXYOverlappingObstacles(node)\n\n // For each obstacle, check if it has any overlap in the z-axis\n const xyzOverlappingObstacles: Obstacle[] = []\n for (const obstacle of xyOverlappingObstacles) {\n if (node.availableZ.some((z) => obstacle.zLayers!.includes(z))) {\n xyzOverlappingObstacles.push(obstacle)\n }\n }\n\n return xyzOverlappingObstacles\n }\n\n /**\n * Checks if the given mesh node overlaps with any obstacle.\n * We treat both obstacles and nodes as axis‐aligned rectangles.\n */\n doesNodeOverlapObstacle(node: CapacityMeshNode): boolean {\n const overlappingObstacles = this.getXYZOverlappingObstacles(node)\n\n if (overlappingObstacles.length > 0) {\n return true\n }\n\n // Compute node bounds\n const nodeLeft = node.center.x - node.width / 2\n const nodeRight = node.center.x + node.width / 2\n const nodeTop = node.center.y - node.height / 2\n const nodeBottom = node.center.y + node.height / 2\n\n // If node is outside the bounds, we consider it to contain an obstacle\n if (\n nodeLeft < this.srj.bounds.minX ||\n nodeRight > this.srj.bounds.maxX ||\n nodeTop < this.srj.bounds.minY ||\n nodeBottom > this.srj.bounds.maxY\n ) {\n return true\n }\n return false\n }\n\n /**\n * Checks if the entire node is contained within any obstacle.\n */\n isNodeCompletelyInsideObstacle(node: CapacityMeshNode): boolean {\n const overlappingObstacles = this.getXYZOverlappingObstacles(node)\n\n // Compute node bounds\n const nodeLeft = node.center.x - node.width / 2\n const nodeRight = node.center.x + node.width / 2\n const nodeTop = node.center.y - node.height / 2\n const nodeBottom = node.center.y + node.height / 2\n\n for (const obstacle of overlappingObstacles) {\n const obsLeft = obstacle.center.x - obstacle.width / 2\n const obsRight = obstacle.center.x + obstacle.width / 2\n const obsTop = obstacle.center.y - obstacle.height / 2\n const obsBottom = obstacle.center.y + obstacle.height / 2\n\n // Check if the node's bounds are completely inside the obstacle's bounds.\n if (\n nodeLeft >= obsLeft &&\n nodeRight <= obsRight &&\n nodeTop >= obsTop &&\n nodeBottom <= obsBottom\n ) {\n return true\n }\n }\n\n // if (\n // nodeRight < this.srj.bounds.minX ||\n // nodeLeft > this.srj.bounds.maxX ||\n // nodeBottom < this.srj.bounds.minY ||\n // nodeTop > this.srj.bounds.maxY\n // ) {\n // return true\n // }\n\n return false\n }\n\n getChildNodes(parent: CapacityMeshNode): CapacityMeshNode[] {\n if (parent._depth === this.MAX_DEPTH) return []\n const childNodes: CapacityMeshNode[] = []\n\n const childNodeSize = { width: parent.width / 2, height: parent.height / 2 }\n\n const childNodePositions = [\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n ]\n\n for (const position of childNodePositions) {\n const childNode: CapacityMeshNode = {\n capacityMeshNodeId: this.getNextNodeId(),\n center: position,\n width: childNodeSize.width,\n height: childNodeSize.height,\n layer: parent.layer,\n availableZ: [0, 1],\n _depth: (parent._depth ?? 0) + 1,\n _parent: parent,\n }\n childNode._containsObstacle = this.doesNodeOverlapObstacle(childNode)\n\n const target = this.getTargetIfNodeContainsTarget(childNode)\n\n if (target) {\n childNode._targetConnectionName = target.connectionName\n childNode.availableZ = target.availableZ\n childNode._containsTarget = true\n }\n\n if (childNode._containsObstacle) {\n childNode._completelyInsideObstacle =\n this.isNodeCompletelyInsideObstacle(childNode)\n }\n if (childNode._completelyInsideObstacle && !childNode._containsTarget)\n continue\n childNodes.push(childNode)\n }\n\n return childNodes\n }\n\n shouldNodeBeXYSubdivided(node: CapacityMeshNode) {\n if (node._depth! >= this.MAX_DEPTH) return false\n if (node._containsTarget) return true\n if (node._containsObstacle && !node._completelyInsideObstacle) return true\n return false\n }\n\n _step() {\n const nextNode = this.unfinishedNodes.pop()\n if (!nextNode) {\n this.solved = true\n return\n }\n\n const newNodes = this.getChildNodes(nextNode)\n\n const finishedNewNodes: CapacityMeshNode[] = []\n const unfinishedNewNodes: CapacityMeshNode[] = []\n\n for (const newNode of newNodes) {\n const shouldBeSubdivided = this.shouldNodeBeXYSubdivided(newNode)\n if (shouldBeSubdivided) {\n unfinishedNewNodes.push(newNode)\n } else if (!shouldBeSubdivided && !newNode._containsObstacle) {\n finishedNewNodes.push(newNode)\n } else if (!shouldBeSubdivided && newNode._containsTarget) {\n finishedNewNodes.push(newNode)\n }\n }\n\n this.unfinishedNodes.push(...unfinishedNewNodes)\n this.finishedNodes.push(...finishedNewNodes)\n }\n\n /**\n * Creates a GraphicsObject to visualize the mesh, its nodes, obstacles, and connection points.\n *\n * - Mesh nodes are rendered as rectangles.\n * - Nodes that have an obstacle intersection are outlined in red.\n * - Other nodes are outlined in green.\n * - Lines are drawn from a node to its parent.\n * - Obstacles are drawn as semi-transparent red rectangles.\n * - Points for each connection’s pointsToConnect are drawn in a unique color.\n */\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Capacity Mesh Visualization\",\n }\n\n // Draw obstacles\n for (const obstacle of this.srj.obstacles) {\n graphics.rects!.push({\n center: obstacle.center,\n width: obstacle.width,\n height: obstacle.height,\n fill:\n obstacle.zLayers?.length === 1 && obstacle.zLayers?.includes(1)\n ? \"rgba(0,0,255,0.3)\"\n : \"rgba(255,0,0,0.3)\",\n stroke: \"red\",\n label: [\"obstacle\", `z: ${obstacle.zLayers!.join(\",\")}`].join(\"\\n\"),\n })\n }\n\n // Draw mesh nodes (both finished and unfinished)\n const allNodes = [...this.finishedNodes, ...this.unfinishedNodes]\n for (const node of allNodes) {\n const lowestZ = Math.min(...node.availableZ)\n const isNextToBeProcessed =\n this.unfinishedNodes.length > 0 &&\n node === this.unfinishedNodes[this.unfinishedNodes.length - 1]\n\n graphics.rects!.push({\n center: {\n x: node.center.x + lowestZ * node.width * 0.05,\n y: node.center.y - lowestZ * node.width * 0.05,\n },\n width: Math.max(node.width - 2, node.width * 0.8),\n height: Math.max(node.height - 2, node.height * 0.8),\n fill: node._containsObstacle\n ? \"rgba(255,0,0,0.1)\"\n : ({\n \"0,1\": \"rgba(0,0,0,0.1)\",\n \"0\": \"rgba(0,200,200, 0.1)\",\n \"1\": \"rgba(0,0,200, 0.1)\",\n }[node.availableZ.join(\",\")] ?? \"rgba(0,200,200,0.1)\"),\n stroke: isNextToBeProcessed ? \"rgba(255,165,0,0.5)\" : undefined,\n label: [\n node.capacityMeshNodeId,\n `availableZ: ${node.availableZ.join(\",\")}`,\n `target? ${node._containsTarget ?? false}`,\n `obs? ${node._containsObstacle ?? false}`,\n ].join(\"\\n\"),\n })\n }\n graphics.rects!.sort((a, b) => a.center.y - b.center.y)\n\n // Draw connection points (each connection gets a unique color).\n this.srj.connections.forEach((connection, index) => {\n const color = COLORS[index % COLORS.length]\n for (const pt of connection.pointsToConnect) {\n graphics.points!.push({\n x: pt.x,\n y: pt.y,\n label: `conn-${index} (${pt.layer})`,\n color,\n })\n }\n })\n\n return graphics\n }\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n Obstacle,\n SimpleRouteJson,\n} from \"../../types\"\nimport { COLORS } from \"../colors\"\nimport { isPointInRect } from \"lib/utils/isPointInRect\"\nimport { doRectsOverlap } from \"lib/utils/doRectsOverlap\"\nimport { CapacityMeshNodeSolver } from \"./CapacityMeshNodeSolver1\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\n\ninterface CapacityMeshNodeSolverOptions {\n capacityDepth?: number\n}\n\ninterface Target {\n x: number\n y: number\n connectionName: string\n availableZ: number[]\n}\n\nexport class CapacityMeshNodeSolver2_NodeUnderObstacle extends CapacityMeshNodeSolver {\n constructor(\n public srj: SimpleRouteJson,\n public opts: CapacityMeshNodeSolverOptions = {},\n ) {\n super(srj, opts)\n }\n\n isNodeCompletelyOutsideBounds(node: CapacityMeshNode): boolean {\n return (\n node.center.x + node.width / 2 < this.srj.bounds.minX ||\n node.center.x - node.width / 2 > this.srj.bounds.maxX ||\n node.center.y + node.height / 2 < this.srj.bounds.minY ||\n node.center.y - node.height / 2 > this.srj.bounds.maxY\n )\n }\n\n isNodePartiallyOutsideBounds(node: CapacityMeshNode): boolean {\n return (\n node.center.x - node.width / 2 < this.srj.bounds.minX ||\n node.center.x + node.width / 2 > this.srj.bounds.maxX ||\n node.center.y - node.height / 2 < this.srj.bounds.minY ||\n node.center.y + node.height / 2 > this.srj.bounds.maxY\n )\n }\n createChildNodeAtPosition(\n parent: CapacityMeshNode,\n opts: {\n center: { x: number; y: number }\n width: number\n height: number\n availableZ: number[]\n _depth?: number\n },\n ): CapacityMeshNode {\n const childNode: CapacityMeshNode = {\n capacityMeshNodeId: this.getNextNodeId(),\n center: opts.center,\n width: opts.width,\n height: opts.height,\n layer: parent.layer,\n availableZ: opts.availableZ,\n _depth: opts._depth ?? (parent._depth ?? 0) + 1,\n _parent: parent,\n }\n\n const overlappingObstacles = this.getXYZOverlappingObstacles(childNode)\n\n childNode._containsObstacle =\n overlappingObstacles.length > 0 ||\n this.isNodePartiallyOutsideBounds(childNode)\n\n const target = this.getTargetIfNodeContainsTarget(childNode)\n\n if (target) {\n childNode._targetConnectionName = target.connectionName\n childNode._containsTarget = true\n }\n\n if (childNode._containsObstacle) {\n childNode._completelyInsideObstacle =\n this.isNodeCompletelyInsideObstacle(childNode)\n }\n // childNode._shouldBeInGraph =\n // (!isOutsideBounds && !childNode._completelyInsideObstacle) || childNode._\n\n return childNode\n }\n\n getZSubdivisionChildNodes(node: CapacityMeshNode): CapacityMeshNode[] {\n if (node.availableZ.length === 1) return []\n\n const childNodes: CapacityMeshNode[] = []\n\n // TODO when we have more than 2 layers, we need to handle other\n // variations, you always want to prioritize having larger contiguous\n // z-blocks\n const otherZBlocks = [[0], [1]]\n\n for (const zBlock of otherZBlocks) {\n const childNode = this.createChildNodeAtPosition(node, {\n center: { ...node.center },\n width: node.width,\n height: node.height,\n availableZ: zBlock,\n // z-subdivision doesn't count towards depth, should be same as parent\n _depth: node._depth!,\n })\n\n if (this.isNodeCompletelyOutsideBounds(childNode)) {\n continue\n }\n\n childNodes.push(childNode)\n }\n\n return childNodes\n }\n\n getChildNodes(parent: CapacityMeshNode): CapacityMeshNode[] {\n if (parent._depth! >= this.MAX_DEPTH) return []\n const childNodes: CapacityMeshNode[] = []\n\n const childNodeSize = { width: parent.width / 2, height: parent.height / 2 }\n\n const childNodePositions = [\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y - childNodeSize.height / 2,\n },\n {\n x: parent.center.x - childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n {\n x: parent.center.x + childNodeSize.width / 2,\n y: parent.center.y + childNodeSize.height / 2,\n },\n ]\n\n for (const position of childNodePositions) {\n const childNode = this.createChildNodeAtPosition(parent, {\n center: position,\n width: childNodeSize.width,\n height: childNodeSize.height,\n availableZ: parent.availableZ,\n })\n if (this.isNodeCompletelyOutsideBounds(childNode)) {\n continue\n }\n childNodes.push(childNode)\n }\n\n return childNodes\n }\n\n shouldNodeBeXYSubdivided(node: CapacityMeshNode) {\n if (node._depth! >= this.MAX_DEPTH) return false\n if (node._containsTarget) return true\n if (node.availableZ.length === 1 && node._depth! <= this.MAX_DEPTH)\n return true\n if (node._containsObstacle && !node._completelyInsideObstacle) return true\n return false\n }\n\n _step() {\n const nextNode = this.unfinishedNodes.pop()\n if (!nextNode) {\n this.solved = true\n return\n }\n\n const childNodes = this.getChildNodes(nextNode)\n\n const finishedNewNodes: CapacityMeshNode[] = []\n const unfinishedNewNodes: CapacityMeshNode[] = []\n\n for (const childNode of childNodes) {\n const shouldBeXYSubdivided = this.shouldNodeBeXYSubdivided(childNode)\n const shouldBeZSubdivided =\n childNode.availableZ.length > 1 &&\n !shouldBeXYSubdivided &&\n childNode._containsObstacle\n if (shouldBeXYSubdivided) {\n unfinishedNewNodes.push(childNode)\n } else if (!shouldBeXYSubdivided && !childNode._containsObstacle) {\n finishedNewNodes.push(childNode)\n } else if (!shouldBeXYSubdivided && childNode._containsTarget) {\n if (shouldBeZSubdivided) {\n const zSubNodes = this.getZSubdivisionChildNodes(childNode)\n finishedNewNodes.push(\n ...zSubNodes.filter(\n (n) => n._containsTarget || !n._containsObstacle,\n ),\n )\n } else {\n finishedNewNodes.push(childNode)\n }\n } else if (shouldBeZSubdivided) {\n finishedNewNodes.push(\n ...this.getZSubdivisionChildNodes(childNode).filter(\n (zSubNode) => !zSubNode._containsObstacle,\n ),\n )\n }\n }\n\n this.unfinishedNodes.push(...unfinishedNewNodes)\n this.finishedNodes.push(...finishedNewNodes)\n }\n}\n","import type { CapacityMeshEdge, CapacityMeshNodeId } from \"../../types\"\n\nexport function getNodeEdgeMap(\n edges: CapacityMeshEdge[],\n): Map<CapacityMeshNodeId, CapacityMeshEdge[]> {\n const nodeEdgeMap = new Map<CapacityMeshNodeId, CapacityMeshEdge[]>()\n\n for (const edge of edges) {\n for (const nodeId of edge.nodeIds) {\n nodeEdgeMap.set(nodeId, [...(nodeEdgeMap.get(nodeId) ?? []), edge])\n }\n }\n\n return nodeEdgeMap\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n CapacityPath,\n} from \"../../types\"\nimport type { NodePortSegment } from \"../../types/capacity-edges-to-port-segments-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { getNodeEdgeMap } from \"./getNodeEdgeMap\"\nimport { safeTransparentize } from \"../colors\"\n\n/**\n * Each Node is a square. The capacity paths indicate the nodes the trace will\n * travel through. We want to find the \"Port Segment\" that each capacity path\n * will take for each node.\n */\nexport class CapacityEdgeToPortSegmentSolver extends BaseSolver {\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n capacityPaths: CapacityPath[]\n\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n nodeEdgeMap: Map<CapacityMeshNodeId, CapacityMeshEdge[]>\n\n unprocessedNodeIds: CapacityMeshNodeId[]\n\n nodePortSegments: Map<CapacityMeshNodeId, NodePortSegment[]>\n colorMap: Record<string, string>\n\n constructor({\n nodes,\n edges,\n capacityPaths,\n colorMap,\n }: {\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n capacityPaths: CapacityPath[]\n colorMap?: Record<string, string>\n }) {\n super()\n this.nodes = nodes\n this.edges = edges\n this.nodeMap = new Map(nodes.map((node) => [node.capacityMeshNodeId, node]))\n this.nodeEdgeMap = getNodeEdgeMap(edges)\n this.capacityPaths = capacityPaths\n this.colorMap = colorMap ?? {}\n\n // We will be evaluating capacity paths\n this.unprocessedNodeIds = [\n ...new Set(capacityPaths.flatMap((path) => path.nodeIds)),\n ]\n this.nodePortSegments = new Map()\n }\n\n step() {\n const nodeId = this.unprocessedNodeIds.pop()\n if (!nodeId) {\n this.solved = true\n return\n }\n\n const pathsGoingThroughNode: Array<{\n path: CapacityPath\n indexOfNodeInPath: number\n }> = []\n for (const path of this.capacityPaths) {\n const indexOfNodeInPath = path.nodeIds.indexOf(nodeId)\n if (indexOfNodeInPath !== -1) {\n pathsGoingThroughNode.push({ path, indexOfNodeInPath })\n }\n }\n\n const node = this.nodeMap.get(nodeId)!\n const nodePortSegments: NodePortSegment[] = []\n\n for (const { path, indexOfNodeInPath } of pathsGoingThroughNode) {\n const entryNodeId = path.nodeIds[indexOfNodeInPath - 1]\n const exitNodeId = path.nodeIds[indexOfNodeInPath + 1]\n\n for (const adjNodeId of [entryNodeId, exitNodeId]) {\n const adjNode = this.nodeMap.get(adjNodeId)!\n if (!adjNode) continue\n const segment = findOverlappingSegment(node, adjNode)\n\n const mutuallyAvailableZ = adjNode.availableZ.filter((z) =>\n node.availableZ.includes(z),\n )\n\n if (mutuallyAvailableZ.length === 0) continue\n\n const portSegment: NodePortSegment = {\n capacityMeshNodeId: nodeId,\n start: segment.start,\n end: segment.end,\n connectionNames: [path.connectionName],\n availableZ: mutuallyAvailableZ,\n }\n\n nodePortSegments.push(portSegment)\n }\n }\n\n // Combine overlapping or adjacent segments on the same edge.\n const combinedSegments = combineSegments(nodePortSegments)\n this.nodePortSegments.set(nodeId, combinedSegments)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n this.nodePortSegments.forEach((segments, nodeId) => {\n const node = this.nodeMap.get(nodeId)!\n segments.forEach((segment) => {\n const isVertical = segment.start.x === segment.end.x\n const THICKNESS = 0.1 / segment.connectionNames.length\n for (let i = 0; i < segment.connectionNames.length; i++) {\n const offsetAmount =\n (i / (segment.connectionNames.length - 1 + 0.000001) - 0.5) *\n THICKNESS\n const offset = {\n x: isVertical ? offsetAmount : 0,\n y: isVertical ? 0 : offsetAmount,\n }\n const trueSegmentCenter = {\n x: (segment.start.x + segment.end.x) / 2 + offset.x,\n y: (segment.start.y + segment.end.y) / 2 + offset.y,\n }\n graphics.rects!.push({\n center: {\n x: (trueSegmentCenter.x * 6 + node.center.x) / 7,\n y: (trueSegmentCenter.y * 6 + node.center.y) / 7,\n },\n width: isVertical\n ? THICKNESS\n : Math.abs(segment.end.x - segment.start.x),\n height: isVertical\n ? Math.abs(segment.end.y - segment.start.y)\n : THICKNESS,\n fill: safeTransparentize(\n this.colorMap[segment.connectionNames[i]],\n 0.6,\n ),\n label: `${nodeId}: ${segment.connectionNames.join(\", \")}\\navailableZ: ${segment.availableZ.join(\",\")}`,\n })\n }\n })\n })\n return graphics\n }\n}\n\nfunction findOverlappingSegment(\n node: CapacityMeshNode,\n adjNode: CapacityMeshNode,\n): { start: { x: number; y: number }; end: { x: number; y: number } } {\n // Find overlapping ranges in x and y dimensions\n const xOverlap = {\n start: Math.max(\n node.center.x - node.width / 2,\n adjNode.center.x - adjNode.width / 2,\n ),\n end: Math.min(\n node.center.x + node.width / 2,\n adjNode.center.x + adjNode.width / 2,\n ),\n }\n\n const yOverlap = {\n start: Math.max(\n node.center.y - node.height / 2,\n adjNode.center.y - adjNode.height / 2,\n ),\n end: Math.min(\n node.center.y + node.height / 2,\n adjNode.center.y + adjNode.height / 2,\n ),\n }\n\n const xRange = xOverlap.end - xOverlap.start\n const yRange = yOverlap.end - yOverlap.start\n\n // If the x-range is smaller then the nodes touch vertically (common vertical edge).\n if (xRange < yRange) {\n // They are horizontally adjacent: shared vertical edge.\n const x = (xOverlap.start + xOverlap.end) / 2\n return {\n start: { x, y: yOverlap.start },\n end: { x, y: yOverlap.end },\n }\n } else {\n // Otherwise, they are vertically adjacent: shared horizontal edge.\n const y = (yOverlap.start + yOverlap.end) / 2\n return {\n start: { x: xOverlap.start, y },\n end: { x: xOverlap.end, y },\n }\n }\n}\n\n/**\n * Given a list of segments on a node, merge segments that are overlapping\n */\nfunction combineSegments(segments: NodePortSegment[]): NodePortSegment[] {\n const mergedSegments: NodePortSegment[] = []\n const remainingSegments = [...segments]\n while (remainingSegments.length > 0) {\n const segmentUnderTest = remainingSegments.pop()!\n const overlappingMergedSegment = mergedSegments.find((segment) => {\n return (\n segment.start.x === segmentUnderTest.start.x &&\n segment.start.y === segmentUnderTest.start.y &&\n segment.end.x === segmentUnderTest.end.x &&\n segment.end.y === segmentUnderTest.end.y\n )\n })\n if (overlappingMergedSegment) {\n overlappingMergedSegment.connectionNames.push(\n ...segmentUnderTest.connectionNames,\n )\n } else {\n mergedSegments.push(segmentUnderTest)\n }\n }\n return mergedSegments\n}\n","import { BaseSolver } from \"../BaseSolver\"\nimport type { NodePortSegment } from \"../../types/capacity-edges-to-port-segments-types\"\nimport type { GraphicsObject, Line } from \"graphics-debug\"\nimport type { NodeWithPortPoints } from \"../../types/high-density-types\"\nimport type { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\n\nexport interface SegmentWithAssignedPoints extends NodePortSegment {\n assignedPoints?: {\n connectionName: string\n point: { x: number; y: number; z: number }\n }[]\n}\n\n/**\n * CapacitySegmentToPointSolver:\n *\n * In each step, the solver iterates over all unsolved segments (segments\n * without points assigned for each connection). For each segment:\n *\n * - If there is only one connection, it assigns the center as the point.\n * - If there are two connections, it attempts to determine the ordering using\n * other segments within the node. If no ordering can be determined, it does nothing.\n *\n * If an iteration produces no new assignments, the solver picks the segment with\n * the fewest connections and assigns points evenly spaced along the segment,\n * ordering them alphabetically.\n */\nexport class CapacitySegmentToPointSolver extends BaseSolver {\n unsolvedSegments: SegmentWithAssignedPoints[]\n solvedSegments: (NodePortSegment & {\n assignedPoints: {\n connectionName: string\n point: { x: number; y: number; z: number }\n }[]\n })[]\n nodeMap: Record<string, CapacityMeshNode>\n colorMap: Record<string, string>\n\n // We use an extra property on segments to remember assigned points.\n // Each segment will get an added property \"assignedPoints\" which is an array of:\n // { connectionName: string, point: {x: number, y: number } }\n // This is a temporary extension used by the solver.\n constructor({\n segments,\n colorMap,\n nodes,\n }: {\n segments: NodePortSegment[]\n colorMap?: Record<string, string>\n /**\n * This isn't used by the algorithm, but allows associating metadata\n * for the result datatype (the center, width, height of the node)\n */\n nodes: CapacityMeshNode[]\n }) {\n super()\n this.MAX_ITERATIONS = 100_000\n this.unsolvedSegments = segments\n this.solvedSegments = []\n this.colorMap = colorMap ?? {}\n this.nodeMap = Object.fromEntries(\n nodes.map((node) => [node.capacityMeshNodeId, node]),\n )\n }\n\n /**\n * Perform one iteration step.\n */\n _step() {\n let updated = false\n // unsolved segments: segments without complete assignments.\n const unsolved = [...this.unsolvedSegments]\n\n // Iterate over unsolved segments.\n for (const seg of unsolved) {\n const n = seg.connectionNames.length\n // Already processed? Skip if assignedPoints exists for all connections.\n if (\"assignedPoints\" in seg && seg.assignedPoints?.length === n) continue\n\n if (n === 1) {\n // For a single connection, assign the center of the segment.\n const center = {\n x: (seg.start.x + seg.end.x) / 2,\n y: (seg.start.y + seg.end.y) / 2,\n z: seg.availableZ[0],\n }\n ;(seg as any).assignedPoints = [\n { connectionName: seg.connectionNames[0], point: center },\n ]\n // Move seg from unsolvedSegments to solvedSegments.\n this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(seg), 1)\n this.solvedSegments.push(seg as any)\n updated = true\n }\n }\n\n // If no segments were updated in this iteration, perform a fallback.\n if (!updated && unsolved.length > 0) {\n // Choose the unsolved segment with the fewest connections.\n let candidate = unsolved[0]\n for (const seg of unsolved) {\n if (seg.connectionNames.length < candidate.connectionNames.length) {\n candidate = seg\n }\n }\n // Fallback: assign points evenly spaced along the segment,\n // after sorting connection names alphabetically.\n const sortedConnections = [...candidate.connectionNames].sort()\n const dx = candidate.end.x - candidate.start.x\n const dy = candidate.end.y - candidate.start.y\n const n = sortedConnections.length\n const points: { x: number; y: number; z: number }[] = []\n // Evenly space positions using fractions of the segment distance.\n for (let i = 1; i <= n; i++) {\n const fraction = i / (n + 1)\n points.push({\n x: candidate.start.x + dx * fraction,\n y: candidate.start.y + dy * fraction,\n z: candidate.availableZ[0],\n })\n }\n ;(candidate as any).assignedPoints = sortedConnections.map(\n (conn, idx) => ({\n connectionName: conn,\n point: points[idx],\n }),\n )\n // Move candidate from unsolvedSegments to solvedSegments.\n this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(candidate), 1)\n this.solvedSegments.push(candidate as any)\n updated = true\n }\n\n // If all segments have been assigned points, mark solved.\n if (this.unsolvedSegments.length === 0) {\n this.solved = true\n }\n }\n\n /**\n * Return the assigned points for each segment.\n */\n getNodesWithPortPoints(): NodeWithPortPoints[] {\n if (!this.solved) {\n throw new Error(\n \"CapacitySegmentToPointSolver not solved, can't give port points yet\",\n )\n }\n const map = new Map<string, NodeWithPortPoints>()\n for (const seg of this.solvedSegments) {\n const nodeId = seg.capacityMeshNodeId\n const node = this.nodeMap[nodeId]\n if (!map.has(nodeId)) {\n map.set(nodeId, {\n capacityMeshNodeId: nodeId,\n portPoints: [],\n center: node.center,\n width: node.width,\n height: node.height,\n })\n }\n map.get(nodeId)!.portPoints.push(\n ...seg.assignedPoints.map((ap) => ({\n ...ap.point,\n connectionName: ap.connectionName,\n })),\n )\n }\n return Array.from(map.values())\n }\n\n /**\n * Return a GraphicsObject that visualizes the segments with assigned points.\n */\n visualize(): GraphicsObject {\n const graphics = {\n points: this.solvedSegments.flatMap((seg) =>\n seg.assignedPoints.map((ap) => ({\n x: ap.point.x,\n y: ap.point.y,\n label: [\n `${seg.capacityMeshNodeId}-${ap.connectionName}`,\n `z: ${seg.availableZ.join(\",\")}`,\n ].join(\"\\n\"),\n color: this.colorMap[ap.connectionName],\n step: 4,\n })),\n ),\n lines: this.solvedSegments.map((seg) => ({\n points: [seg.start, seg.end],\n step: 4,\n })),\n rects: [],\n circles: [],\n }\n\n // Add a dashed line connecting the assignment points with the same\n // connection name within the same node\n const dashedLines: Line[] = []\n const nodeConnections: Record<\n CapacityMeshNodeId,\n Record<string, { x: number; y: number }[]>\n > = {}\n for (const seg of this.solvedSegments) {\n const nodeId = seg.capacityMeshNodeId\n if (!nodeConnections[nodeId]) {\n nodeConnections[nodeId] = {}\n }\n for (const ap of seg.assignedPoints) {\n if (!nodeConnections[nodeId][ap.connectionName]) {\n nodeConnections[nodeId][ap.connectionName] = []\n }\n nodeConnections[nodeId][ap.connectionName].push({\n x: ap.point.x,\n y: ap.point.y,\n })\n }\n }\n for (const nodeId in nodeConnections) {\n for (const conn in nodeConnections[nodeId]) {\n const points = nodeConnections[nodeId][conn]\n if (points.length > 1) {\n dashedLines.push({\n points,\n step: 4,\n strokeDash: \"5 5\",\n strokeColor: this.colorMap[conn] || \"#000\",\n } as Line)\n }\n }\n }\n graphics.lines.push(...(dashedLines as any))\n\n return graphics\n }\n}\n","import { BaseSolver } from \"../BaseSolver\"\nimport type { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport {\n distance,\n pointToSegmentDistance,\n doSegmentsIntersect,\n} from \"@tscircuit/math-utils\"\nimport type { GraphicsObject } from \"graphics-debug\"\nimport { HighDensityHyperParameters } from \"./HighDensityHyperParameters\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\n\nexport type FutureConnection = {\n connectionName: string\n points: { x: number; y: number }[]\n}\n\nexport type Node = {\n x: number\n y: number\n z: number\n\n g: number\n h: number\n f: number\n\n parent: Node | null\n}\n\nexport class SingleHighDensityRouteSolver extends BaseSolver {\n obstacleRoutes: HighDensityIntraNodeRoute[]\n bounds: { minX: number; maxX: number; minY: number; maxY: number }\n boundsSize: { width: number; height: number }\n boundsCenter: { x: number; y: number }\n A: { x: number; y: number; z: number }\n B: { x: number; y: number; z: number }\n straightLineDistance: number\n\n viaDiameter: number\n traceThickness: number\n obstacleMargin: number\n layerCount: number\n minCellSize = 0.05\n cellStep = 0.05\n GREEDY_MULTIPLER = 1.1\n numRoutes: number\n\n VIA_PENALTY_FACTOR = 0.3\n CELL_SIZE_FACTOR: number\n\n exploredNodes: Set<string>\n\n candidates: Node[]\n\n connectionName: string\n solvedPath: HighDensityIntraNodeRoute | null = null\n\n futureConnections: FutureConnection[]\n hyperParameters: Partial<HighDensityHyperParameters>\n\n connMap?: ConnectivityMap\n\n /** For debugging/animating the exploration */\n debug_exploredNodesOrdered: string[]\n debug_nodesTooCloseToObstacle: Set<string>\n debug_nodePathToParentIntersectsObstacle: Set<string>\n\n debugEnabled = true\n\n constructor(opts: {\n connectionName: string\n obstacleRoutes: HighDensityIntraNodeRoute[]\n minDistBetweenEnteringPoints: number\n bounds: { minX: number; maxX: number; minY: number; maxY: number }\n A: { x: number; y: number; z: number }\n B: { x: number; y: number; z: number }\n viaDiameter?: number\n traceThickness?: number\n obstacleMargin?: number\n layerCount?: number\n futureConnections?: FutureConnection[]\n hyperParameters?: Partial<HighDensityHyperParameters>\n connMap?: ConnectivityMap\n }) {\n super()\n this.bounds = opts.bounds\n this.connMap = opts.connMap\n this.hyperParameters = opts.hyperParameters ?? {}\n this.CELL_SIZE_FACTOR = this.hyperParameters.CELL_SIZE_FACTOR ?? 1\n this.boundsSize = {\n width: this.bounds.maxX - this.bounds.minX,\n height: this.bounds.maxY - this.bounds.minY,\n }\n this.boundsCenter = {\n x: (this.bounds.minX + this.bounds.maxX) / 2,\n y: (this.bounds.minY + this.bounds.maxY) / 2,\n }\n this.connectionName = opts.connectionName\n this.obstacleRoutes = opts.obstacleRoutes\n this.A = opts.A\n this.B = opts.B\n this.viaDiameter = opts.viaDiameter ?? 0.6\n this.traceThickness = opts.traceThickness ?? 0.15\n this.obstacleMargin = opts.obstacleMargin ?? 0.2\n this.layerCount = opts.layerCount ?? 2\n this.exploredNodes = new Set()\n this.candidates = [\n {\n ...opts.A,\n z: opts.A.z ?? 0,\n g: 0,\n h: 0,\n f: 0,\n parent: null,\n },\n ]\n this.straightLineDistance = distance(this.A, this.B)\n this.futureConnections = opts.futureConnections ?? []\n this.MAX_ITERATIONS = 5000\n\n this.debug_exploredNodesOrdered = []\n this.debug_nodesTooCloseToObstacle = new Set()\n this.debug_nodePathToParentIntersectsObstacle = new Set()\n this.numRoutes = this.obstacleRoutes.length + this.futureConnections.length\n const bestRowOrColumnCount = Math.ceil(5 * (this.numRoutes + 1))\n let numXCells = this.boundsSize.width / this.cellStep\n let numYCells = this.boundsSize.height / this.cellStep\n\n while (numXCells * numYCells > bestRowOrColumnCount ** 2) {\n if (this.cellStep * 2 > opts.minDistBetweenEnteringPoints) {\n break\n }\n this.cellStep *= 2\n numXCells = this.boundsSize.width / this.cellStep\n numYCells = this.boundsSize.height / this.cellStep\n }\n\n this.cellStep *= this.CELL_SIZE_FACTOR\n\n if (\n this.futureConnections &&\n this.futureConnections.length === 0 &&\n this.obstacleRoutes.length === 0\n ) {\n this.handleSimpleCases()\n }\n }\n\n handleSimpleCases() {\n this.solved = true\n const { A, B } = this\n const route =\n A.z === B.z\n ? [A, B]\n : [\n A,\n { ...this.boundsCenter, z: this.A.z },\n {\n ...this.boundsCenter,\n z: B.z,\n },\n B,\n ]\n this.solvedPath = {\n connectionName: this.connectionName,\n route,\n traceThickness: this.traceThickness,\n viaDiameter: this.viaDiameter,\n vias: this.A.z === this.B.z ? [] : [this.boundsCenter],\n }\n }\n\n get viaPenaltyDistance() {\n return this.cellStep + this.straightLineDistance * this.VIA_PENALTY_FACTOR\n }\n\n isNodeTooCloseToObstacle(node: Node, margin?: number, isVia?: boolean) {\n margin ??= this.obstacleMargin\n\n if (isVia && node.parent) {\n const viasInMyRoute = this.getViasInNodePath(node.parent)\n for (const via of viasInMyRoute) {\n if (distance(node, via) < this.viaDiameter / 2 + margin) {\n return true\n }\n }\n }\n\n for (const route of this.obstacleRoutes) {\n const connectedToObstacle = this.connMap?.areIdsConnected?.(\n this.connectionName,\n route.connectionName,\n )\n\n if (!connectedToObstacle) {\n const pointPairs = getSameLayerPointPairs(route)\n for (const pointPair of pointPairs) {\n if (\n (isVia || pointPair.z === node.z) &&\n pointToSegmentDistance(node, pointPair.A, pointPair.B) <\n this.traceThickness + margin\n ) {\n return true\n }\n }\n }\n for (const via of route.vias) {\n if (distance(node, via) < this.viaDiameter / 2 + margin) {\n return true\n }\n }\n }\n\n return false\n }\n\n isNodeTooCloseToEdge(node: Node, isVia?: boolean) {\n const margin = isVia ? this.viaDiameter / 2 : this.obstacleMargin\n const tooClose =\n node.x < this.bounds.minX + margin ||\n node.x > this.bounds.maxX - margin ||\n node.y < this.bounds.minY + margin ||\n node.y > this.bounds.maxY - margin\n if (tooClose && !isVia) {\n // If it's close to B or A it's an exception\n if (\n distance(node, this.B) < margin * 2 ||\n distance(node, this.A) < margin * 2\n ) {\n return false\n }\n }\n return tooClose\n }\n\n doesPathToParentIntersectObstacle(node: Node) {\n const parent = node.parent\n if (!parent) return false\n for (const route of this.obstacleRoutes) {\n const obstacleIsConnectedToNewPath = this.connMap?.areIdsConnected?.(\n this.connectionName,\n route.connectionName,\n )\n if (obstacleIsConnectedToNewPath) continue\n for (const pointPair of getSameLayerPointPairs(route)) {\n if (pointPair.z !== node.z) continue\n if (doSegmentsIntersect(node, parent, pointPair.A, pointPair.B)) {\n return true\n }\n }\n }\n return false\n }\n\n computeH(node: Node) {\n return (\n distance(node, this.B) +\n // via penalty\n Math.abs(node.z - this.B.z) * this.viaPenaltyDistance\n )\n }\n\n computeG(node: Node) {\n return (\n (node.parent?.g ?? 0) +\n (node.z === 0 ? 0 : this.viaPenaltyDistance) +\n distance(node, node.parent!)\n )\n }\n\n computeF(g: number, h: number) {\n return g + h * this.GREEDY_MULTIPLER\n }\n\n getNodeKey(node: Node) {\n return `${Math.round(node.x / this.cellStep) * this.cellStep},${Math.round(node.y / this.cellStep) * this.cellStep},${node.z}`\n }\n\n getNeighbors(node: Node) {\n const neighbors: Node[] = []\n\n const { maxX, minX, maxY, minY } = this.bounds\n\n for (let x = -1; x <= 1; x++) {\n for (let y = -1; y <= 1; y++) {\n if (x === 0 && y === 0) continue\n\n const neighbor = {\n ...node,\n parent: node,\n x: clamp(node.x + x * this.cellStep, minX, maxX),\n y: clamp(node.y + y * this.cellStep, minY, maxY),\n }\n\n const neighborKey = this.getNodeKey(neighbor)\n\n if (this.exploredNodes.has(neighborKey)) {\n continue\n }\n\n if (this.isNodeTooCloseToObstacle(neighbor)) {\n this.debug_nodesTooCloseToObstacle.add(neighborKey)\n this.exploredNodes.add(neighborKey)\n continue\n }\n\n if (this.isNodeTooCloseToEdge(neighbor, false)) {\n this.exploredNodes.add(neighborKey)\n continue\n }\n\n if (this.doesPathToParentIntersectObstacle(neighbor)) {\n this.debug_nodePathToParentIntersectsObstacle.add(neighborKey)\n this.exploredNodes.add(neighborKey)\n continue\n }\n\n neighbor.g = this.computeG(neighbor)\n neighbor.h = this.computeH(neighbor)\n neighbor.f = this.computeF(neighbor.g, neighbor.h)\n\n neighbors.push(neighbor)\n }\n }\n\n const viaNeighbor = {\n ...node,\n parent: node,\n z: node.z === 0 ? this.layerCount - 1 : 0,\n }\n\n if (\n !this.exploredNodes.has(this.getNodeKey(viaNeighbor)) &&\n !this.isNodeTooCloseToObstacle(\n viaNeighbor,\n this.viaDiameter / 2 + this.obstacleMargin / 2,\n true,\n ) &&\n !this.isNodeTooCloseToEdge(viaNeighbor, true)\n ) {\n viaNeighbor.g = this.computeG(viaNeighbor)\n viaNeighbor.h = this.computeH(viaNeighbor)\n viaNeighbor.f = this.computeF(viaNeighbor.g, viaNeighbor.h)\n\n neighbors.push(viaNeighbor)\n }\n\n return neighbors\n }\n\n getNodePath(node: Node) {\n const path: Node[] = []\n while (node) {\n path.push(node)\n node = node.parent!\n }\n return path\n }\n\n getViasInNodePath(node: Node) {\n const path = this.getNodePath(node)\n const vias: { x: number; y: number }[] = []\n for (let i = 0; i < path.length - 1; i++) {\n if (path[i].z !== path[i + 1].z) {\n vias.push({ x: path[i].x, y: path[i].y })\n }\n }\n return vias\n }\n\n setSolvedPath(node: Node) {\n const path = this.getNodePath(node)\n path.reverse()\n\n const vias: { x: number; y: number }[] = []\n for (let i = 0; i < path.length - 1; i++) {\n if (path[i].z !== path[i + 1].z) {\n vias.push({ x: path[i].x, y: path[i].y })\n }\n }\n\n this.solvedPath = {\n connectionName: this.connectionName,\n traceThickness: this.traceThickness,\n viaDiameter: this.viaDiameter,\n route: path\n .map((node) => ({ x: node.x, y: node.y, z: node.z }))\n .concat([this.B]),\n vias,\n }\n }\n\n computeProgress(currentNode: Node, goalDist: number, isOnLayer: boolean) {\n if (!isOnLayer) goalDist += this.viaPenaltyDistance\n const goalDistPercent = 1 - goalDist / this.straightLineDistance\n\n // This is a perfectly acceptable progress metric\n // return Math.max(this.progress || 0, goalDistPercent)\n\n // Linearize because it typically gets harder towards the end\n return Math.max(\n this.progress || 0,\n // 0.112 = ~90% -> 50%\n // ~25% -> 2%\n // ~99% -> 94%\n // ~95% -> 72%\n (2 / Math.PI) *\n Math.atan((0.112 * goalDistPercent) / (1 - goalDistPercent)),\n )\n }\n\n _step() {\n this.candidates.sort((a, b) => b.f - a.f)\n let currentNode = this.candidates.pop()\n\n while (\n currentNode &&\n this.exploredNodes.has(this.getNodeKey(currentNode))\n ) {\n currentNode = this.candidates.pop()\n }\n\n if (!currentNode) {\n this.failed = true\n return\n }\n this.exploredNodes.add(this.getNodeKey(currentNode))\n this.debug_exploredNodesOrdered.push(this.getNodeKey(currentNode))\n\n const goalDist = distance(currentNode, this.B)\n\n this.progress = this.computeProgress(\n currentNode,\n goalDist,\n currentNode.z === this.B.z,\n )\n\n if (goalDist <= this.cellStep && currentNode.z === this.B.z) {\n this.solved = true\n this.setSolvedPath(currentNode)\n }\n\n const neighbors = this.getNeighbors(currentNode)\n for (const neighbor of neighbors) {\n this.candidates.push(neighbor)\n }\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n\n // Display the input port points (from nodeWithPortPoints via A and B)\n graphics.points!.push({\n x: this.A.x,\n y: this.A.y,\n label: `Input A\\nz: ${this.A.z}`,\n color: \"orange\",\n })\n graphics.points!.push({\n x: this.B.x,\n y: this.B.y,\n label: `Input B\\nz: ${this.B.z}`,\n color: \"orange\",\n })\n\n // Draw circles at future connection points\n // if (\"FUTURE_CONNECTION_PROXIMITY_VD\" in this) {\n // for (const futureConnection of this.futureConnections) {\n // for (const point of futureConnection.points) {\n // graphics.circles!.push({\n // center: point,\n // radius:\n // (this.viaDiameter *\n // (this.FUTURE_CONNECTION_PROXIMITY_VD as number)) /\n // 2,\n // // strokeColor: \"rgba(0, 255, 0, 0.3)\",\n // stroke: \"rgba(0,255,0,0.1)\",\n // label: `Future Connection: ${futureConnection.connectionName}`,\n // })\n // }\n // }\n // // Draw circles around obstacle route points\n // for (const route of this.obstacleRoutes) {\n // for (const point of [\n // route.route[0],\n // route.route[route.route.length - 1],\n // ]) {\n // graphics.circles!.push({\n // center: point,\n // radius:\n // (this.viaDiameter *\n // (this.FUTURE_CONNECTION_PROXIMITY_VD as number)) /\n // 2,\n // stroke: \"rgba(255,0,0,0.1)\",\n // label: \"Obstacle Route Point\",\n // })\n // }\n // }\n // }\n\n // Draw a line representing the direct connection between the input port points\n graphics.lines!.push({\n points: [this.A, this.B],\n strokeColor: \"rgba(255, 0, 0, 0.5)\",\n label: \"Direct Input Connection\",\n })\n\n // Show any obstacle routes as background references\n for (\n let routeIndex = 0;\n routeIndex < this.obstacleRoutes.length;\n routeIndex++\n ) {\n const route = this.obstacleRoutes[routeIndex]\n for (let i = 0; i < route.route.length - 1; i++) {\n const z = route.route[i].z\n graphics.lines!.push({\n points: [route.route[i], route.route[i + 1]],\n strokeColor:\n z === 0 ? \"rgba(255, 0, 0, 0.75)\" : \"rgba(255, 128, 0, 0.25)\",\n strokeWidth: route.traceThickness,\n label: \"Obstacle Route\",\n layer: `obstacle${routeIndex.toString()}`,\n })\n }\n }\n\n // Optionally, visualize explored nodes for debugging purposes\n for (let i = 0; i < this.debug_exploredNodesOrdered.length; i++) {\n const nodeKey = this.debug_exploredNodesOrdered[i]\n const [x, y, z] = nodeKey.split(\",\").map(Number)\n if (this.debug_nodesTooCloseToObstacle.has(nodeKey)) continue\n if (this.debug_nodePathToParentIntersectsObstacle.has(nodeKey)) continue\n graphics.rects!.push({\n center: {\n x: x + (z * this.cellStep) / 20,\n y: y + (z * this.cellStep) / 20,\n },\n fill:\n z === 0\n ? `rgba(255,0,255,${0.3 - (i / this.debug_exploredNodesOrdered.length) * 0.2})`\n : `rgba(0,0,255,${0.3 - (i / this.debug_exploredNodesOrdered.length) * 0.2})`,\n width: this.cellStep * 0.9,\n height: this.cellStep * 0.9,\n label: `Explored (z=${z})`,\n })\n }\n\n // Visualize vias from obstacle routes\n for (const route of this.obstacleRoutes) {\n for (const via of route.vias) {\n graphics.circles!.push({\n center: {\n x: via.x,\n y: via.y,\n },\n radius: this.viaDiameter / 2,\n fill: \"rgba(255, 0, 0, 0.5)\",\n label: \"Via\",\n })\n }\n }\n // If a solved route exists, display it along with via markers\n if (this.solvedPath) {\n graphics.lines!.push({\n points: this.solvedPath.route,\n strokeColor: \"green\",\n label: \"Solved Route\",\n })\n for (const via of this.solvedPath.vias) {\n graphics.circles!.push({\n center: via,\n radius: this.viaDiameter / 2,\n fill: \"green\",\n label: \"Via\",\n })\n }\n }\n\n return graphics\n }\n}\n\nfunction getSameLayerPointPairs(route: HighDensityIntraNodeRoute) {\n const pointPairs: {\n z: number\n A: { x: number; y: number; z: number }\n B: { x: number; y: number; z: number }\n }[] = []\n\n for (let i = 0; i < route.route.length - 1; i++) {\n if (route.route[i].z === route.route[i + 1].z) {\n pointPairs.push({\n z: route.route[i].z,\n A: route.route[i],\n B: route.route[i + 1],\n })\n }\n }\n\n return pointPairs\n}\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(value, max))\n}\n","import { distance } from \"@tscircuit/math-utils\"\nimport {\n SingleHighDensityRouteSolver,\n type Node,\n} from \"./SingleHighDensityRouteSolver\"\n\nexport class SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost extends SingleHighDensityRouteSolver {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR = 2\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR = 1\n FUTURE_CONNECTION_PROXIMITY_VD = 10\n MISALIGNED_DIST_PENALTY_FACTOR = 5\n VIA_PENALTY_FACTOR_2 = 1\n FLIP_TRACE_ALIGNMENT_DIRECTION = false\n\n constructor(\n opts: ConstructorParameters<typeof SingleHighDensityRouteSolver>[0],\n ) {\n super(opts)\n for (const key in opts.hyperParameters) {\n // @ts-ignore\n this[key] = opts.hyperParameters[key]\n }\n\n // Ratio of available space determines via penalty\n const viasThatCanFitHorz = this.boundsSize.width / this.viaDiameter\n this.VIA_PENALTY_FACTOR =\n 0.3 * (viasThatCanFitHorz / this.numRoutes) * this.VIA_PENALTY_FACTOR_2\n }\n\n getClosestFutureConnectionPoint(node: Node) {\n let minDist = Infinity\n let closestPoint = null\n\n for (const futureConnection of this.futureConnections) {\n for (const point of futureConnection.points) {\n const dist = distance(node, point)\n if (dist < minDist) {\n minDist = dist\n closestPoint = point\n }\n }\n }\n\n return closestPoint\n }\n\n /**\n * Rapidly approaches 0 as the goal distance approaches 0\n */\n diminishCloseToGoal(node: Node) {\n const goalDist = distance(node, this.B)\n return 1 - Math.exp((-goalDist / this.straightLineDistance) * 5)\n }\n\n getFutureConnectionPenalty(node: Node, isVia: boolean) {\n let futureConnectionPenalty = 0\n const closestFuturePoint = this.getClosestFutureConnectionPoint(node)\n const goalDist = distance(node, this.B)\n if (closestFuturePoint) {\n const distToFuturePoint = distance(node, closestFuturePoint)\n if (goalDist <= distToFuturePoint) return 0\n const maxDist = this.viaDiameter * this.FUTURE_CONNECTION_PROXIMITY_VD\n const distRatio = distToFuturePoint / maxDist\n const maxPenalty = isVia\n ? this.straightLineDistance *\n this.FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR\n : this.straightLineDistance *\n this.FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR\n futureConnectionPenalty = maxPenalty * Math.exp(-distRatio * 5)\n }\n return futureConnectionPenalty\n }\n\n computeH(node: Node) {\n const goalDist = distance(node, this.B) ** 1.6\n const goalDistRatio = goalDist / this.straightLineDistance\n\n // Base cost from original function\n const baseCost =\n goalDist + (node.z !== this.B.z ? this.viaPenaltyDistance : 0)\n\n return (\n baseCost +\n this.getFutureConnectionPenalty(node, node.z !== node.parent?.z)\n )\n }\n\n computeG(node: Node) {\n const dx = Math.abs(node.x - node.parent!.x)\n const dy = Math.abs(node.y - node.parent!.y)\n const dist = Math.sqrt(dx ** 2 + dy ** 2)\n\n const misalignedDist = !this.FLIP_TRACE_ALIGNMENT_DIRECTION\n ? node.z === 0\n ? dy\n : dx\n : node.z === 0\n ? dx\n : dy\n\n // Base cost from original function\n const baseCost =\n (node.parent?.g ?? 0) +\n (node.z === node.parent?.z ? 0 : this.viaPenaltyDistance) +\n dist +\n misalignedDist * this.MISALIGNED_DIST_PENALTY_FACTOR\n\n return (\n baseCost +\n this.getFutureConnectionPenalty(node, node.z !== node.parent?.z)\n )\n }\n}\n","export function seededRandom(seed: number) {\n // Use a simple hash to initialize both state variables\n let s = seed\n for (let i = 0; i < 10; i++) {\n s = (s * 16807) % 2147483647\n }\n let state0 = s\n\n // Use a different hash for the second state\n s = (seed * 69069 + 1) % 2147483647\n for (let i = 0; i < 10; i++) {\n s = (s * 48271) % 2147483647\n }\n let state1 = s\n\n // Return the function that generates random numbers\n return () => {\n // xorshift128+ algorithm produces much better randomness than LCG\n let s1 = state0\n const s0 = state1\n\n state0 = s0\n s1 ^= s1 << 23\n s1 ^= s1 >>> 17\n s1 ^= s0\n s1 ^= s0 >>> 26\n state1 = s1\n\n // Generate a number between 0 and 1\n const result = (state0 + state1) / 4294967296\n return result - Math.floor(result)\n }\n}\n\nexport function cloneAndShuffleArray<T>(arr: T[], seed: number): T[] {\n if (seed === 0) return arr\n const random = seededRandom(seed)\n // if (arr.length === 2) {\n // console.log(random(), seed)\n // if (random() > 0.5) return arr.slice()\n // return [arr[1], arr[0]]\n // }\n const shuffled = arr.slice() // Copy the array\n for (let i = 0; i < shuffled.length; i++) {\n const i1 = Math.floor(random() * shuffled.length)\n const i2 = Math.floor(random() * (i + 1))\n ;[shuffled[i1], shuffled[i2]] = [shuffled[i2], shuffled[i1]]\n }\n return shuffled\n}\n","import { NodeWithPortPoints } from \"lib/types/high-density-types\"\n\nexport function getBoundsFromNodeWithPortPoints(\n nodeWithPortPoints: NodeWithPortPoints,\n): { minX: number; maxX: number; minY: number; maxY: number } {\n const bounds = {\n minX: nodeWithPortPoints.center.x - nodeWithPortPoints.width / 2,\n maxX: nodeWithPortPoints.center.x + nodeWithPortPoints.width / 2,\n minY: nodeWithPortPoints.center.y - nodeWithPortPoints.height / 2,\n maxY: nodeWithPortPoints.center.y + nodeWithPortPoints.height / 2,\n }\n\n // Sometimes port points may be outside the node- this happens when there's\n // a \"leap\" to the final target or at the end or beginning of a trace when\n // we're wrapping up\n for (const pt of nodeWithPortPoints.portPoints) {\n if (pt.x < bounds.minX) {\n bounds.minX = pt.x\n }\n if (pt.x > bounds.maxX) {\n bounds.maxX = pt.x\n }\n if (pt.y < bounds.minY) {\n bounds.minY = pt.y\n }\n if (pt.y > bounds.maxY) {\n bounds.maxY = pt.y\n }\n }\n\n return bounds\n}\n","import { NodeWithPortPoints } from \"lib/types/high-density-types\"\n\nexport const getMinDistBetweenEnteringPoints = (node: NodeWithPortPoints) => {\n let minDist = Infinity\n const points = node.portPoints\n\n // Compare each point with every other point\n for (let i = 0; i < points.length; i++) {\n for (let j = i + 1; j < points.length; j++) {\n const p1 = points[i]\n const p2 = points[j]\n\n // Calculate Euclidean distance between points\n const dist = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2)\n\n minDist = Math.min(minDist, dist)\n }\n }\n\n return minDist === Infinity ? 0 : minDist\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport type {\n HighDensityIntraNodeRoute,\n NodeWithPortPoints,\n} from \"../../types/high-density-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { SingleHighDensityRouteSolver } from \"./SingleHighDensityRouteSolver\"\nimport { safeTransparentize } from \"../colors\"\nimport { SingleHighDensityRouteSolver2_CenterAttraction } from \"./SingleHighDensityRouteSolver2_CenterAttraction\"\nimport { SingleHighDensityRouteSolver3_RepelEndpoints } from \"./SingleHighDensityRouteSolver3_RepellingEndpoints\"\nimport { SingleHighDensityRouteSolver4_RepelEdgeViaFuture } from \"./SingleHighDensityRouteSolver4_RepelEdgeViaFuture\"\nimport { SingleHighDensityRouteSolver5_BinaryFutureConnectionPenalty } from \"./SingleHighDensityRouteSolver5_BinaryFutureConnectionPenalty\"\nimport { SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost } from \"./SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost\"\nimport { HighDensityHyperParameters } from \"./HighDensityHyperParameters\"\nimport { cloneAndShuffleArray } from \"lib/utils/cloneAndShuffleArray\"\nimport { SingleHighDensityRouteSolver7_CostPoint } from \"./SingleHighDensityRouteSolver7_CostPoint\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { getBoundsFromNodeWithPortPoints } from \"lib/utils/getBoundsFromNodeWithPortPoints\"\nimport { getIntraNodeCrossings } from \"lib/utils/getIntraNodeCrossings\"\nimport { getMinDistBetweenEnteringPoints } from \"lib/utils/getMinDistBetweenEnteringPoints\"\n\nexport class IntraNodeRouteSolver extends BaseSolver {\n nodeWithPortPoints: NodeWithPortPoints\n colorMap: Record<string, string>\n unsolvedConnections: {\n connectionName: string\n points: { x: number; y: number; z: number }[]\n }[]\n\n totalConnections: number\n solvedRoutes: HighDensityIntraNodeRoute[]\n failedSubSolvers: SingleHighDensityRouteSolver[]\n hyperParameters: Partial<HighDensityHyperParameters>\n minDistBetweenEnteringPoints: number\n\n activeSolver: SingleHighDensityRouteSolver | null = null\n connMap?: ConnectivityMap\n\n // Legacy compat\n get failedSolvers() {\n return this.failedSubSolvers\n }\n\n constructor(params: {\n nodeWithPortPoints: NodeWithPortPoints\n colorMap?: Record<string, string>\n hyperParameters?: Partial<HighDensityHyperParameters>\n connMap?: ConnectivityMap\n }) {\n const { nodeWithPortPoints, colorMap } = params\n super()\n this.nodeWithPortPoints = nodeWithPortPoints\n this.colorMap = colorMap ?? {}\n this.solvedRoutes = []\n this.hyperParameters = params.hyperParameters ?? {}\n this.failedSubSolvers = []\n this.connMap = params.connMap\n const unsolvedConnectionsMap: Map<\n string,\n { x: number; y: number; z: number }[]\n > = new Map()\n for (const { connectionName, x, y, z } of nodeWithPortPoints.portPoints) {\n unsolvedConnectionsMap.set(connectionName, [\n ...(unsolvedConnectionsMap.get(connectionName) ?? []),\n { x, y, z: z ?? 0 },\n ])\n }\n this.unsolvedConnections = Array.from(\n unsolvedConnectionsMap.entries().map(([connectionName, points]) => ({\n connectionName,\n points,\n })),\n )\n\n if (this.hyperParameters.SHUFFLE_SEED) {\n this.unsolvedConnections = cloneAndShuffleArray(\n this.unsolvedConnections,\n this.hyperParameters.SHUFFLE_SEED ?? 0,\n )\n\n // Shuffle the starting and ending points of each connection (some\n // algorithms are biased towards the start or end of a trace)\n this.unsolvedConnections = this.unsolvedConnections.map(\n ({ points, ...rest }, i) => ({\n ...rest,\n points: cloneAndShuffleArray(\n points,\n i * 7117 + (this.hyperParameters.SHUFFLE_SEED ?? 0),\n ),\n }),\n )\n }\n\n this.totalConnections = this.unsolvedConnections.length\n this.MAX_ITERATIONS = 1_000 * this.totalConnections ** 1.5\n\n this.minDistBetweenEnteringPoints = getMinDistBetweenEnteringPoints(\n this.nodeWithPortPoints,\n )\n\n // const {\n // numEntryExitLayerChanges,\n // numSameLayerCrossings,\n // numTransitionPairCrossings,\n // numTransitions,\n // } = getIntraNodeCrossings(this.nodeWithPortPoints)\n\n // if (\n // numSameLayerCrossings === 0 &&\n // numTransitions === 0 &&\n // numEntryExitLayerChanges === 0\n // ) {\n // this.handleSimpleNoCrossingsCase()\n // }\n }\n\n // handleSimpleNoCrossingsCase() {\n // // TODO check to make sure there are no crossings due to trace width\n // this.solved = true\n // this.solvedRoutes = this.unsolvedConnections.map(\n // ({ connectionName, points }) => ({\n // connectionName,\n // route: points,\n // traceThickness: 0.1, // TODO load from hyperParameters\n // viaDiameter: 0.6,\n // vias: [],\n // }),\n // )\n // this.unsolvedConnections = []\n // }\n\n computeProgress() {\n return (\n (this.solvedRoutes.length + (this.activeSolver?.progress || 0)) /\n this.totalConnections\n )\n }\n\n _step() {\n if (this.activeSolver) {\n this.activeSolver.step()\n this.progress = this.computeProgress()\n if (this.activeSolver.solved) {\n this.solvedRoutes.push(this.activeSolver.solvedPath!)\n this.activeSolver = null\n } else if (this.activeSolver.failed) {\n this.failedSubSolvers.push(this.activeSolver)\n this.activeSolver = null\n this.error = this.failedSubSolvers.map((s) => s.error).join(\"\\n\")\n this.failed = true\n }\n return\n }\n\n const unsolvedConnection = this.unsolvedConnections.pop()\n this.progress = this.computeProgress()\n if (!unsolvedConnection) {\n this.solved = this.failedSubSolvers.length === 0\n return\n }\n if (unsolvedConnection.points.length === 1) {\n return\n }\n if (unsolvedConnection.points.length === 2) {\n const [A, B] = unsolvedConnection.points\n if (A.x === B.x && A.y === B.y && A.z === B.z) {\n return\n }\n }\n const { connectionName, points } = unsolvedConnection\n this.activeSolver =\n new SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost({\n connectionName,\n minDistBetweenEnteringPoints: this.minDistBetweenEnteringPoints,\n bounds: getBoundsFromNodeWithPortPoints(this.nodeWithPortPoints),\n A: { x: points[0].x, y: points[0].y, z: points[0].z },\n B: {\n x: points[points.length - 1].x,\n y: points[points.length - 1].y,\n z: points[points.length - 1].z,\n },\n obstacleRoutes: this.solvedRoutes,\n futureConnections: this.unsolvedConnections,\n layerCount: 2,\n hyperParameters: this.hyperParameters,\n connMap: this.connMap,\n })\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n\n // Draw node bounds\n // graphics.rects!.push({\n // center: {\n // x: this.nodeWithPortPoints.center.x,\n // y: this.nodeWithPortPoints.center.y,\n // },\n // width: this.nodeWithPortPoints.width,\n // height: this.nodeWithPortPoints.height,\n // stroke: \"gray\",\n // fill: \"transparent\",\n // })\n\n // Visualize input nodeWithPortPoints\n for (const pt of this.nodeWithPortPoints.portPoints) {\n graphics.points!.push({\n x: pt.x,\n y: pt.y,\n label: [pt.connectionName, `layer: ${pt.z}`].join(\"\\n\"),\n color: this.colorMap[pt.connectionName] ?? \"blue\",\n })\n }\n\n // Visualize solvedRoutes\n for (\n let routeIndex = 0;\n routeIndex < this.solvedRoutes.length;\n routeIndex++\n ) {\n const route = this.solvedRoutes[routeIndex]\n if (route.route.length > 0) {\n const routeColor = this.colorMap[route.connectionName] ?? \"blue\"\n\n // Draw route segments between points\n for (let i = 0; i < route.route.length - 1; i++) {\n const p1 = route.route[i]\n const p2 = route.route[i + 1]\n\n graphics.lines!.push({\n points: [p1, p2],\n strokeColor:\n p1.z === 0\n ? safeTransparentize(routeColor, 0.2)\n : safeTransparentize(routeColor, 0.8),\n layer: `route-layer-${p1.z}`,\n step: routeIndex,\n strokeWidth: route.traceThickness,\n })\n }\n\n // Draw vias\n for (const via of route.vias) {\n graphics.circles!.push({\n center: { x: via.x, y: via.y },\n radius: route.viaDiameter / 2,\n fill: safeTransparentize(routeColor, 0.5),\n layer: \"via\",\n step: routeIndex,\n })\n }\n }\n }\n\n // Draw border around the node\n const bounds = getBoundsFromNodeWithPortPoints(this.nodeWithPortPoints)\n const { minX, minY, maxX, maxY } = bounds\n\n // Draw the four sides of the border with thin red lines\n graphics.lines!.push({\n points: [\n { x: minX, y: minY },\n { x: maxX, y: minY },\n { x: maxX, y: maxY },\n { x: minX, y: maxY },\n { x: minX, y: minY },\n ],\n strokeColor: \"rgba(255, 0, 0, 0.25)\",\n strokeDash: \"4 4\",\n layer: \"border\",\n })\n\n return graphics\n }\n}\n","import { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"./BaseSolver\"\n\nexport type SupervisedSolver<T extends BaseSolver> = {\n hyperParameters: any\n solver: T\n h: number\n g: number\n f: number\n}\n\nexport type HyperParameterDef = {\n name: string\n possibleValues: Array<any>\n}\n\n/**\n * The HyperParameterSupervisorSolver is a solver that solves a problem by\n * running competing solvers with different hyperparameters.\n *\n * As solvers make progress, the supervisor will allow the best solvers to run\n * for more iterations, prioritizing the solvers that are working the best.\n */\nexport class HyperParameterSupervisorSolver<\n T extends BaseSolver,\n> extends BaseSolver {\n GREEDY_MULTIPLIER = 1.2\n MIN_SUBSTEPS = 1\n\n supervisedSolvers?: Array<SupervisedSolver<T>>\n\n getHyperParameterDefs(): Array<HyperParameterDef> {\n throw new Error(\"Not implemented\")\n }\n\n getCombinationDefs(): Array<Array<string>> | null {\n return null\n }\n\n getHyperParameterCombinations(\n hyperParameterDefs?: Array<HyperParameterDef>,\n ): Array<Record<string, any>> {\n if (!hyperParameterDefs) {\n hyperParameterDefs = this.getHyperParameterDefs()\n }\n const combinations: Array<Record<string, any>> = []\n // Base case - no more hyperparameters to combine\n if (hyperParameterDefs.length === 0) {\n return [{}]\n }\n\n // Take first hyperparameter definition\n const [currentDef, ...remainingDefs] = hyperParameterDefs\n\n // Get combinations for remaining hyperparameters\n const subCombinations = this.getHyperParameterCombinations(remainingDefs)\n\n // For each possible value of current hyperparameter,\n // combine with all sub-combinations\n currentDef.possibleValues.forEach((value) => {\n subCombinations.forEach((subCombo) => {\n combinations.push({\n ...subCombo,\n ...value,\n })\n })\n })\n\n return combinations\n }\n\n initializeSolvers() {\n const hyperParameterDefs = this.getHyperParameterDefs()\n\n const combinationDefs = this.getCombinationDefs() ?? [\n hyperParameterDefs.map((def) => def.name),\n ]\n\n this.supervisedSolvers = []\n for (const combinationDef of combinationDefs) {\n const hyperParameterCombinations = this.getHyperParameterCombinations(\n hyperParameterDefs.filter((hpd) => combinationDef.includes(hpd.name)),\n )\n\n for (const hyperParameters of hyperParameterCombinations) {\n const solver = this.generateSolver(hyperParameters)\n this.supervisedSolvers.push({\n hyperParameters,\n solver,\n h: 0,\n g: 0,\n f: 0,\n })\n }\n }\n }\n\n generateSolver(hyperParameters: any): T {\n throw new Error(\"Not implemented\")\n }\n\n computeG(solver: T) {\n return solver.iterations / solver.MAX_ITERATIONS\n }\n\n computeH(solver: T) {\n return 1 - (solver.progress || 0)\n }\n\n computeF(g: number, h: number) {\n return g + h * this.GREEDY_MULTIPLIER\n }\n\n getSupervisedSolverWithBestFitness(): SupervisedSolver<T> | null {\n let bestFitness = Infinity\n let bestSolver: SupervisedSolver<T> | null = null\n for (const supervisedSolver of this.supervisedSolvers ?? []) {\n if (supervisedSolver.solver.solved) {\n return supervisedSolver\n }\n if (supervisedSolver.solver.failed) {\n continue\n }\n const fitness = supervisedSolver.f\n if (fitness < bestFitness) {\n bestFitness = fitness\n bestSolver = supervisedSolver\n }\n }\n return bestSolver\n }\n\n _step() {\n if (!this.supervisedSolvers) this.initializeSolvers()\n\n const supervisedSolver = this.getSupervisedSolverWithBestFitness()\n\n if (!supervisedSolver) {\n this.failed = true\n this.error = \"All solvers failed\"\n return\n }\n\n for (let i = 0; i < this.MIN_SUBSTEPS; i++) {\n supervisedSolver.solver.step()\n }\n\n supervisedSolver.g = this.computeG(supervisedSolver.solver)\n supervisedSolver.h = this.computeH(supervisedSolver.solver)\n supervisedSolver.f = this.computeF(supervisedSolver.g, supervisedSolver.h)\n\n if (supervisedSolver.solver.solved) {\n this.solved = true\n this.onSolve?.(supervisedSolver)\n }\n }\n\n onSolve(solver: SupervisedSolver<T>) {}\n\n visualize(): GraphicsObject {\n const bestSupervisedSolver = this.getSupervisedSolverWithBestFitness()\n let graphics: GraphicsObject = {\n lines: [],\n circles: [],\n points: [],\n rects: [],\n }\n\n if (bestSupervisedSolver) {\n graphics = bestSupervisedSolver.solver.visualize()\n }\n return graphics\n }\n}\n","import {\n HighDensityIntraNodeRoute,\n NodeWithPortPoints,\n} from \"lib/types/high-density-types\"\nimport { IntraNodeRouteSolver } from \"../HighDensitySolver/IntraNodeSolver\"\nimport {\n HyperParameterSupervisorSolver,\n SupervisedSolver,\n} from \"../HyperParameterSupervisorSolver\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\n\nexport class HyperSingleIntraNodeSolver extends HyperParameterSupervisorSolver<IntraNodeRouteSolver> {\n constructorParams: ConstructorParameters<typeof IntraNodeRouteSolver>[0]\n solvedRoutes: HighDensityIntraNodeRoute[] = []\n nodeWithPortPoints: NodeWithPortPoints\n\n constructor(opts: ConstructorParameters<typeof IntraNodeRouteSolver>[0]) {\n super()\n this.nodeWithPortPoints = opts.nodeWithPortPoints\n this.constructorParams = opts\n this.MAX_ITERATIONS = 250_000\n this.GREEDY_MULTIPLIER = 5\n this.MIN_SUBSTEPS = 100\n }\n\n getCombinationDefs() {\n return [\n [\"majorCombinations\", \"orderings6\", \"cellSizeFactor\"],\n [\"noVias\"],\n [\"orderings50\"],\n [\"flipTraceAlignmentDirection\", \"orderings6\"],\n ]\n }\n\n getHyperParameterDefs() {\n return [\n {\n name: \"majorCombinations\",\n possibleValues: [\n {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR: 2,\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR: 1,\n FUTURE_CONNECTION_PROXIMITY_VD: 10,\n MISALIGNED_DIST_PENALTY_FACTOR: 5,\n },\n {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR: 1,\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR: 0.5,\n FUTURE_CONNECTION_PROXIMITY_VD: 5,\n MISALIGNED_DIST_PENALTY_FACTOR: 2,\n },\n {\n FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR: 10,\n FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR: 1,\n FUTURE_CONNECTION_PROXIMITY_VD: 5,\n MISALIGNED_DIST_PENALTY_FACTOR: 10,\n VIA_PENALTY_FACTOR_2: 1,\n },\n ],\n },\n {\n name: \"orderings6\",\n possibleValues: [\n {\n SHUFFLE_SEED: 0,\n },\n {\n SHUFFLE_SEED: 1,\n },\n {\n SHUFFLE_SEED: 2,\n },\n {\n SHUFFLE_SEED: 3,\n },\n {\n SHUFFLE_SEED: 4,\n },\n {\n SHUFFLE_SEED: 5,\n },\n ],\n },\n {\n name: \"cellSizeFactor\",\n possibleValues: [\n {\n CELL_SIZE_FACTOR: 0.5,\n },\n {\n CELL_SIZE_FACTOR: 1,\n },\n ],\n },\n {\n name: \"flipTraceAlignmentDirection\",\n possibleValues: [\n {\n FLIP_TRACE_ALIGNMENT_DIRECTION: true,\n },\n ],\n },\n {\n name: \"noVias\",\n possibleValues: [\n {\n CELL_SIZE_FACTOR: 2,\n VIA_PENALTY_FACTOR_2: 10,\n },\n ],\n },\n {\n name: \"orderings50\",\n possibleValues: Array.from({ length: 50 }, (_, i) => ({\n SHUFFLE_SEED: 100 + i,\n })),\n },\n ]\n }\n\n computeG(solver: IntraNodeRouteSolver) {\n return (\n solver.iterations / 10_000 // + solver.hyperParameters.SHUFFLE_SEED! * 0.05\n )\n }\n\n computeH(solver: IntraNodeRouteSolver) {\n return 1 - (solver.progress || 0)\n }\n\n generateSolver(hyperParameters: any): IntraNodeRouteSolver {\n return new IntraNodeRouteSolver({\n ...this.constructorParams,\n hyperParameters,\n })\n }\n\n onSolve(solver: SupervisedSolver<IntraNodeRouteSolver>) {\n this.solvedRoutes = solver.solver.solvedRoutes\n }\n}\n","interface RoutePoint {\n x: number\n y: number\n z: number\n}\n\ninterface MergedSegment {\n points: { x: number; y: number }[]\n z: number\n connectionName: string\n color: string\n}\n\n/**\n * Merges consecutive route points with the same z-coordinate into segments\n * @param route Array of route points\n * @param connectionName Name of the connection\n * @param color Color for the segment\n * @returns Array of merged segments\n */\nexport function mergeRouteSegments(\n route: RoutePoint[],\n connectionName: string,\n color: string,\n): MergedSegment[] {\n const segments: MergedSegment[] = []\n let currentSegment: MergedSegment | null = null\n\n for (let i = 0; i < route.length; i++) {\n const point = route[i]\n\n if (!currentSegment) {\n currentSegment = {\n points: [{ x: point.x, y: point.y }],\n z: point.z,\n connectionName,\n color,\n }\n } else if (currentSegment.z === point.z) {\n currentSegment.points.push({ x: point.x, y: point.y })\n } else {\n segments.push(currentSegment)\n currentSegment = {\n points: [{ x: point.x, y: point.y }],\n z: point.z,\n connectionName,\n color,\n }\n }\n\n // Add final segment if we're at the last point\n if (i === route.length - 1 && currentSegment) {\n segments.push(currentSegment)\n }\n }\n\n return segments\n}\n","import type {\n HighDensityIntraNodeRoute,\n NodeWithPortPoints,\n} from \"../../types/high-density-types\"\nimport type { GraphicsObject } from \"graphics-debug\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { safeTransparentize } from \"../colors\"\nimport { IntraNodeRouteSolver } from \"./IntraNodeSolver\"\nimport { HyperSingleIntraNodeSolver } from \"../HyperHighDensitySolver/HyperSingleIntraNodeSolver\"\nimport { combineVisualizations } from \"lib/utils/combineVisualizations\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { mergeRouteSegments } from \"lib/utils/mergeRouteSegments\"\n\nexport class HighDensitySolver extends BaseSolver {\n unsolvedNodePortPoints: NodeWithPortPoints[]\n routes: HighDensityIntraNodeRoute[]\n colorMap: Record<string, string>\n\n // Defaults as specified: viaDiameter of 0.6 and traceThickness of 0.15\n readonly defaultViaDiameter = 0.6\n readonly defaultTraceThickness = 0.15\n\n failedSolvers: (IntraNodeRouteSolver | HyperSingleIntraNodeSolver)[]\n activeSubSolver: IntraNodeRouteSolver | HyperSingleIntraNodeSolver | null =\n null\n connMap?: ConnectivityMap\n\n constructor({\n nodePortPoints,\n colorMap,\n connMap,\n }: {\n nodePortPoints: NodeWithPortPoints[]\n colorMap?: Record<string, string>\n connMap?: ConnectivityMap\n }) {\n super()\n this.unsolvedNodePortPoints = nodePortPoints\n this.colorMap = colorMap ?? {}\n this.connMap = connMap\n this.routes = []\n this.failedSolvers = []\n this.MAX_ITERATIONS = 1e6\n }\n\n /**\n * Each iteration, pop an unsolved node and attempt to find the routes inside\n * of it.\n */\n _step() {\n if (this.activeSubSolver) {\n this.activeSubSolver.step()\n if (this.activeSubSolver.solved) {\n this.routes.push(...this.activeSubSolver.solvedRoutes)\n this.activeSubSolver = null\n } else if (this.activeSubSolver.failed) {\n this.failedSolvers.push(this.activeSubSolver)\n this.activeSubSolver = null\n }\n return\n }\n if (this.unsolvedNodePortPoints.length === 0) {\n this.solved = true\n return\n }\n const node = this.unsolvedNodePortPoints.pop()!\n\n this.activeSubSolver = new HyperSingleIntraNodeSolver({\n nodeWithPortPoints: node,\n colorMap: this.colorMap,\n connMap: this.connMap,\n })\n }\n\n visualize(): GraphicsObject {\n let graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n for (const route of this.routes) {\n // Merge segments based on z-coordinate\n const mergedSegments = mergeRouteSegments(\n route.route,\n route.connectionName,\n this.colorMap[route.connectionName],\n )\n\n // Add merged segments to graphics\n for (const segment of mergedSegments) {\n graphics.lines!.push({\n points: segment.points,\n label: segment.connectionName,\n strokeColor:\n segment.z === 0\n ? segment.color\n : safeTransparentize(segment.color, 0.75),\n strokeWidth: route.traceThickness,\n strokeDash: segment.z !== 0 ? \"10, 5\" : undefined,\n })\n }\n for (const via of route.vias) {\n graphics.circles!.push({\n center: via,\n radius: route.viaDiameter / 2,\n fill: this.colorMap[route.connectionName],\n label: `${route.connectionName} via`,\n })\n }\n }\n for (const solver of this.failedSolvers) {\n const node = solver.nodeWithPortPoints\n // Group port points by connectionName\n const connectionGroups: Record<\n string,\n { x: number; y: number; z: number }[]\n > = {}\n for (const pt of node.portPoints) {\n if (!connectionGroups[pt.connectionName]) {\n connectionGroups[pt.connectionName] = []\n }\n connectionGroups[pt.connectionName].push({ x: pt.x, y: pt.y, z: pt.z })\n }\n\n for (const [connectionName, points] of Object.entries(connectionGroups)) {\n for (let i = 0; i < points.length - 1; i++) {\n const start = points[i]\n const end = points[i + 1]\n graphics.lines!.push({\n points: [start, end],\n strokeColor: \"red\",\n strokeDash: \"10, 5\",\n })\n }\n }\n }\n if (this.activeSubSolver) {\n graphics = combineVisualizations(\n graphics,\n this.activeSubSolver.visualize(),\n )\n }\n return graphics\n }\n}\n","type NodeId = string\n\nexport function findConnectedNetworks(\n connections: Array<NodeId[]>,\n): Record<string, string[]> {\n const networks: Map<string, Set<string>> = new Map()\n let netCounter = 0\n\n function getOrCreateNetwork(nodeId: string): Set<string> {\n for (const [, network] of networks) {\n if (network.has(nodeId)) {\n return network\n }\n }\n const newNetwork = new Set<string>()\n networks.set(`connectivity_net${netCounter++}`, newNetwork)\n return newNetwork\n }\n\n for (const connection of connections) {\n let network: Set<string> | null = null\n\n for (const nodeId of connection) {\n if (!network) {\n network = getOrCreateNetwork(nodeId)\n } else if (!network.has(nodeId)) {\n const existingNetwork = getOrCreateNetwork(nodeId)\n if (existingNetwork !== network) {\n // Merge networks\n for (const node of existingNetwork) {\n network.add(node)\n }\n networks.delete(\n Array.from(networks.entries()).find(\n ([, net]) => net === existingNetwork,\n )![0],\n )\n }\n }\n network.add(nodeId)\n }\n }\n\n return Object.fromEntries(\n Array.from(networks.entries()).map(([netId, connectedNodes]) => [\n netId,\n Array.from(connectedNodes),\n ]),\n )\n}\n","export class ConnectivityMap {\n netMap: Record<string, string[]>\n\n idToNetMap: Record<string, string>\n\n constructor(netMap: Record<string, string[]>) {\n this.netMap = netMap\n this.idToNetMap = {}\n for (const [netId, ids] of Object.entries(netMap)) {\n for (const id of ids) {\n this.idToNetMap[id] = netId\n }\n }\n }\n\n addConnections(connections: string[][]) {\n for (const connection of connections) {\n const existingNets = new Set<string>()\n\n // Find all existing nets for the connection\n for (const id of connection) {\n const existingNetId = this.idToNetMap[id]\n if (existingNetId) {\n existingNets.add(existingNetId)\n }\n }\n\n let targetNetId: string\n\n if (existingNets.size === 0) {\n // If no existing nets found, create a new one\n targetNetId = `connectivity_net${Object.keys(this.netMap).length}`\n this.netMap[targetNetId] = []\n } else if (existingNets.size === 1) {\n // If only one existing net found, use it\n targetNetId =\n existingNets.values().next().value ??\n `connectivity_net${Object.keys(this.netMap).length}`\n } else {\n // If multiple nets found, merge them\n targetNetId =\n existingNets.values().next().value ??\n `connectivity_net${Object.keys(this.netMap).length}`\n for (const netId of existingNets) {\n if (netId !== targetNetId) {\n this.netMap[targetNetId].push(...this.netMap[netId])\n\n // we could delete the net, but setting it to reference the other net\n // will make sure any usage of the old netId will still work\n this.netMap[netId] = this.netMap[targetNetId]\n for (const id of this.netMap[targetNetId]) {\n this.idToNetMap[id] = targetNetId\n }\n }\n }\n }\n\n // Add all ids to the target net\n for (const id of connection) {\n if (!this.netMap[targetNetId].includes(id)) {\n this.netMap[targetNetId].push(id)\n }\n this.idToNetMap[id] = targetNetId\n }\n }\n }\n\n getIdsConnectedToNet(netId: string): string[] {\n return this.netMap[netId] || []\n }\n\n getNetConnectedToId(id: string): string | undefined {\n return this.idToNetMap[id]\n }\n\n areIdsConnected(id1: string, id2: string): boolean {\n if (id1 === id2) return true\n const netId1 = this.getNetConnectedToId(id1)\n if (!netId1) return false\n const netId2 = this.getNetConnectedToId(id2)\n if (!netId2) return false\n return netId1 === netId2 || netId2 === id1 || netId2 === id1\n }\n\n areAllIdsConnected(ids: string[]): boolean {\n const netId = this.getNetConnectedToId(ids[0])\n for (const id of ids) {\n const nextNetId = this.getNetConnectedToId(id)\n if (nextNetId === undefined) {\n return false\n }\n if (nextNetId !== netId) {\n return false\n }\n }\n return true\n }\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getSourcePortConnectivityMapFromCircuitJson = (\n circuitJson: AnyCircuitElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push([\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ])\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getFullConnectivityMapFromCircuitJson = (\n circuitJson: AnyCircuitElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push(\n [\n element.source_trace_id,\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ].filter(Boolean),\n )\n } else if (element.type === \"pcb_port\") {\n const { pcb_port_id, source_port_id } = element\n if (source_port_id && pcb_port_id) {\n connections.push([source_port_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_smtpad\") {\n const { pcb_smtpad_id, pcb_port_id } = element\n if (pcb_port_id && pcb_smtpad_id) {\n connections.push([pcb_smtpad_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_plated_hole\") {\n const { pcb_plated_hole_id, pcb_port_id } = element\n if (pcb_port_id && pcb_plated_hole_id) {\n connections.push([pcb_plated_hole_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_trace\") {\n const { pcb_trace_id, source_trace_id } = element\n if (source_trace_id && pcb_trace_id) {\n connections.push([pcb_trace_id, source_trace_id])\n }\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnyCircuitElement, PCBPort, PCBTrace } from \"circuit-json\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\nimport { doesLineIntersectLine } from \"@tscircuit/math-utils\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\n\n/**\n * A PCB Connectivity Map is a connectivity map that has analyzed what traces and ports are actually connected on the\n * PCB.\n *\n * This is useful for determining how to route a trace on the PCB. For example, you may want to determine where the\n * nearest connected net point is to connect an unrouted pin.\n */\nexport class PcbConnectivityMap {\n circuitJson: AnyCircuitElement[]\n traceIdToElm: Map<string, PCBTrace>\n portIdToElm: Map<string, PCBPort>\n connMap: ConnectivityMap\n\n constructor(circuitJson?: AnyCircuitElement[]) {\n this.circuitJson = circuitJson || []\n this.traceIdToElm = new Map()\n this.portIdToElm = new Map()\n if (circuitJson) {\n this._buildTraceMap()\n this._buildPortMap()\n this.connMap = this._buildTraceConnectivityMap()\n } else {\n this.connMap = new ConnectivityMap({})\n }\n }\n\n private _buildPortMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_port\") {\n this.portIdToElm.set(element.pcb_port_id, element as PCBPort)\n }\n }\n }\n\n private _buildTraceMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_trace\") {\n this.traceIdToElm.set(element.pcb_trace_id, element as PCBTrace)\n }\n }\n }\n\n private _buildTraceConnectivityMap(): ConnectivityMap {\n const connections: string[][] = []\n const traceIds = Array.from(this.traceIdToElm.keys())\n\n for (let i = 0; i < traceIds.length; i++) {\n for (let j = i + 1; j < traceIds.length; j++) {\n const trace1 = this.traceIdToElm.get(traceIds[i])!\n const trace2 = this.traceIdToElm.get(traceIds[j])!\n if (this._arePcbTracesConnected(trace1, trace2)) {\n connections.push([traceIds[i], traceIds[j]])\n }\n }\n }\n\n for (const port of this.portIdToElm.values()) {\n for (const trace of this.traceIdToElm.values()) {\n for (const rp of trace.route) {\n if (rp.route_type === \"wire\") {\n if (rp.start_pcb_port_id === port.pcb_port_id) {\n connections.push([port.pcb_port_id, trace.pcb_trace_id])\n } else if (rp.end_pcb_port_id === port.pcb_port_id) {\n connections.push([trace.pcb_trace_id, port.pcb_port_id])\n }\n }\n }\n }\n }\n\n return new ConnectivityMap(findConnectedNetworks(connections))\n }\n\n addTrace(trace: PCBTrace) {\n this.traceIdToElm.set(trace.pcb_trace_id, trace)\n const connections: string[][] = []\n for (const rp of trace.route) {\n if (rp.route_type === \"wire\") {\n if (rp.start_pcb_port_id) {\n connections.push([rp.start_pcb_port_id, trace.pcb_trace_id])\n }\n if (rp.end_pcb_port_id) {\n connections.push([rp.end_pcb_port_id, trace.pcb_trace_id])\n }\n }\n }\n\n this.connMap.addConnections(connections)\n }\n\n _arePcbTracesConnected(trace1: PCBTrace, trace2: PCBTrace): boolean {\n for (let i = 0; i < trace1.route.length - 1; i++) {\n const segment1A = trace1.route[i]\n const segment1B = trace1.route[i + 1]\n if (segment1A.route_type !== \"wire\") continue\n if (segment1B.route_type !== \"wire\") continue\n for (let j = 0; j < trace2.route.length - 1; j++) {\n const segment2A = trace2.route[j]\n const segment2B = trace2.route[j + 1]\n\n if (segment2A.route_type !== \"wire\") continue\n if (segment2B.route_type !== \"wire\") continue\n\n // Check if lines are overlapping\n const isOverlapping = doesLineIntersectLine(\n [segment1A, segment1B],\n [segment2A, segment2B],\n {\n lineThickness: (segment1A.width + segment2A.width) / 2,\n },\n )\n if (isOverlapping) {\n return true\n }\n }\n }\n return false\n }\n\n areTracesConnected(traceId1: string, traceId2: string): boolean {\n return this.connMap.areIdsConnected(traceId1, traceId2)\n }\n\n getAllTracesConnectedToTrace(traceId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(traceId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n\n getAllTracesConnectedToPort(portId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(portId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n}\n","import { SimpleRouteJson } from \"lib/types\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\n\nexport const getConnectivityMapFromSimpleRouteJson = (srj: SimpleRouteJson) => {\n const connMap = new ConnectivityMap({})\n for (const connection of srj.connections) {\n for (const point of connection.pointsToConnect) {\n if (\"pcb_port_id\" in point && point.pcb_port_id) {\n connMap.addConnections([[connection.name, point.pcb_port_id as string]])\n }\n }\n }\n return connMap\n}\n","import { CapacityMeshNode } from \"lib/types/capacity-mesh-types\"\n\n/**\n * Calculate the capacity of a node based on its width\n *\n * This capacity corresponds to how many vias the node can fit, tuned for two\n * layers.\n *\n * @param nodeOrWidth The node or width to calculate capacity for\n * @param maxCapacityFactor Optional multiplier to adjust capacity\n * @returns The calculated capacity\n */\nexport const getTunedTotalCapacity1 = (\n nodeOrWidth: CapacityMeshNode | { width: number },\n maxCapacityFactor = 1,\n) => {\n const VIA_DIAMETER = 0.6\n const TRACE_WIDTH = 0.15\n const obstacleMargin = 0.2\n\n const width = \"width\" in nodeOrWidth ? nodeOrWidth.width : nodeOrWidth\n const viaLengthAcross = width / (VIA_DIAMETER / 2 + obstacleMargin)\n\n return (viaLengthAcross / 2) ** 1.1 * maxCapacityFactor\n}\n\n/**\n * Calculate the optimal subdivision depth to reach a target minimum capacity\n * @param initialWidth The initial width of the top-level node\n * @param targetMinCapacity The minimum capacity target (default 0.5)\n * @param maxDepth Maximum allowed depth (default 10)\n * @returns The optimal capacity depth\n */\nexport const calculateOptimalCapacityDepth = (\n initialWidth: number,\n targetMinCapacity = 0.5,\n maxDepth = 16,\n): number => {\n let depth = 0\n let width = initialWidth\n\n // Calculate capacity at each subdivision level until we reach target or max depth\n while (depth < maxDepth) {\n const capacity = getTunedTotalCapacity1({ width })\n\n // If capacity is below target, we've gone far enough\n if (capacity <= targetMinCapacity) {\n break\n }\n\n // Move to next subdivision level (each level divides width by 2)\n width /= 2\n depth++\n }\n\n // Return depth + 1 to account for the fact that we want to subdivide\n // until the smallest nodes have capacity <= targetMinCapacity\n return Math.max(1, depth)\n}\n","type Point = { x: number; y: number }\n\nexport class KDNode {\n point: Point\n left: KDNode | null = null\n right: KDNode | null = null\n\n constructor(point: Point) {\n this.point = point\n }\n}\n\nclass KDTree {\n root: KDNode | null = null\n\n constructor(points: Point[]) {\n if (points.length > 0) {\n this.root = this.buildTree(points, 0)\n }\n }\n\n private buildTree(points: Point[], depth: number): KDNode {\n const axis = depth % 2 === 0 ? \"x\" : \"y\"\n\n // Sort points by the current axis\n points.sort((a, b) => a[axis] - b[axis])\n\n // Choose median as the pivot element\n const medianIndex = Math.floor(points.length / 2)\n const node = new KDNode(points[medianIndex])\n\n // Recursively build left and right subtrees\n if (medianIndex > 0) {\n node.left = this.buildTree(points.slice(0, medianIndex), depth + 1)\n }\n\n if (medianIndex < points.length - 1) {\n node.right = this.buildTree(points.slice(medianIndex + 1), depth + 1)\n }\n\n return node\n }\n\n // Find the nearest neighbor to a query point\n findNearestNeighbor(queryPoint: Point): Point {\n if (!this.root) {\n throw new Error(\"Tree is empty\")\n }\n\n const best: Point = this.root.point\n const bestDistance = this.distance(queryPoint, best)\n\n this.nearestNeighborSearch(this.root, queryPoint, 0, best, bestDistance)\n\n return best\n }\n\n private nearestNeighborSearch(\n node: KDNode | null,\n queryPoint: Point,\n depth: number,\n best: Point,\n bestDistance: number,\n ): Point {\n if (!node) {\n return best\n }\n\n const axis = depth % 2 ? \"x\" : \"y\"\n const currentDistance = this.distance(queryPoint, node.point)\n\n if (currentDistance < bestDistance) {\n best = node.point\n bestDistance = currentDistance\n }\n\n // Determine which subtree to search first\n const axisDiff = queryPoint[axis] - node.point[axis]\n const firstBranch = axisDiff <= 0 ? node.left : node.right\n const secondBranch = axisDiff <= 0 ? node.right : node.left\n\n // Recursively search the first branch\n best = this.nearestNeighborSearch(\n firstBranch,\n queryPoint,\n depth + 1,\n best,\n bestDistance,\n )\n bestDistance = this.distance(queryPoint, best)\n\n // Check if we need to search the second branch\n if (Math.abs(axisDiff) < bestDistance) {\n best = this.nearestNeighborSearch(\n secondBranch,\n queryPoint,\n depth + 1,\n best,\n bestDistance,\n )\n }\n\n return best\n }\n\n // Find k nearest neighbors\n findKNearestNeighbors(queryPoint: Point, k: number): Point[] {\n if (!this.root) {\n return []\n }\n\n const neighbors: Array<{ point: Point; distance: number }> = []\n\n this.kNearestNeighborSearch(this.root, queryPoint, 0, neighbors, k)\n\n return neighbors\n .sort((a, b) => a.distance - b.distance)\n .slice(0, k)\n .map((n) => n.point)\n }\n\n private kNearestNeighborSearch(\n node: KDNode | null,\n queryPoint: Point,\n depth: number,\n neighbors: Array<{ point: Point; distance: number }>,\n k: number,\n ): void {\n if (!node) {\n return\n }\n\n const axis = depth % 2 ? \"x\" : \"y\"\n const currentDistance = this.distance(queryPoint, node.point)\n\n // Add current node to neighbors\n neighbors.push({ point: node.point, distance: currentDistance })\n\n // Determine which subtree to search first\n const axisDiff = queryPoint[axis] - node.point[axis]\n const firstBranch = axisDiff <= 0 ? node.left : node.right\n const secondBranch = axisDiff <= 0 ? node.right : node.left\n\n // Recursively search the first branch\n this.kNearestNeighborSearch(\n firstBranch,\n queryPoint,\n depth + 1,\n neighbors,\n k,\n )\n\n // Get the kth distance if we have k neighbors\n let kthDistance = Infinity\n if (neighbors.length >= k) {\n neighbors.sort((a, b) => a.distance - b.distance)\n kthDistance = neighbors[k - 1]?.distance || Infinity\n }\n\n // Search the other branch if necessary\n if (Math.abs(axisDiff) < kthDistance || neighbors.length < k) {\n this.kNearestNeighborSearch(\n secondBranch,\n queryPoint,\n depth + 1,\n neighbors,\n k,\n )\n }\n }\n\n // Calculate Euclidean distance between two points\n private distance(a: Point, b: Point): number {\n return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)\n }\n}\n\n// Disjoint Set (Union-Find) data structure for Kruskal's algorithm\nexport class DisjointSet {\n private parent: Map<string, string> = new Map()\n private rank: Map<string, number> = new Map()\n\n constructor(points: Point[]) {\n // Initialize each point as a separate set\n for (const point of points) {\n const key = this.pointToKey(point)\n this.parent.set(key, key)\n this.rank.set(key, 0)\n }\n }\n\n private pointToKey(point: Point): string {\n return `${point.x},${point.y}`\n }\n\n find(point: Point): string {\n const key = this.pointToKey(point)\n if (!this.parent.has(key)) {\n throw new Error(`Point ${key} not found in DisjointSet`)\n }\n\n let root = key\n while (root !== this.parent.get(root)) {\n root = this.parent.get(root)!\n }\n\n // Path compression\n let current = key\n while (current !== root) {\n const next = this.parent.get(current)!\n this.parent.set(current, root)\n current = next\n }\n\n return root\n }\n\n union(pointA: Point, pointB: Point): boolean {\n const rootA = this.find(pointA)\n const rootB = this.find(pointB)\n\n if (rootA === rootB) {\n return false // Already in the same set\n }\n\n // Union by rank\n const rankA = this.rank.get(rootA) || 0\n const rankB = this.rank.get(rootB) || 0\n\n if (rankA < rankB) {\n this.parent.set(rootA, rootB)\n } else if (rankA > rankB) {\n this.parent.set(rootB, rootA)\n } else {\n this.parent.set(rootB, rootA)\n this.rank.set(rootA, rankA + 1)\n }\n\n return true\n }\n}\n\n// Edge representation for Kruskal's algorithm\ninterface Edge<T extends Point> {\n from: T\n to: T\n weight: number\n}\n\n// Main function to build a minimum spanning tree using Kruskal's algorithm\nexport function buildMinimumSpanningTree<T extends Point>(\n points: T[],\n): Edge<T>[] {\n if (points.length <= 1) {\n return []\n }\n\n // Build KD-Tree for efficient nearest neighbor search\n const kdTree = new KDTree(points)\n\n // Generate edges with k-nearest neighbors for each point\n // This is an optimization to avoid generating all possible n(n-1)/2 edges\n const edges: Edge<T>[] = []\n const k = Math.min(10, points.length - 1) // Consider k nearest neighbors\n\n for (const point of points) {\n const neighbors = kdTree.findKNearestNeighbors(point, k + 1) // +1 because it includes the point itself\n\n for (const neighbor of neighbors) {\n // Skip self\n if (point.x === neighbor.x && point.y === neighbor.y) {\n continue\n }\n\n const distance = Math.sqrt(\n (point.x - neighbor.x) ** 2 + (point.y - neighbor.y) ** 2,\n )\n\n edges.push({\n from: point,\n to: neighbor as T,\n weight: distance,\n })\n }\n }\n\n // Sort edges by weight (distance)\n edges.sort((a, b) => a.weight - b.weight)\n\n // Apply Kruskal's algorithm\n const disjointSet = new DisjointSet(points)\n const mstEdges: Edge<T>[] = []\n\n for (const edge of edges) {\n if (disjointSet.union(edge.from, edge.to)) {\n mstEdges.push(edge)\n\n // MST has n-1 edges for n points\n if (mstEdges.length === points.length - 1) {\n break\n }\n }\n }\n\n return mstEdges\n}\n","import { SimpleRouteConnection, SimpleRouteJson } from \"lib/types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { buildMinimumSpanningTree } from \"./buildMinimumSpanningTree\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { seededRandom } from \"lib/utils/cloneAndShuffleArray\"\n\n/**\n * Converts a net containing many points to connect into an array of point pair\n * connections.\n *\n * For example, a connection with 3 pointsToConnect could be turned into 2\n * connections of 2 points each.\n *\n * Where we create the minimum number of pairs, we're using a minimum spanning\n * tree (MST).\n *\n * Sometimes it can be used to add additional traces to help make sure we\n * distribute load effectively. In this version we don't do that!\n */\nexport class NetToPointPairsSolver extends BaseSolver {\n unprocessedConnections: Array<SimpleRouteConnection>\n newConnections: Array<SimpleRouteConnection>\n\n constructor(\n public ogSrj: SimpleRouteJson,\n public colorMap: Record<string, string> = {},\n ) {\n super()\n this.unprocessedConnections = [...ogSrj.connections]\n this.newConnections = []\n }\n\n _step() {\n if (this.unprocessedConnections.length === 0) {\n this.solved = true\n return\n }\n const connection = this.unprocessedConnections.pop()!\n if (connection.pointsToConnect.length === 2) {\n this.newConnections.push(connection)\n return\n }\n\n const edges = buildMinimumSpanningTree(connection.pointsToConnect)\n\n for (let i = 0; i < edges.length; i++) {\n const edge = edges[i]\n this.newConnections.push({\n pointsToConnect: [edge.from, edge.to],\n name: `${connection.name}_mst${i}`,\n })\n }\n }\n\n getNewSimpleRouteJson(): SimpleRouteJson {\n return {\n ...this.ogSrj,\n connections: this.newConnections,\n }\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Net To Point Pairs Visualization\",\n }\n\n // Draw unprocessed connections in red\n this.unprocessedConnections.forEach((connection) => {\n // Draw points\n connection.pointsToConnect.forEach((point) => {\n graphics.points!.push({\n x: point.x,\n y: point.y,\n color: \"red\",\n label: connection.name,\n })\n })\n\n // Draw lines connecting all points in the connection\n const fullyConnectedEdgeCount = connection.pointsToConnect.length ** 2\n const random = seededRandom(0)\n const alreadyPlacedEdges = new Set<string>()\n for (\n let i = 0;\n i <\n Math.max(\n fullyConnectedEdgeCount,\n connection.pointsToConnect.length * 2,\n );\n i++\n ) {\n const a = Math.floor(random() * connection.pointsToConnect.length)\n const b = Math.floor(random() * connection.pointsToConnect.length)\n if (alreadyPlacedEdges.has(`${a}-${b}`)) continue\n alreadyPlacedEdges.add(`${a}-${b}`)\n graphics.lines!.push({\n points: [\n connection.pointsToConnect[a],\n connection.pointsToConnect[b],\n ],\n strokeColor: \"rgba(255,0,0,0.25)\",\n })\n }\n })\n\n // Draw processed connections with appropriate colors\n this.newConnections.forEach((connection) => {\n const color = this.colorMap?.[connection.name] || \"blue\"\n\n // Draw points\n connection.pointsToConnect.forEach((point) => {\n graphics.points!.push({\n x: point.x,\n y: point.y,\n color: color,\n label: connection.name,\n })\n })\n\n // Draw lines connecting all points in the connection\n for (let i = 0; i < connection.pointsToConnect.length - 1; i++) {\n for (let j = i + 1; j < connection.pointsToConnect.length; j++) {\n graphics.lines!.push({\n points: [\n connection.pointsToConnect[i],\n connection.pointsToConnect[j],\n ],\n strokeColor: color,\n })\n }\n }\n })\n\n return graphics\n }\n}\n","export const mapZToLayerName = (z: number, layerCount: number) => {\n if (z < 0 || z >= layerCount) {\n throw new Error(`Invalid z \"${z}\" for layer count: ${layerCount}`)\n }\n\n if (z === 0) return \"top\"\n if (z === layerCount - 1) return \"bottom\"\n return `inner${z}`\n}\n","import { SimplifiedPcbTraces } from \"lib/types\"\nimport { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport { mapZToLayerName } from \"./mapZToLayerName\"\n\ntype Point = { x: number; y: number; z: number }\n\nexport const convertHdRouteToSimplifiedRoute = (\n hdRoute: HighDensityIntraNodeRoute,\n layerCount: number,\n): SimplifiedPcbTraces[number][\"route\"] => {\n const result: SimplifiedPcbTraces[number][\"route\"] = []\n if (hdRoute.route.length === 0) return result\n\n let currentLayerPoints: Point[] = []\n let currentZ = hdRoute.route[0].z\n\n // Add all points to their respective layer segments\n for (let i = 0; i < hdRoute.route.length; i++) {\n const point = hdRoute.route[i]\n\n // If we're changing layers, process the current layer's points\n // and add a via if one exists at this position\n if (point.z !== currentZ) {\n // Add all wire segments for the current layer\n const layerName = mapZToLayerName(currentZ, layerCount)\n for (const layerPoint of currentLayerPoints) {\n result.push({\n route_type: \"wire\",\n x: layerPoint.x,\n y: layerPoint.y,\n width: hdRoute.traceThickness,\n layer: layerName,\n })\n }\n\n // Check if a via exists at this position\n const viaExists = hdRoute.vias.some(\n (via) =>\n Math.abs(via.x - point.x) < 0.001 &&\n Math.abs(via.y - point.y) < 0.001,\n )\n\n // Add a via if one exists\n if (viaExists) {\n const fromLayer = mapZToLayerName(currentZ, layerCount)\n const toLayer = mapZToLayerName(point.z, layerCount)\n\n result.push({\n route_type: \"via\",\n x: point.x,\n y: point.y,\n from_layer: fromLayer,\n to_layer: toLayer,\n })\n }\n\n // Start a new layer\n currentLayerPoints = [point]\n currentZ = point.z\n } else {\n // Continue on the same layer\n currentLayerPoints.push(point)\n }\n }\n\n // Add the final layer's wire segments\n const layerName = mapZToLayerName(currentZ, layerCount)\n for (const layerPoint of currentLayerPoints) {\n result.push({\n route_type: \"wire\",\n x: layerPoint.x,\n y: layerPoint.y,\n width: hdRoute.traceThickness,\n layer: layerName,\n })\n }\n\n return result\n}\n","import { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { distance } from \"@tscircuit/math-utils\"\n\nexport class SingleHighDensityRouteStitchSolver extends BaseSolver {\n mergedHdRoute: HighDensityIntraNodeRoute\n remainingHdRoutes: HighDensityIntraNodeRoute[]\n start: { x: number; y: number; z: number }\n end: { x: number; y: number; z: number }\n\n constructor(opts: {\n hdRoutes: HighDensityIntraNodeRoute[]\n start: { x: number; y: number; z: number }\n end: { x: number; y: number; z: number }\n }) {\n super()\n this.remainingHdRoutes = [...opts.hdRoutes]\n this.mergedHdRoute = {\n connectionName: opts.hdRoutes[0].connectionName,\n route: [\n {\n x: opts.start.x,\n y: opts.start.y,\n z: opts.start.z,\n },\n ],\n vias: [],\n viaDiameter: opts.hdRoutes[0].viaDiameter,\n traceThickness: opts.hdRoutes[0].traceThickness,\n }\n this.start = opts.start\n this.end = opts.end\n }\n\n _step() {\n if (this.remainingHdRoutes.length === 0) {\n // Add the end point to the merged route\n this.mergedHdRoute.route.push({\n x: this.end.x,\n y: this.end.y,\n z: this.end.z,\n })\n this.solved = true\n return\n }\n\n const lastMergedPoint =\n this.mergedHdRoute.route[this.mergedHdRoute.route.length - 1]\n\n // Find the next logical route to merge\n // 1. We need to check both the first and last points of the remaining routes\n // 2. If the last point is closest, we need to reverse the hd route before merging\n // 3. After merging, we remove it from the remaining routes\n\n let closestRouteIndex = 0\n let matchedOn: \"first\" | \"last\" = \"first\"\n let closestDistance = Infinity\n for (let i = 0; i < this.remainingHdRoutes.length; i++) {\n const hdRoute = this.remainingHdRoutes[i]\n const lastPointInCandidate = hdRoute.route[hdRoute.route.length - 1]\n const firstPointInCandidate = hdRoute.route[0]\n const distToFirst = distance(lastMergedPoint, firstPointInCandidate)\n const distToLast = distance(lastMergedPoint, lastPointInCandidate)\n if (distToFirst < closestDistance) {\n closestDistance = distToFirst\n closestRouteIndex = i\n matchedOn = \"first\"\n }\n if (distToLast < closestDistance) {\n closestDistance = distToLast\n closestRouteIndex = i\n matchedOn = \"last\"\n }\n }\n\n const hdRouteToMerge = this.remainingHdRoutes[closestRouteIndex]\n this.remainingHdRoutes.splice(closestRouteIndex, 1)\n\n if (matchedOn === \"first\") {\n this.mergedHdRoute.route.push(...hdRouteToMerge.route)\n } else {\n this.mergedHdRoute.route.push(...[...hdRouteToMerge.route].reverse())\n }\n\n this.mergedHdRoute.vias.push(...hdRouteToMerge.vias)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n points: [],\n lines: [],\n circles: [],\n title: \"Single High Density Route Stitch Solver\",\n }\n\n // Visualize start and end points\n graphics.points?.push(\n {\n x: this.start.x,\n y: this.start.y,\n color: \"green\",\n label: \"Start\",\n },\n {\n x: this.end.x,\n y: this.end.y,\n color: \"red\",\n label: \"End\",\n },\n )\n\n // Visualize the merged HD route in green\n if (this.mergedHdRoute && this.mergedHdRoute.route.length > 1) {\n graphics.lines?.push({\n points: this.mergedHdRoute.route.map((point) => ({\n x: point.x,\n y: point.y,\n })),\n strokeColor: \"green\",\n })\n\n // Add points for the merged route\n for (const point of this.mergedHdRoute.route) {\n graphics.points?.push({\n x: point.x,\n y: point.y,\n color: \"green\",\n })\n }\n\n // Visualize vias in the merged route\n for (const via of this.mergedHdRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: this.mergedHdRoute.viaDiameter / 2,\n fill: \"green\",\n })\n }\n }\n\n // Visualize all remaining HD routes\n const colorList = Array.from(\n { length: this.remainingHdRoutes.length },\n (_, i) => `hsl(${(i * 360) / this.remainingHdRoutes.length}, 100%, 50%)`,\n )\n for (const [i, hdRoute] of this.remainingHdRoutes.entries()) {\n if (hdRoute.route.length > 1) {\n // Create a line for the route\n graphics.lines?.push({\n points: hdRoute.route.map((point) => ({ x: point.x, y: point.y })),\n strokeColor: colorList[i],\n })\n }\n\n // Add points for each route node\n for (let pi = 0; pi < hdRoute.route.length; pi++) {\n const point = hdRoute.route[pi]\n graphics.points?.push({\n x: point.x + ((i % 2) - 0.5) / 500 + ((pi % 8) - 4) / 1000,\n y: point.y + ((i % 2) - 0.5) / 500 + ((pi % 8) - 4) / 1000,\n color: colorList[i],\n label: `Route ${i} ${point === hdRoute.route[0] ? \"First\" : point === hdRoute.route[hdRoute.route.length - 1] ? \"Last\" : \"\"}`,\n })\n }\n\n // Visualize vias\n for (const via of hdRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: hdRoute.viaDiameter / 2,\n fill: colorList[i],\n })\n }\n }\n\n return graphics\n }\n}\n","import { SimpleRouteConnection } from \"lib/types\"\nimport { HighDensityIntraNodeRoute } from \"lib/types/high-density-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\nimport { SingleHighDensityRouteStitchSolver } from \"./SingleHighDensityRouteStitchSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { safeTransparentize } from \"../colors\"\n\nexport type UnsolvedRoute = {\n connectionName: string\n hdRoutes: HighDensityIntraNodeRoute[]\n start: { x: number; y: number; z: number }\n end: { x: number; y: number; z: number }\n}\n\nexport class MultipleHighDensityRouteStitchSolver extends BaseSolver {\n unsolvedRoutes: UnsolvedRoute[]\n activeSolver: SingleHighDensityRouteStitchSolver | null = null\n mergedHdRoutes: HighDensityIntraNodeRoute[] = []\n\n constructor(opts: {\n connections: SimpleRouteConnection[]\n hdRoutes: HighDensityIntraNodeRoute[]\n layerCount: number\n }) {\n super()\n this.unsolvedRoutes = opts.connections.map((c) => ({\n connectionName: c.name,\n hdRoutes: opts.hdRoutes.filter((r) => r.connectionName === c.name),\n start: {\n ...c.pointsToConnect[0],\n z: mapLayerNameToZ(c.pointsToConnect[0].layer, opts.layerCount),\n },\n end: {\n ...c.pointsToConnect[1],\n z: mapLayerNameToZ(c.pointsToConnect[1].layer, opts.layerCount),\n },\n }))\n }\n\n _step() {\n if (this.activeSolver) {\n this.activeSolver.step()\n if (this.activeSolver.solved) {\n this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute)\n this.activeSolver = null\n } else if (this.activeSolver.failed) {\n this.failed = true\n this.error = this.activeSolver.error\n }\n return\n }\n\n const unsolvedRoute = this.unsolvedRoutes.pop()\n\n if (!unsolvedRoute) {\n this.solved = true\n return\n }\n\n if (unsolvedRoute.hdRoutes.length === 0) {\n console.warn(`No routes to stitch for ${unsolvedRoute.connectionName}`)\n return\n }\n\n this.activeSolver = new SingleHighDensityRouteStitchSolver({\n hdRoutes: unsolvedRoute.hdRoutes,\n start: unsolvedRoute.start,\n end: unsolvedRoute.end,\n })\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n points: [],\n lines: [],\n circles: [],\n title: \"Multiple High Density Route Stitch Solver\",\n }\n\n // Visualize the active solver if one exists\n if (this.activeSolver) {\n // Combine visualizations from the active solver\n const activeSolverGraphics = this.activeSolver.visualize()\n\n // Merge points\n if (activeSolverGraphics.points?.length) {\n graphics.points?.push(...activeSolverGraphics.points)\n }\n\n // Merge lines\n if (activeSolverGraphics.lines?.length) {\n graphics.lines?.push(...activeSolverGraphics.lines)\n }\n\n // Merge circles\n if (activeSolverGraphics.circles?.length) {\n graphics.circles?.push(...activeSolverGraphics.circles)\n }\n\n // Merge rects if they exist\n if (activeSolverGraphics.rects?.length) {\n graphics.rects = activeSolverGraphics.rects\n }\n }\n\n // Visualize all merged HD routes that have been solved\n for (const [i, mergedRoute] of this.mergedHdRoutes.entries()) {\n const solvedColor = `hsl(120, 100%, ${40 + ((i * 10) % 40)}%)` // Different shades of green\n\n // Visualize the route path\n if (mergedRoute.route.length > 1) {\n graphics.lines?.push({\n points: mergedRoute.route.map((point) => ({\n x: point.x,\n y: point.y,\n })),\n strokeColor: solvedColor,\n strokeWidth: mergedRoute.traceThickness,\n })\n }\n\n // Visualize route points\n for (const point of mergedRoute.route) {\n graphics.points?.push({\n x: point.x,\n y: point.y,\n color: solvedColor,\n })\n }\n\n // Visualize vias in the merged route\n for (const via of mergedRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: mergedRoute.viaDiameter / 2,\n fill: solvedColor,\n })\n }\n }\n\n // Visualize all remaining unsolved routes - start/end points only\n const colorList = Array.from(\n { length: this.unsolvedRoutes.length },\n (_, i) => `hsl(${(i * 360) / this.unsolvedRoutes.length}, 100%, 50%)`,\n )\n for (const [i, unsolvedRoute] of this.unsolvedRoutes.entries()) {\n // Add start and end points for unsolved connections\n graphics.points?.push(\n {\n x: unsolvedRoute.start.x,\n y: unsolvedRoute.start.y,\n color: colorList[i],\n label: `${unsolvedRoute.connectionName} Start`,\n },\n {\n x: unsolvedRoute.end.x,\n y: unsolvedRoute.end.y,\n color: colorList[i],\n label: `${unsolvedRoute.connectionName} End`,\n },\n )\n\n // Add a light dashed line between start and end to show pending connections\n graphics.lines?.push({\n points: [\n { x: unsolvedRoute.start.x, y: unsolvedRoute.start.y },\n { x: unsolvedRoute.end.x, y: unsolvedRoute.end.y },\n ],\n strokeColor: colorList[i],\n strokeDash: \"2 2\",\n })\n\n // Visualize HD routes associated with unsolved routes (faded)\n for (const hdRoute of unsolvedRoute.hdRoutes) {\n if (hdRoute.route.length > 1) {\n graphics.lines?.push({\n points: hdRoute.route.map((point) => ({ x: point.x, y: point.y })),\n strokeColor: safeTransparentize(colorList[i], 0.5),\n strokeDash: \"10 5\",\n })\n }\n\n // Visualize vias\n for (const via of hdRoute.vias) {\n graphics.circles?.push({\n center: { x: via.x, y: via.y },\n radius: hdRoute.viaDiameter / 2,\n fill: colorList[i],\n })\n }\n }\n }\n\n return graphics\n }\n}\n","import { Rect, Line, Circle, Point } from \"graphics-debug\"\nimport { SimpleRouteJson } from \"../../lib/types/srj-types\"\nimport { getColorMap, safeTransparentize } from \"lib/solvers/colors\"\n\nexport const convertSrjToGraphicsObject = (srj: SimpleRouteJson) => {\n const lines: Line[] = []\n const circles: Circle[] = []\n const points: Point[] = []\n\n const colorMap: Record<string, string> = getColorMap(srj)\n\n // Add points for each connection's pointsToConnect\n if (srj.connections) {\n for (const connection of srj.connections) {\n for (const point of connection.pointsToConnect) {\n points.push({\n x: point.x,\n y: point.y,\n color: colorMap[connection.name]!,\n label: `${connection.name} (${point.layer})`,\n })\n }\n }\n }\n\n // Process each trace\n if (srj.traces) {\n for (const trace of srj.traces) {\n for (let j = 0; j < trace.route.length - 1; j++) {\n const routePoint = trace.route[j]\n const nextRoutePoint = trace.route[j + 1]\n\n if (routePoint.route_type === \"via\") {\n // Add a circle for the via\n circles.push({\n center: { x: routePoint.x, y: routePoint.y },\n radius: 0.3, // 0.6 via diameter\n fill: \"blue\",\n stroke: \"none\",\n })\n } else if (\n routePoint.route_type === \"wire\" &&\n nextRoutePoint.route_type === \"wire\" &&\n nextRoutePoint.layer === routePoint.layer\n ) {\n // Create a line between consecutive wire segments on the same layer\n lines.push({\n points: [\n { x: routePoint.x, y: routePoint.y },\n { x: nextRoutePoint.x, y: nextRoutePoint.y },\n ],\n strokeWidth: 0.15,\n strokeColor: safeTransparentize(\n {\n top: \"red\",\n bottom: \"blue\",\n inner1: \"green\",\n inner2: \"yellow\",\n }[routePoint.layer]!,\n 0.5,\n ),\n // For some reason this is too small, likely a graphics-debug bug\n // strokeWidth: 0.15,\n })\n }\n }\n }\n }\n\n return {\n rects: srj.obstacles.map(\n (o) =>\n ({\n center: o.center,\n width: o.width,\n height: o.height,\n fill: \"rgba(255,0,0,0.5)\",\n }) as Rect,\n ),\n circles,\n lines,\n points,\n }\n}\n","import { CapacityMeshNodeId } from \"lib/types\"\n\nexport function getNodesNearNode(params: {\n nodeId: CapacityMeshNodeId\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n hops: number\n}): CapacityMeshNodeId[] {\n const { nodeId, nodeIdToSegmentIds, segmentIdToNodeIds, hops } = params\n\n if (hops === 0) return [nodeId]\n const segments = nodeIdToSegmentIds.get(nodeId)!\n const nodes = new Set<CapacityMeshNodeId>()\n for (const segmentId of segments) {\n const adjacentNodeIds = segmentIdToNodeIds.get(segmentId)!\n for (const adjacentNodeId of adjacentNodeIds) {\n const ancestors = getNodesNearNode({\n nodeId: adjacentNodeId,\n nodeIdToSegmentIds,\n segmentIdToNodeIds,\n hops: hops - 1,\n })\n for (const ancestor of ancestors) {\n nodes.add(ancestor)\n }\n }\n }\n return Array.from(nodes)\n}\n","import { SegmentPointId } from \"./types\"\n\nexport const createPointModificationsHash = (\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n) => {\n return Array.from(pointModifications.entries())\n .map(\n ([id, { x, y, z }]) =>\n `${id}(${x?.toFixed(3) ?? \"\"},${y?.toFixed(3) ?? \"\"},${z ?? \"\"})`,\n )\n .sort()\n .join(\"&\")\n}\n\nexport const createFullPointModificationsHash = (\n originalPoints: Map<SegmentPointId, { x: number; y: number; z: number }>,\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n) => {\n return Array.from(originalPoints.entries())\n .map(([id, originalPoint]) => {\n const mods = pointModifications.get(id)\n const finalPoint = {\n x: mods?.x !== undefined ? mods.x : originalPoint.x,\n y: mods?.y !== undefined ? mods.y : originalPoint.y,\n z: mods?.z !== undefined ? mods.z : originalPoint.z,\n }\n return `${id}(${finalPoint.x.toFixed(3)},${finalPoint.y.toFixed(3)},${finalPoint.z})`\n })\n .sort()\n .join(\"&\")\n}\n","export const hasZRangeOverlap = (\n A_z1: number,\n A_z2: number,\n B_z1: number,\n B_z2: number,\n) => {\n const Amin = Math.min(A_z1, A_z2)\n const Amax = Math.max(A_z1, A_z2)\n const Bmin = Math.min(B_z1, B_z2)\n const Bmax = Math.max(B_z1, B_z2)\n return Amin <= Bmax && Amax >= Bmin\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport {\n UnravelSection,\n UnravelIssue,\n UnravelTransitionViaIssue,\n SegmentPoint,\n SegmentPointId,\n UnravelSameLayerCrossingIssue,\n UnravelSingleTransitionCrossingIssue,\n UnravelDoubleTransitionCrossingIssue,\n} from \"./types\"\nimport { getIntraNodeCrossingsFromSegments } from \"lib/utils/getIntraNodeCrossingsFromSegments\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\nimport { getLogProbability } from \"./getLogProbability\"\nimport { doSegmentsIntersect } from \"@tscircuit/math-utils\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { hasZRangeOverlap } from \"./hasZRangeOverlap\"\n\nexport const getIssuesInSection = (\n section: UnravelSection,\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>,\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n connMap?: ConnectivityMap,\n): UnravelIssue[] => {\n const issues: UnravelIssue[] = []\n\n const points: Map<SegmentPointId, { x: number; y: number; z: number }> =\n new Map()\n for (const nodeId of section.allNodeIds) {\n for (const segmentPointId of section.segmentPointsInNode.get(nodeId)!) {\n if (!points.has(segmentPointId)) {\n const ogPoint = section.segmentPointMap.get(segmentPointId)!\n const modPoint = pointModifications.get(segmentPointId)\n points.set(segmentPointId, {\n x: modPoint?.x ?? ogPoint.x,\n y: modPoint?.y ?? ogPoint.y,\n z: modPoint?.z ?? ogPoint.z,\n })\n }\n }\n }\n\n for (const nodeId of section.allNodeIds) {\n const node = nodeMap.get(nodeId)\n if (!node) continue\n\n const nodeSegmentPairs = section.segmentPairsInNode.get(nodeId)!\n\n // If there's a Z transition within the pair, there's a transition_via issue\n for (const pair of nodeSegmentPairs) {\n const A = points.get(pair[0])!\n const B = points.get(pair[1])!\n if (A.z !== B.z) {\n issues.push({\n type: \"transition_via\",\n segmentPoints: pair,\n capacityMeshNodeId: nodeId,\n probabilityOfFailure: 0,\n })\n }\n }\n\n // Find crossing issues\n for (let i = 0; i < nodeSegmentPairs.length; i++) {\n for (let j = i + 1; j < nodeSegmentPairs.length; j++) {\n if (\n connMap?.areIdsConnected(\n nodeSegmentPairs[i][0],\n nodeSegmentPairs[i][1],\n )\n ) {\n continue\n }\n\n const pair1 = nodeSegmentPairs[i]\n const pair2 = nodeSegmentPairs[j]\n\n const A = points.get(pair1[0])!\n const B = points.get(pair1[1])!\n const C = points.get(pair2[0])!\n const D = points.get(pair2[1])!\n\n // Are the lines ever on the same layer? Is there any risk of overlap?\n if (!hasZRangeOverlap(A.z, B.z, C.z, D.z)) continue\n\n const areCrossing = doSegmentsIntersect(A, B, C, D)\n const isSameLayer = A.z === B.z && C.z === D.z && A.z === C.z\n if (areCrossing) {\n if (isSameLayer) {\n issues.push({\n type: \"same_layer_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n crossingLine1: pair1,\n crossingLine2: pair2,\n probabilityOfFailure: 0,\n } as UnravelSameLayerCrossingIssue)\n } else if (A.z === B.z && C.z !== D.z) {\n issues.push({\n type: \"single_transition_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n sameLayerCrossingLine: pair1,\n transitionCrossingLine: pair2,\n probabilityOfFailure: 0,\n } as UnravelSingleTransitionCrossingIssue)\n } else if (A.z !== B.z && C.z === D.z) {\n issues.push({\n type: \"single_transition_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n sameLayerCrossingLine: pair2,\n transitionCrossingLine: pair1,\n probabilityOfFailure: 0,\n } as UnravelSingleTransitionCrossingIssue)\n } else if (A.z !== B.z && C.z !== D.z) {\n issues.push({\n type: \"double_transition_crossing\",\n segmentPoints: [pair1, pair2],\n capacityMeshNodeId: nodeId,\n crossingLine1: pair1,\n crossingLine2: pair2,\n probabilityOfFailure: 0,\n } as UnravelDoubleTransitionCrossingIssue)\n }\n }\n }\n }\n }\n\n return issues\n}\n","export const getLogProbability = (probability: number) => {\n const K = -2.3\n return 1 - Math.exp(probability * K)\n}\n","import { SegmentPointId, UnravelOperation } from \"./types\"\n\n/**\n * Applies an operation to the point modifications map\n * @param pointModifications The current point modifications map\n * @param operation The operation to apply\n * @param getPointInCandidate Function to get the current point values (with any existing modifications)\n * @returns The modified point modifications map\n */\nexport const applyOperationToPointModifications = (\n pointModifications: Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >,\n operation: UnravelOperation,\n getPointInCandidate: (segmentPointId: SegmentPointId) => {\n x: number\n y: number\n z: number\n segmentId: string\n },\n) => {\n if (operation.type === \"change_layer\") {\n for (const segmentPointId of operation.segmentPointIds) {\n const existingMods = pointModifications.get(segmentPointId) || {}\n pointModifications.set(segmentPointId, {\n ...existingMods,\n z: operation.newZ,\n })\n }\n } else if (operation.type === \"swap_position_on_segment\") {\n const [ASpId, BSpId] = operation.segmentPointIds\n const A = getPointInCandidate(ASpId)\n const B = getPointInCandidate(BSpId)\n\n const existingModsA = pointModifications.get(ASpId) || {}\n const existingModsB = pointModifications.get(BSpId) || {}\n\n pointModifications.set(ASpId, {\n ...existingModsA,\n x: B.x,\n y: B.y,\n })\n\n pointModifications.set(BSpId, {\n ...existingModsB,\n x: A.x,\n y: A.y,\n })\n } else if (operation.type === \"combined\") {\n // For combined operations, recursively apply each operation\n for (const subOperation of operation.operations) {\n // Apply each sub-operation directly to the modifications\n applyOperationToPointModifications(\n pointModifications,\n subOperation,\n getPointInCandidate,\n )\n }\n }\n}\n","import { CapacityMeshNodeId } from \"lib/types\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport {\n SegmentId,\n SegmentPoint,\n SegmentPointId,\n SegmentPointMap,\n} from \"./types\"\n\nexport const createSegmentPointMap = (\n dedupedSegments: SegmentWithAssignedPoints[],\n segmentIdToNodeIds: Map<SegmentId, CapacityMeshNodeId[]>,\n): SegmentPointMap => {\n const segmentPoints: SegmentPoint[] = []\n let highestSegmentPointId = 0\n for (const segment of dedupedSegments) {\n for (const point of segment.assignedPoints!) {\n segmentPoints.push({\n segmentPointId: `SP${highestSegmentPointId++}`,\n segmentId: segment.nodePortSegmentId!,\n capacityMeshNodeIds: segmentIdToNodeIds.get(\n segment.nodePortSegmentId!,\n )!,\n connectionName: point.connectionName,\n x: point.point.x,\n y: point.point.y,\n z: point.point.z,\n directlyConnectedSegmentPointIds: [],\n })\n }\n }\n\n const segmentPointMap = new Map<SegmentPointId, SegmentPoint>()\n for (const segmentPoint of segmentPoints) {\n segmentPointMap.set(segmentPoint.segmentPointId, segmentPoint)\n }\n\n return segmentPointMap\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport {\n UnravelSection,\n UnravelCandidate,\n SegmentPoint,\n SegmentPointId,\n SegmentId,\n UnravelOperation,\n UnravelIssue,\n SegmentPointMap,\n} from \"./types\"\nimport { getNodesNearNode } from \"./getNodesNearNode\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport {\n createFullPointModificationsHash,\n createPointModificationsHash,\n} from \"./createPointModificationsHash\"\nimport { getIssuesInSection } from \"./getIssuesInSection\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\nimport { getLogProbability } from \"./getLogProbability\"\nimport { applyOperationToPointModifications } from \"./applyOperationToPointModifications\"\nimport { createSegmentPointMap } from \"./createSegmentPointMap\"\n\n/**\n * The UntangleSectionSolver optimizes a section of connected capacity nodes\n * with their deduplicated segments.\n *\n * The section always has a \"root\" node. From the root node, MUTABLE_HOPS are\n * taken to reach other nodes that are mutable. One additional hop is taken to\n * have all the impacted nodes in section. So a section is composed of mutable\n * and immutable nodes.\n *\n * The goal of the solver is to perform operations on the mutable nodes of the\n * section to lower the overall cost of the section.\n *\n * The untangle phase will perform \"operations\" on segments based on \"issues\"\n *\n * An \"issue\" is anything that increases the cost of the node:\n * - Anything that causes a via (e.g. layer transition)\n * - Any time two traces cross on the same layer\n *\n * An operation is a change to a segment. There are two main operations:\n * - Change layer\n * - Change point order on segment\n *\n * This solver works by exploring different paths of operations. When an\n * operation is performed, new issues are created. Each path has a cost, and\n * a set of neighbors representing next operations to perform.\n *\n */\nexport class UnravelSectionSolver extends BaseSolver {\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n dedupedSegments: SegmentWithAssignedPoints[]\n dedupedSegmentMap: Map<SegmentId, SegmentWithAssignedPoints>\n\n MUTABLE_HOPS = 1\n\n unravelSection: UnravelSection\n\n candidates: UnravelCandidate[] = []\n\n lastProcessedCandidate: UnravelCandidate | null = null\n bestCandidate: UnravelCandidate | null = null\n originalCandidate: UnravelCandidate\n\n rootNodeId: CapacityMeshNodeId\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n colorMap: Record<string, string>\n tunedNodeCapacityMap: Map<CapacityMeshNodeId, number>\n MAX_CANDIDATES = 500\n\n selectedCandidateIndex: number | \"best\" | \"original\" | null = null\n\n queuedOrExploredCandidatePointModificationHashes: Set<string> = new Set()\n\n constructor(params: {\n rootNodeId: CapacityMeshNodeId\n colorMap?: Record<string, string>\n MUTABLE_HOPS?: number\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n dedupedSegments: SegmentWithAssignedPoints[]\n dedupedSegmentMap?: Map<SegmentId, SegmentWithAssignedPoints>\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentPointMap?: SegmentPointMap\n }) {\n super()\n\n this.MUTABLE_HOPS = params.MUTABLE_HOPS ?? this.MUTABLE_HOPS\n\n this.nodeMap = params.nodeMap\n this.dedupedSegments = params.dedupedSegments\n if (params.dedupedSegmentMap) {\n this.dedupedSegmentMap = params.dedupedSegmentMap\n } else {\n this.dedupedSegmentMap = new Map()\n for (const segment of this.dedupedSegments) {\n this.dedupedSegmentMap.set(segment.nodePortSegmentId!, segment)\n }\n }\n this.nodeIdToSegmentIds = params.nodeIdToSegmentIds\n this.segmentIdToNodeIds = params.segmentIdToNodeIds\n this.rootNodeId = params.rootNodeId\n this.colorMap = params.colorMap ?? {}\n this.unravelSection = this.createUnravelSection(params.segmentPointMap)\n this.tunedNodeCapacityMap = new Map()\n for (const nodeId of this.unravelSection.allNodeIds) {\n this.tunedNodeCapacityMap.set(\n nodeId,\n getTunedTotalCapacity1(this.nodeMap.get(nodeId)!),\n )\n }\n this.originalCandidate = this.createInitialCandidate()\n this.candidates = [this.originalCandidate]\n }\n\n createUnravelSection(segmentPointMap?: SegmentPointMap): UnravelSection {\n const mutableNodeIds = getNodesNearNode({\n nodeId: this.rootNodeId,\n nodeIdToSegmentIds: this.nodeIdToSegmentIds,\n segmentIdToNodeIds: this.segmentIdToNodeIds,\n hops: this.MUTABLE_HOPS,\n })\n const allNodeIds = getNodesNearNode({\n nodeId: this.rootNodeId,\n nodeIdToSegmentIds: this.nodeIdToSegmentIds,\n segmentIdToNodeIds: this.segmentIdToNodeIds,\n hops: this.MUTABLE_HOPS + 1,\n })\n const immutableNodeIds = Array.from(\n new Set(allNodeIds).difference(new Set(mutableNodeIds)),\n )\n\n if (!segmentPointMap) {\n segmentPointMap = createSegmentPointMap(\n this.dedupedSegments,\n this.segmentIdToNodeIds,\n )\n }\n\n const segmentPoints = Array.from(segmentPointMap.values())\n\n const segmentPointsInNode = new Map<CapacityMeshNodeId, SegmentPointId[]>()\n for (const segmentPoint of segmentPoints) {\n for (const nodeId of segmentPoint.capacityMeshNodeIds) {\n segmentPointsInNode.set(nodeId, [\n ...(segmentPointsInNode.get(nodeId) ?? []),\n segmentPoint.segmentPointId,\n ])\n }\n }\n\n const segmentPointsInSegment = new Map<SegmentId, SegmentPointId[]>()\n for (const segmentPoint of segmentPoints) {\n segmentPointsInSegment.set(segmentPoint.segmentId, [\n ...(segmentPointsInSegment.get(segmentPoint.segmentId) ?? []),\n segmentPoint.segmentPointId,\n ])\n }\n\n // Second pass: set neighboring segment point ids\n for (let i = 0; i < segmentPoints.length; i++) {\n const A = segmentPoints[i]\n for (let j = i + 1; j < segmentPoints.length; j++) {\n const B = segmentPoints[j]\n if (B.segmentPointId === A.segmentPointId) continue\n if (B.segmentId === A.segmentId) continue\n if (B.connectionName !== A.connectionName) continue\n // If the points share the same capacity node, and share the same\n // connection name, then they're neighbors\n if (\n A.capacityMeshNodeIds.some((nId) =>\n B.capacityMeshNodeIds.includes(nId),\n )\n ) {\n A.directlyConnectedSegmentPointIds.push(B.segmentPointId)\n B.directlyConnectedSegmentPointIds.push(A.segmentPointId)\n }\n }\n }\n\n const segmentPairsInNode = new Map<\n CapacityMeshNodeId,\n Array<[SegmentPointId, SegmentPointId]>\n >()\n for (const nodeId of allNodeIds) {\n segmentPairsInNode.set(nodeId, [])\n }\n\n for (const A of segmentPoints) {\n for (const nodeId of A.capacityMeshNodeIds) {\n const otherSegmentPoints = segmentPointsInNode\n .get(nodeId)!\n .map((spId) => segmentPointMap.get(spId)!)\n const segmentPairs = segmentPairsInNode.get(nodeId)\n if (!segmentPairs) continue\n for (const BId of A.directlyConnectedSegmentPointIds) {\n const B = segmentPointMap.get(BId)!\n if (B.segmentPointId === A.segmentPointId) continue\n if (!B.capacityMeshNodeIds.some((nId) => nId === nodeId)) continue\n if (\n !segmentPairs.some(\n ([a, b]) =>\n (a === A.segmentPointId && b === B.segmentPointId) ||\n (a === B.segmentPointId && b === A.segmentPointId),\n )\n ) {\n segmentPairs.push([A.segmentPointId, B.segmentPointId])\n }\n }\n }\n }\n\n const mutableSegmentIds = new Set<string>()\n for (const nodeId of mutableNodeIds) {\n for (const segmentId of this.nodeIdToSegmentIds.get(nodeId)!) {\n const allNodeIdsWithSegment = this.segmentIdToNodeIds.get(segmentId)!\n if (\n allNodeIdsWithSegment.every(\n (nodeId) => !this.nodeMap.get(nodeId)!._containsTarget,\n )\n ) {\n mutableSegmentIds.add(segmentId)\n }\n }\n }\n\n return {\n allNodeIds,\n mutableNodeIds,\n immutableNodeIds,\n mutableSegmentIds,\n segmentPairsInNode,\n segmentPointMap,\n segmentPointsInNode,\n segmentPointsInSegment,\n }\n }\n\n createInitialCandidate(): UnravelCandidate {\n const pointModifications = new Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >()\n const issues = getIssuesInSection(\n this.unravelSection,\n this.nodeMap,\n pointModifications,\n )\n const g = this.computeG({\n issues,\n originalCandidate: {} as any,\n operationsPerformed: 0,\n operation: {} as any,\n })\n return {\n pointModifications,\n issues,\n g,\n h: 0,\n f: g,\n operationsPerformed: 0,\n candidateHash: createPointModificationsHash(pointModifications),\n // candidateFullHash: createFullPointModificationsHash(\n // this.unravelSection.segmentPointMap,\n // pointModifications,\n // ),\n }\n }\n\n get nextCandidate(): UnravelCandidate | null {\n return this.candidates[0] ?? null\n }\n\n getPointInCandidate(\n candidate: UnravelCandidate,\n segmentPointId: SegmentPointId,\n ): { x: number; y: number; z: number; segmentId: string } {\n const originalPoint =\n this.unravelSection.segmentPointMap.get(segmentPointId)!\n const modifications = candidate.pointModifications.get(segmentPointId)\n\n return {\n x: modifications?.x ?? originalPoint.x,\n y: modifications?.y ?? originalPoint.y,\n z: modifications?.z ?? originalPoint.z,\n segmentId: originalPoint.segmentId,\n }\n }\n\n getOperationsForIssue(\n candidate: UnravelCandidate,\n issue: UnravelIssue,\n ): UnravelOperation[] {\n const operations: UnravelOperation[] = []\n\n if (issue.type === \"transition_via\") {\n // When there's a transition via, we attempt to change the layer of either\n // end to match the other end\n const [APointId, BPointId] = issue.segmentPoints\n const pointA = this.getPointInCandidate(candidate, APointId)\n const pointB = this.getPointInCandidate(candidate, BPointId)\n\n const aAvailableZ = this.dedupedSegmentMap.get(\n pointA.segmentId,\n )!.availableZ\n const bAvailableZ = this.dedupedSegmentMap.get(\n pointB.segmentId,\n )!.availableZ\n\n if (\n this.unravelSection.mutableSegmentIds.has(pointA.segmentId) &&\n aAvailableZ.includes(pointB.z)\n ) {\n operations.push({\n type: \"change_layer\",\n newZ: pointB.z,\n segmentPointIds: [APointId],\n })\n }\n if (\n this.unravelSection.mutableSegmentIds.has(pointB.segmentId) &&\n bAvailableZ.includes(pointA.z)\n ) {\n operations.push({\n type: \"change_layer\",\n newZ: pointA.z,\n segmentPointIds: [BPointId],\n })\n }\n }\n\n if (issue.type === \"same_layer_crossing\") {\n // For a same-layer crossing, we should try all the following:\n // 1. Swap the points on each segment (for each shared segment, if any)\n // 2. Change the layer of each segment entirely to remove the crossing\n // 3. Change the layer of each point individually to make it a transition\n // crossing\n\n // 1. SWAP POINTS\n const [APointId, BPointId] = issue.crossingLine1\n const [CPointId, DPointId] = issue.crossingLine2\n\n const sharedSegments: Array<[SegmentPointId, SegmentPointId]> = []\n const A = this.unravelSection.segmentPointMap.get(APointId)!\n const B = this.unravelSection.segmentPointMap.get(BPointId)!\n const C = this.unravelSection.segmentPointMap.get(CPointId)!\n const D = this.unravelSection.segmentPointMap.get(DPointId)!\n\n if (A.segmentId === C.segmentId) {\n sharedSegments.push([APointId, CPointId])\n }\n if (A.segmentId === D.segmentId) {\n sharedSegments.push([APointId, DPointId])\n }\n if (B.segmentId === C.segmentId) {\n sharedSegments.push([BPointId, CPointId])\n }\n if (B.segmentId === D.segmentId) {\n sharedSegments.push([BPointId, DPointId])\n }\n\n for (const [EPointId, FPointId] of sharedSegments) {\n operations.push({\n type: \"swap_position_on_segment\",\n segmentPointIds: [EPointId, FPointId],\n })\n }\n\n // 2. CHANGE LAYER OF EACH SEGMENT ENTIRELY TO REMOVE CROSSING\n const Amutable = this.unravelSection.mutableSegmentIds.has(A.segmentId)\n const Bmutable = this.unravelSection.mutableSegmentIds.has(B.segmentId)\n const Cmutable = this.unravelSection.mutableSegmentIds.has(C.segmentId)\n const Dmutable = this.unravelSection.mutableSegmentIds.has(D.segmentId)\n if (Amutable && Bmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: A.z === 0 ? 1 : 0,\n segmentPointIds: [APointId, BPointId],\n })\n }\n if (Cmutable && Dmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: C.z === 0 ? 1 : 0,\n segmentPointIds: [CPointId, DPointId],\n })\n }\n\n // 3. CHANGE LAYER OF EACH POINT INDIVIDUALLY TO MAKE TRANSITION CROSSING\n if (Amutable) {\n operations.push({\n type: \"change_layer\",\n newZ: A.z === 0 ? 1 : 0,\n segmentPointIds: [APointId],\n })\n }\n if (Bmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: B.z === 0 ? 1 : 0,\n segmentPointIds: [BPointId],\n })\n }\n if (Cmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: C.z === 0 ? 1 : 0,\n segmentPointIds: [CPointId],\n })\n }\n if (Dmutable) {\n operations.push({\n type: \"change_layer\",\n newZ: D.z === 0 ? 1 : 0,\n segmentPointIds: [DPointId],\n })\n }\n }\n\n // TODO single_transition_crossing\n // TODO double_transition_crossing\n // TODO same_layer_trace_imbalance_with_low_capacity\n\n return operations\n }\n\n computeG(params: {\n issues: UnravelIssue[]\n originalCandidate: UnravelCandidate\n operationsPerformed: number\n operation: UnravelOperation\n }): number {\n const { issues, originalCandidate, operationsPerformed, operation } = params\n\n const nodeProblemCounts = new Map<\n CapacityMeshNodeId,\n {\n numTransitionCrossings: number\n numSameLayerCrossings: number\n numEntryExitLayerChanges: number\n }\n >()\n\n for (const issue of issues) {\n if (!nodeProblemCounts.has(issue.capacityMeshNodeId)) {\n nodeProblemCounts.set(issue.capacityMeshNodeId, {\n numTransitionCrossings: 0,\n numSameLayerCrossings: 0,\n numEntryExitLayerChanges: 0,\n })\n }\n\n const nodeProblemCount = nodeProblemCounts.get(issue.capacityMeshNodeId)!\n\n if (issue.type === \"transition_via\") {\n nodeProblemCount.numTransitionCrossings++\n } else if (issue.type === \"same_layer_crossing\") {\n nodeProblemCount.numSameLayerCrossings++\n } else if (\n issue.type === \"double_transition_crossing\" ||\n issue.type === \"single_transition_crossing\"\n ) {\n nodeProblemCount.numEntryExitLayerChanges++\n } else if (\n issue.type === \"same_layer_trace_imbalance_with_low_capacity\"\n ) {\n // TODO\n }\n }\n\n let cost = 0\n\n for (const [\n nodeId,\n {\n numEntryExitLayerChanges,\n numSameLayerCrossings,\n numTransitionCrossings,\n },\n ] of nodeProblemCounts) {\n const estNumVias =\n numSameLayerCrossings * 0.82 +\n numEntryExitLayerChanges * 0.41 +\n numTransitionCrossings * 0.2\n\n const estUsedCapacity = (estNumVias / 2) ** 1.1\n\n const totalCapacity = this.tunedNodeCapacityMap.get(nodeId)!\n\n const estPf = estUsedCapacity / totalCapacity\n\n cost += getLogProbability(estPf)\n }\n\n return cost\n }\n\n getNeighborByApplyingOperation(\n currentCandidate: UnravelCandidate,\n operation: UnravelOperation,\n ): UnravelCandidate {\n const pointModifications = new Map<\n SegmentPointId,\n { x?: number; y?: number; z?: number }\n >(currentCandidate.pointModifications)\n\n applyOperationToPointModifications(\n pointModifications,\n operation,\n (segmentPointId) =>\n this.getPointInCandidate(currentCandidate, segmentPointId),\n )\n\n const issues = getIssuesInSection(\n this.unravelSection,\n this.nodeMap,\n pointModifications,\n )\n\n const operationsPerformed = currentCandidate.operationsPerformed + 1\n\n const g = this.computeG({\n issues,\n originalCandidate: currentCandidate,\n operationsPerformed,\n operation,\n })\n\n return {\n issues,\n g,\n h: 0,\n f: g,\n pointModifications,\n candidateHash: createPointModificationsHash(pointModifications),\n\n // TODO PERFORMANCE allow disabling this\n // candidateFullHash: createFullPointModificationsHash(\n // this.unravelSection.segmentPointMap,\n // pointModifications,\n // ),\n\n operationsPerformed,\n }\n }\n\n getNeighborOperationsForCandidate(\n candidate: UnravelCandidate,\n ): UnravelOperation[] {\n return candidate.issues.flatMap((issue) =>\n this.getOperationsForIssue(candidate, issue),\n )\n }\n\n getNeighbors(candidate: UnravelCandidate): UnravelCandidate[] {\n const neighbors: UnravelCandidate[] = []\n\n const operations = this.getNeighborOperationsForCandidate(candidate)\n for (const operation of operations) {\n const neighbor = this.getNeighborByApplyingOperation(candidate, operation)\n neighbors.push(neighbor)\n }\n\n return neighbors\n }\n\n _step() {\n const candidate = this.candidates.shift()\n if (!candidate) {\n this.solved = true\n return\n }\n this.lastProcessedCandidate = candidate\n\n if (candidate.f < (this.bestCandidate?.f ?? Infinity)) {\n this.bestCandidate = candidate\n // TODO, only works if we start computing f\n // if (candidate.f <= 0.00001) {\n // this.solved = true\n // return\n // }\n }\n\n this.getNeighbors(candidate).forEach((neighbor) => {\n const isPartialHashExplored =\n this.queuedOrExploredCandidatePointModificationHashes.has(\n neighbor.candidateHash,\n )\n // const isFullHashExplored =\n // neighbor.candidateFullHash &&\n // this.queuedOrExploredCandidatePointModificationHashes.has(\n // neighbor.candidateFullHash,\n // )\n\n // if (isPartialHashExplored || isFullHashExplored) return\n if (isPartialHashExplored) return\n this.queuedOrExploredCandidatePointModificationHashes.add(\n neighbor.candidateHash,\n )\n // if (neighbor.candidateFullHash) {\n // this.queuedOrExploredCandidatePointModificationHashes.add(\n // neighbor.candidateFullHash,\n // )\n // }\n this.candidates.push(neighbor)\n })\n this.candidates.sort((a, b) => a.f - b.f)\n this.candidates.length = Math.min(\n this.candidates.length,\n this.MAX_CANDIDATES,\n )\n }\n\n visualize(): GraphicsObject {\n const graphics: Required<GraphicsObject> = {\n points: [],\n lines: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Unravel Section Solver\",\n }\n\n // Get the candidate to visualize\n let candidate: UnravelCandidate | null = null\n if (this.selectedCandidateIndex !== null) {\n if (this.selectedCandidateIndex === \"best\") {\n candidate = this.bestCandidate\n } else if (this.selectedCandidateIndex === \"original\") {\n candidate = this.originalCandidate\n } else {\n candidate = this.candidates[this.selectedCandidateIndex]\n }\n } else {\n candidate = this.lastProcessedCandidate || this.candidates[0]\n }\n if (!candidate) return graphics\n\n // Create a map of segment points with modifications applied\n const modifiedSegmentPoints = new Map<string, SegmentPoint>()\n for (const [segmentPointId, segmentPoint] of this.unravelSection\n .segmentPointMap) {\n // Create a copy of the original point\n const modifiedPoint = { ...segmentPoint }\n\n // Apply any modifications from the candidate\n const modification = candidate.pointModifications.get(segmentPointId)\n if (modification) {\n if (modification.x !== undefined) modifiedPoint.x = modification.x\n if (modification.y !== undefined) modifiedPoint.y = modification.y\n if (modification.z !== undefined) modifiedPoint.z = modification.z\n }\n\n modifiedSegmentPoints.set(segmentPointId, modifiedPoint)\n }\n\n // Visualize all segment points with modifications applied\n for (const [segmentPointId, segmentPoint] of modifiedSegmentPoints) {\n graphics.points.push({\n x: segmentPoint.x,\n y: segmentPoint.y,\n label: `${segmentPointId}\\nSegment: ${segmentPoint.segmentId} ${this.unravelSection.mutableSegmentIds.has(segmentPoint.segmentId) ? \"MUTABLE\" : \"IMMUTABLE\"}\\nLayer: ${segmentPoint.z}`,\n color: this.colorMap[segmentPoint.connectionName] || \"#000\",\n })\n }\n\n // Visualize nodes\n for (const nodeId of this.unravelSection.allNodeIds) {\n const node = this.nodeMap.get(nodeId)!\n const isMutable = this.unravelSection.mutableNodeIds.includes(nodeId)\n\n graphics.rects.push({\n center: node.center,\n label: `${nodeId}\\n${node.width.toFixed(2)}x${node.height.toFixed(2)}\\n${isMutable ? \"MUTABLE\" : \"IMMUTABLE\"}`,\n color: isMutable ? \"green\" : \"red\",\n width: node.width / 8,\n height: node.height / 8,\n })\n }\n\n // Connect segment points that belong to the same segment\n for (const [segmentId, segmentPointIds] of this.unravelSection\n .segmentPointsInSegment) {\n if (segmentPointIds.length <= 1) continue\n\n const points = segmentPointIds.map(\n (spId) => modifiedSegmentPoints.get(spId)!,\n )\n\n // Connect points in order\n for (let i = 0; i < points.length - 1; i++) {\n graphics.lines.push({\n points: [\n { x: points[i].x, y: points[i].y },\n { x: points[i + 1].x, y: points[i + 1].y },\n ],\n strokeColor: this.colorMap[segmentId] || \"#000\",\n })\n }\n }\n\n // Connect directly connected segment points (points with the same connection name)\n for (const [segmentPointId, segmentPoint] of modifiedSegmentPoints) {\n for (const connectedPointId of segmentPoint.directlyConnectedSegmentPointIds) {\n // Only process each connection once (when the current point's ID is less than the connected point's ID)\n if (segmentPointId < connectedPointId) {\n const connectedPoint = modifiedSegmentPoints.get(connectedPointId)!\n\n // Determine line style based on layer (z) values\n const sameLayer = segmentPoint.z === connectedPoint.z\n const commonLayer = segmentPoint.z\n\n let strokeDash: string | undefined\n if (sameLayer) {\n strokeDash = commonLayer === 0 ? undefined : \"10 5\" // top layer: solid, bottom layer: long dash\n } else {\n strokeDash = \"3 3 10\" // transition between layers: mixed dash pattern\n }\n\n graphics.lines.push({\n points: [\n { x: segmentPoint.x, y: segmentPoint.y },\n { x: connectedPoint.x, y: connectedPoint.y },\n ],\n strokeDash,\n strokeColor: this.colorMap[segmentPoint.connectionName] || \"#000\",\n })\n }\n }\n }\n\n // Visualize issues\n for (const issue of candidate.issues) {\n const node = this.nodeMap.get(issue.capacityMeshNodeId)!\n\n if (issue.type === \"transition_via\") {\n // Highlight via issues\n for (const segmentPointId of issue.segmentPoints) {\n const segmentPoint = modifiedSegmentPoints.get(segmentPointId)!\n graphics.circles.push({\n center: { x: segmentPoint.x, y: segmentPoint.y },\n radius: node.width / 16,\n stroke: \"#ff0000\",\n fill: \"rgba(255, 0, 0, 0.2)\",\n label: `Via Issue\\n${segmentPointId}\\nLayer: ${segmentPoint.z}`,\n })\n }\n } else if (issue.type === \"same_layer_crossing\") {\n // Highlight crossing issues\n for (const [sp1Id, sp2Id] of [\n issue.crossingLine1,\n issue.crossingLine2,\n ]) {\n const sp1 = modifiedSegmentPoints.get(sp1Id)!\n const sp2 = modifiedSegmentPoints.get(sp2Id)!\n\n graphics.lines.push({\n points: [\n { x: sp1.x, y: sp1.y },\n { x: sp2.x, y: sp2.y },\n ],\n strokeColor: \"rgba(255,0,0,0.2)\",\n strokeWidth: node.width / 32,\n })\n }\n }\n }\n\n // Highlight modified points\n for (const [segmentPointId, modification] of candidate.pointModifications) {\n const modifiedPoint = modifiedSegmentPoints.get(segmentPointId)!\n const originalPoint =\n this.unravelSection.segmentPointMap.get(segmentPointId)!\n\n graphics.circles.push({\n center: { x: modifiedPoint.x, y: modifiedPoint.y },\n radius: 0.05,\n stroke: \"#0000ff\",\n fill: \"rgba(0, 0, 255, 0.2)\",\n label: `${segmentPointId}\\nOriginal: (${originalPoint.x.toFixed(2)}, ${originalPoint.y.toFixed(2)}, ${originalPoint.z})\\nNew: (${modifiedPoint.x.toFixed(2)}, ${modifiedPoint.y.toFixed(2)}, ${modifiedPoint.z})`,\n })\n }\n\n return graphics\n }\n}\n","import { NodePortSegment } from \"lib/types/capacity-edges-to-port-segments-types\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\n\n/**\n * Deduplicates segments with the same start and end points.\n * Assigns a unique ID to each unique segment and ensures all segments with the same\n * start/end points share the same ID.\n * @param assignedSegments The segments to deduplicate\n * @returns Deduplicated segments with unique IDs\n */\nexport const getDedupedSegments = (\n assignedSegments: NodePortSegment[],\n): SegmentWithAssignedPoints[] => {\n const dedupedSegments: SegmentWithAssignedPoints[] = []\n type SegKey = `${number}-${number}-${number}-${number}`\n const dedupedSegPointMap: Map<SegKey, NodePortSegment> = new Map()\n let highestSegmentId = -1\n\n for (const seg of assignedSegments) {\n // Check if there's another segment with the same start and end\n const segKey: SegKey = `${seg.start.x}-${seg.start.y}-${seg.end.x}-${seg.end.y}`\n const existingSeg = dedupedSegPointMap.get(segKey)\n\n if (!existingSeg) {\n highestSegmentId++\n seg.nodePortSegmentId = `SEG${highestSegmentId}`\n dedupedSegPointMap.set(segKey, seg)\n dedupedSegments.push(seg)\n continue\n }\n\n seg.nodePortSegmentId = existingSeg.nodePortSegmentId\n }\n\n return dedupedSegments\n}\n","import { doSegmentsIntersect } from \"@tscircuit/math-utils\"\nimport { SegmentWithAssignedPoints } from \"lib/solvers/CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport { NodeWithPortPoints } from \"lib/types/high-density-types\"\n\n/**\n * Get the number of crossings between segments on the same node\n */\nexport const getIntraNodeCrossingsFromSegments = (\n segments: SegmentWithAssignedPoints[],\n): {\n numSameLayerCrossings: number\n numEntryExitLayerChanges: number\n numTransitionCrossings: number\n} => {\n // Count the number of crossings\n let numSameLayerCrossings = 0\n const pointPairs: {\n points: { x: number; y: number; z: number }[]\n z: number\n connectionName: string\n }[] = []\n\n const transitionPairPoints: {\n points: { x: number; y: number; z: number }[]\n connectionName: string\n }[] = []\n\n let numEntryExitLayerChanges = 0\n\n const portPoints = segments.flatMap((seg) => seg.assignedPoints!)\n\n for (const { connectionName: aConnName, point: A } of portPoints) {\n if (pointPairs.some((p) => p.connectionName === aConnName)) {\n continue\n }\n if (transitionPairPoints.some((p) => p.connectionName === aConnName)) {\n continue\n }\n const pointPair = {\n connectionName: aConnName,\n z: A.z,\n points: [A],\n }\n for (const { connectionName: bConnName, point: B } of portPoints) {\n if (aConnName !== bConnName) continue\n if (A === B) continue\n pointPair.points.push(B)\n\n if (pointPair.points.some((p) => p.z !== pointPair.z)) {\n numEntryExitLayerChanges++\n transitionPairPoints.push(pointPair)\n break\n } else {\n pointPairs.push(pointPair)\n break\n }\n }\n }\n\n for (let i = 0; i < pointPairs.length; i++) {\n for (let j = i + 1; j < pointPairs.length; j++) {\n const pair1 = pointPairs[i]\n const pair2 = pointPairs[j]\n if (\n pair1.z === pair2.z &&\n doSegmentsIntersect(\n pair1.points[0],\n pair1.points[1],\n pair2.points[0],\n pair2.points[1],\n )\n ) {\n numSameLayerCrossings++\n }\n }\n }\n\n let numTransitionCrossings = 0\n for (let i = 0; i < transitionPairPoints.length; i++) {\n for (let j = i + 1; j < transitionPairPoints.length; j++) {\n const pair1 = transitionPairPoints[i]\n const pair2 = transitionPairPoints[j]\n\n if (\n doSegmentsIntersect(\n pair1.points[0],\n pair1.points[1],\n pair2.points[0],\n pair2.points[1],\n )\n ) {\n numTransitionCrossings++\n }\n }\n }\n\n for (let i = 0; i < transitionPairPoints.length; i++) {\n for (let j = 0; j < pointPairs.length; j++) {\n const pair1 = transitionPairPoints[i]\n const pair2 = pointPairs[j]\n if (\n doSegmentsIntersect(\n pair1.points[0],\n pair1.points[1],\n pair2.points[0],\n pair2.points[1],\n )\n ) {\n numTransitionCrossings++\n }\n }\n }\n\n return {\n numSameLayerCrossings,\n numEntryExitLayerChanges,\n numTransitionCrossings,\n }\n}\n","import { CapacityMeshNode } from \"lib/types\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\n\nexport const calculateNodeProbabilityOfFailure = (\n node: CapacityMeshNode,\n numSameLayerCrossings: number,\n numEntryExitLayerChanges: number,\n numTransitionCrossings: number,\n): number => {\n if (node?._containsTarget) return 0\n\n // Number of traces through the node\n const totalCapacity = getTunedTotalCapacity1(node)\n\n // Estimated number of vias based on crossings\n const estNumVias =\n numSameLayerCrossings * 0.82 +\n numEntryExitLayerChanges * 0.41 +\n numTransitionCrossings * 0.2\n\n const estUsedCapacity = (estNumVias / 2) ** 1.1\n\n // We could refine this with actual trace capacity\n const approxProb = estUsedCapacity / totalCapacity\n\n // Bounded probability calculation\n return approxProb\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\nimport { SegmentWithAssignedPoints } from \"../CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport { UnravelSectionSolver } from \"./UnravelSectionSolver\"\nimport { getIntraNodeCrossings } from \"lib/utils/getIntraNodeCrossings\"\nimport { NodePortSegment } from \"lib/types/capacity-edges-to-port-segments-types\"\nimport { getDedupedSegments } from \"./getDedupedSegments\"\nimport { getIntraNodeCrossingsFromSegments } from \"lib/utils/getIntraNodeCrossingsFromSegments\"\nimport { calculateNodeProbabilityOfFailure } from \"./calculateCrossingProbabilityOfFailure\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { NodeWithPortPoints } from \"lib/types/high-density-types\"\nimport {\n PointModificationsMap,\n SegmentId,\n SegmentPoint,\n SegmentPointId,\n SegmentPointMap,\n} from \"./types\"\nimport { createSegmentPointMap } from \"./createSegmentPointMap\"\n\nexport class UnravelMultiSectionSolver extends BaseSolver {\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n dedupedSegmentMap: Map<SegmentId, SegmentWithAssignedPoints>\n dedupedSegments: SegmentWithAssignedPoints[]\n nodeIdToSegmentIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n segmentIdToNodeIds: Map<CapacityMeshNodeId, CapacityMeshNodeId[]>\n colorMap: Record<string, string>\n tunedNodeCapacityMap: Map<CapacityMeshNodeId, number>\n\n MAX_NODE_ATTEMPTS = 2\n\n MUTABLE_HOPS = 1\n\n ACCEPTABLE_PF = 0.05\n\n /**\n * Probability of failure for each node\n */\n nodePfMap: Map<CapacityMeshNodeId, number>\n\n attemptsToFixNode: Map<CapacityMeshNodeId, number>\n\n activeSolver: UnravelSectionSolver | null = null\n\n segmentPointMap: SegmentPointMap\n\n constructor({\n assignedSegments,\n colorMap,\n nodes,\n }: {\n assignedSegments: NodePortSegment[]\n colorMap?: Record<string, string>\n /**\n * This isn't used by the algorithm, but allows associating metadata\n * for the result datatype (the center, width, height of the node)\n */\n nodes: CapacityMeshNode[]\n }) {\n super()\n\n this.MAX_ITERATIONS = 100_000\n\n this.dedupedSegments = getDedupedSegments(assignedSegments)\n this.dedupedSegmentMap = new Map()\n for (const segment of this.dedupedSegments) {\n this.dedupedSegmentMap.set(segment.nodePortSegmentId!, segment)\n }\n this.nodeMap = new Map()\n for (const node of nodes) {\n this.nodeMap.set(node.capacityMeshNodeId, node)\n }\n\n this.nodeIdToSegmentIds = new Map()\n this.segmentIdToNodeIds = new Map()\n this.attemptsToFixNode = new Map()\n\n for (const segment of assignedSegments) {\n this.segmentIdToNodeIds.set(segment.nodePortSegmentId!, [\n ...(this.segmentIdToNodeIds.get(segment.nodePortSegmentId!) ?? []),\n segment.capacityMeshNodeId,\n ])\n this.nodeIdToSegmentIds.set(segment.capacityMeshNodeId, [\n ...(this.nodeIdToSegmentIds.get(segment.capacityMeshNodeId) ?? []),\n segment.nodePortSegmentId!,\n ])\n }\n\n this.colorMap = colorMap ?? {}\n\n // Compute tuned capacity for each node\n this.tunedNodeCapacityMap = new Map()\n for (const [nodeId, node] of this.nodeMap) {\n this.tunedNodeCapacityMap.set(nodeId, getTunedTotalCapacity1(node))\n }\n\n this.segmentPointMap = createSegmentPointMap(\n this.dedupedSegments,\n this.segmentIdToNodeIds,\n )\n\n this.nodePfMap = this.computeInitialPfMap()\n }\n\n computeInitialPfMap() {\n const pfMap = new Map<CapacityMeshNodeId, number>()\n\n for (const [nodeId, node] of this.nodeMap.entries()) {\n pfMap.set(nodeId, this.computeNodePf(node))\n }\n\n return pfMap\n }\n\n computeNodePf(node: CapacityMeshNode) {\n const {\n numSameLayerCrossings,\n numEntryExitLayerChanges,\n numTransitionCrossings,\n } = getIntraNodeCrossingsFromSegments(\n this.dedupedSegments.filter((seg) =>\n this.segmentIdToNodeIds\n .get(seg.nodePortSegmentId!)!\n .includes(node.capacityMeshNodeId),\n ),\n )\n\n const probabilityOfFailure = calculateNodeProbabilityOfFailure(\n node,\n numSameLayerCrossings,\n numEntryExitLayerChanges,\n numTransitionCrossings,\n )\n\n return probabilityOfFailure\n }\n\n _step() {\n if (this.iterations >= this.MAX_ITERATIONS - 1) {\n this.solved = true\n return\n }\n if (!this.activeSolver) {\n // Find the node with the highest probability of failure\n let highestPfNodeId = null\n let highestPf = 0\n for (const [nodeId, pf] of this.nodePfMap.entries()) {\n const pfReduced =\n pf *\n (1 -\n (this.attemptsToFixNode.get(nodeId) ?? 0) / this.MAX_NODE_ATTEMPTS)\n if (pfReduced > highestPf) {\n highestPf = pf\n highestPfNodeId = nodeId\n }\n }\n\n if (!highestPfNodeId || highestPf < this.ACCEPTABLE_PF) {\n this.solved = true\n return\n }\n\n this.attemptsToFixNode.set(\n highestPfNodeId,\n (this.attemptsToFixNode.get(highestPfNodeId) ?? 0) + 1,\n )\n this.activeSolver = new UnravelSectionSolver({\n dedupedSegments: this.dedupedSegments,\n dedupedSegmentMap: this.dedupedSegmentMap,\n nodeMap: this.nodeMap,\n nodeIdToSegmentIds: this.nodeIdToSegmentIds,\n segmentIdToNodeIds: this.segmentIdToNodeIds,\n colorMap: this.colorMap,\n rootNodeId: highestPfNodeId,\n MUTABLE_HOPS: this.MUTABLE_HOPS,\n segmentPointMap: this.segmentPointMap,\n })\n }\n\n this.activeSolver.step()\n\n const { bestCandidate, originalCandidate, lastProcessedCandidate } =\n this.activeSolver\n\n const giveUpFactor =\n 1 + 4 * (1 - Math.min(1, this.activeSolver.iterations / 40))\n const shouldEarlyStop =\n lastProcessedCandidate &&\n lastProcessedCandidate!.g > bestCandidate!.g * giveUpFactor\n\n if (this.activeSolver.solved || shouldEarlyStop) {\n // Incorporate the changes from the active solver\n\n const foundBetterSolution =\n bestCandidate && bestCandidate.g < originalCandidate!.g\n\n if (foundBetterSolution) {\n // Modify the points using the pointModifications of the candidate\n for (const [\n segmentPointId,\n pointModification,\n ] of bestCandidate.pointModifications.entries()) {\n const segmentPoint = this.segmentPointMap.get(segmentPointId)!\n segmentPoint.x = pointModification.x ?? segmentPoint.x\n segmentPoint.y = pointModification.y ?? segmentPoint.y\n segmentPoint.z = pointModification.z ?? segmentPoint.z\n }\n }\n\n // Update node failure probabilities\n for (const nodeId of this.activeSolver.unravelSection.allNodeIds) {\n this.nodePfMap.set(\n nodeId,\n this.computeNodePf(this.nodeMap.get(nodeId)!),\n )\n }\n\n this.activeSolver = null\n }\n }\n\n visualize(): GraphicsObject {\n if (this.activeSolver) {\n return this.activeSolver.visualize()\n }\n\n const graphics: Required<GraphicsObject> = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n coordinateSystem: \"cartesian\",\n title: \"Unravel Multi Section Solver\",\n }\n\n // Visualize nodes\n for (const [nodeId, node] of this.nodeMap.entries()) {\n const probabilityOfFailure = this.nodePfMap.get(nodeId) || 0\n // Color based on probability of failure - red for high, gradient to green for low\n const pf = Math.min(probabilityOfFailure, 1) // Cap at 1\n const red = Math.floor(255 * pf)\n const green = Math.floor(255 * (1 - pf))\n const color = `rgb(${red}, ${green}, 0)`\n\n if ((this.attemptsToFixNode.get(nodeId) ?? 0) === 0 && pf === 0) {\n continue\n }\n\n graphics.rects.push({\n center: node.center,\n label: [\n nodeId,\n `${node.width.toFixed(2)}x${node.height.toFixed(2)}`,\n `Pf: ${probabilityOfFailure.toFixed(3)}`,\n ].join(\"\\n\"),\n color,\n width: node.width / 8,\n height: node.height / 8,\n })\n }\n\n // Visualize segment points\n for (const segmentPoint of this.segmentPointMap.values()) {\n const segment = this.dedupedSegmentMap.get(segmentPoint.segmentId)\n graphics.points.push({\n x: segmentPoint.x,\n y: segmentPoint.y,\n label: [\n segmentPoint.segmentPointId,\n segmentPoint.segmentId,\n `z: ${segmentPoint.z}`,\n `segment.availableZ: ${segment?.availableZ.join(\",\")}`,\n ].join(\"\\n\"),\n color: this.colorMap[segmentPoint.connectionName] || \"#000\",\n })\n }\n\n // Connect segment points that belong to the same segment\n // Group points by segment ID\n const pointsBySegment = new Map<string, SegmentPoint[]>()\n for (const point of this.segmentPointMap.values()) {\n if (!pointsBySegment.has(point.segmentId)) {\n pointsBySegment.set(point.segmentId, [])\n }\n pointsBySegment.get(point.segmentId)!.push(point)\n }\n\n // Connect points in each segment\n for (const [segmentId, points] of pointsBySegment.entries()) {\n if (points.length < 2) continue\n\n // Sort points by some logical order (this approximates the correct ordering)\n const sortedPoints = [...points].sort((a, b) =>\n a.x !== b.x ? a.x - b.x : a.y - b.y,\n )\n\n // Connect adjacent points in the sorted order\n for (let i = 0; i < sortedPoints.length - 1; i++) {\n graphics.lines.push({\n points: [\n { x: sortedPoints[i].x, y: sortedPoints[i].y },\n { x: sortedPoints[i + 1].x, y: sortedPoints[i + 1].y },\n ],\n strokeColor: this.colorMap[segmentId] || \"#000\",\n })\n }\n }\n\n // Connect points with the same connection name that share a node\n const processedConnections = new Set<string>()\n const allPoints = Array.from(this.segmentPointMap.values())\n\n for (let i = 0; i < allPoints.length; i++) {\n const point1 = allPoints[i]\n for (let j = i + 1; j < allPoints.length; j++) {\n const point2 = allPoints[j]\n\n // Skip if they have different connection names or are in the same segment\n if (\n point1.connectionName !== point2.connectionName ||\n point1.segmentId === point2.segmentId\n ) {\n continue\n }\n\n // Check if they share a node\n const hasSharedNode = point1.capacityMeshNodeIds.some((nodeId) =>\n point2.capacityMeshNodeIds.includes(nodeId),\n )\n\n if (hasSharedNode) {\n const connectionKey = `${point1.segmentPointId}-${point2.segmentPointId}`\n if (processedConnections.has(connectionKey)) continue\n processedConnections.add(connectionKey)\n\n // Determine line style based on layer (z) values\n const sameLayer = point1.z === point2.z\n const layer = point1.z\n\n let strokeDash: string | undefined\n if (sameLayer) {\n strokeDash = layer === 0 ? undefined : \"10 5\" // Solid for layer 0, long dash for other layers\n } else {\n strokeDash = \"3 3 10\" // Mixed dash for transitions between layers\n }\n\n graphics.lines.push({\n points: [\n { x: point1.x, y: point1.y },\n { x: point2.x, y: point2.y },\n ],\n strokeDash,\n strokeColor: this.colorMap[point1.connectionName] || \"#666\",\n })\n }\n }\n }\n return graphics\n }\n\n getNodesWithPortPoints(): NodeWithPortPoints[] {\n if (!this.solved) {\n throw new Error(\n \"CapacitySegmentToPointSolver not solved, can't give port points yet\",\n )\n }\n const nodeWithPortPointsMap = new Map<string, NodeWithPortPoints>()\n for (const segment of this.dedupedSegments) {\n const segId = segment.nodePortSegmentId!\n for (const nodeId of this.segmentIdToNodeIds.get(segId)!) {\n const node = this.nodeMap.get(nodeId)!\n if (!nodeWithPortPointsMap.has(nodeId)) {\n nodeWithPortPointsMap.set(nodeId, {\n capacityMeshNodeId: nodeId,\n portPoints: [],\n center: node.center,\n width: node.width,\n height: node.height,\n })\n }\n }\n }\n\n for (const segmentPoint of this.segmentPointMap.values()) {\n for (const nodeId of segmentPoint.capacityMeshNodeIds) {\n const nodeWithPortPoints = nodeWithPortPointsMap.get(nodeId)\n if (nodeWithPortPoints) {\n nodeWithPortPoints.portPoints.push({\n x: segmentPoint.x,\n y: segmentPoint.y,\n z: segmentPoint.z,\n connectionName: segmentPoint.connectionName,\n })\n }\n }\n }\n\n return Array.from(nodeWithPortPointsMap.values())\n }\n}\n","import { Rect } from \"graphics-debug\"\nimport { CapacityMeshNode } from \"lib/types\"\n\nexport const createRectFromCapacityNode = (\n node: CapacityMeshNode,\n opts: {\n rectMargin?: number\n } = {},\n): Rect => {\n const lowestZ = Math.min(...node.availableZ)\n return {\n center: !opts.rectMargin\n ? {\n x: node.center.x + lowestZ * node.width * 0.05,\n y: node.center.y - lowestZ * node.width * 0.05,\n }\n : node.center,\n width: opts.rectMargin\n ? node.width - opts.rectMargin * 2\n : Math.max(node.width - 0.5, node.width * 0.8),\n height: opts.rectMargin\n ? node.height - opts.rectMargin * 2\n : Math.max(node.height - 0.5, node.height * 0.8),\n fill: node._containsObstacle\n ? \"rgba(255,0,0,0.1)\"\n : ({\n \"0,1\": \"rgba(0,0,0,0.1)\",\n \"0\": \"rgba(0,200,200, 0.1)\",\n \"1\": \"rgba(0,0,200, 0.1)\",\n }[node.availableZ.join(\",\")] ?? \"rgba(0,200,200,0.1)\"),\n label: [\n node.capacityMeshNodeId,\n `availableZ: ${node.availableZ.join(\",\")}`,\n `${node._containsTarget ? \"containsTarget\" : \"\"}`,\n `${node._containsObstacle ? \"containsObstacle\" : \"\"}`,\n ]\n .filter(Boolean)\n .join(\"\\n\"),\n }\n}\n","import { BaseSolver } from \"../BaseSolver\"\nimport type {\n CapacityMeshEdge,\n CapacityMeshNode,\n CapacityMeshNodeId,\n CapacityPath,\n SimpleRouteConnection,\n SimpleRouteJson,\n} from \"../../types\"\nimport { getNodeEdgeMap } from \"../CapacityMeshSolver/getNodeEdgeMap\"\nimport { distance } from \"@tscircuit/math-utils\"\nimport { CapacityHyperParameters } from \"../CapacityHyperParameters\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { safeTransparentize } from \"../colors\"\nimport { createRectFromCapacityNode } from \"lib/utils/createRectFromCapacityNode\"\n\nexport type Candidate = {\n prevCandidate: Candidate | null\n node: CapacityMeshNode\n f: number\n g: number\n h: number\n}\n\nexport class CapacityPathingSolver extends BaseSolver {\n connectionsWithNodes: Array<{\n connection: SimpleRouteConnection\n nodes: CapacityMeshNode[]\n path?: CapacityMeshNode[]\n }>\n\n usedNodeCapacityMap: Map<CapacityMeshNodeId, number>\n\n simpleRouteJson: SimpleRouteJson\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n GREEDY_MULTIPLIER = 1.1\n\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n nodeEdgeMap: Map<CapacityMeshNodeId, CapacityMeshEdge[]>\n connectionNameToGoalNodeIds: Map<string, CapacityMeshNodeId[]>\n colorMap: Record<string, string>\n maxDepthOfNodes: number\n\n activeCandidateStraightLineDistance?: number\n\n debug_lastNodeCostMap: Map<\n CapacityMeshNodeId,\n {\n g: number\n h: number\n f: number\n }\n >\n\n hyperParameters: Partial<CapacityHyperParameters>\n\n constructor({\n simpleRouteJson,\n nodes,\n edges,\n colorMap,\n MAX_ITERATIONS = 1e6,\n hyperParameters = {},\n }: {\n simpleRouteJson: SimpleRouteJson\n nodes: CapacityMeshNode[]\n edges: CapacityMeshEdge[]\n colorMap?: Record<string, string>\n MAX_ITERATIONS?: number\n hyperParameters?: Partial<CapacityHyperParameters>\n }) {\n super()\n this.MAX_ITERATIONS = MAX_ITERATIONS\n this.simpleRouteJson = simpleRouteJson\n this.nodes = nodes\n this.edges = edges\n this.colorMap = colorMap ?? {}\n const { connectionsWithNodes, connectionNameToGoalNodeIds } =\n this.getConnectionsWithNodes()\n this.connectionsWithNodes = connectionsWithNodes\n this.connectionNameToGoalNodeIds = connectionNameToGoalNodeIds\n this.hyperParameters = hyperParameters\n this.usedNodeCapacityMap = new Map(\n this.nodes.map((node) => [node.capacityMeshNodeId, 0]),\n )\n this.nodeMap = new Map(\n this.nodes.map((node) => [node.capacityMeshNodeId, node]),\n )\n this.nodeEdgeMap = getNodeEdgeMap(this.edges)\n this.maxDepthOfNodes = Math.max(\n ...this.nodes.map((node) => node._depth ?? 0),\n )\n this.debug_lastNodeCostMap = new Map()\n }\n\n getTotalCapacity(node: CapacityMeshNode): number {\n const depth = node._depth ?? 0\n return (this.maxDepthOfNodes - depth + 1) ** 2\n }\n\n getConnectionsWithNodes() {\n const connectionsWithNodes: Array<{\n connection: SimpleRouteConnection\n nodes: CapacityMeshNode[]\n pathFound: boolean\n }> = []\n const nodesWithTargets = this.nodes.filter((node) => node._containsTarget)\n const connectionNameToGoalNodeIds = new Map<string, CapacityMeshNodeId[]>()\n\n for (const connection of this.simpleRouteJson.connections) {\n const nodesForConnection: CapacityMeshNode[] = []\n for (const point of connection.pointsToConnect) {\n let closestNode = this.nodes[0]\n let minDistance = Number.MAX_VALUE\n\n for (const node of nodesWithTargets) {\n const distance = Math.sqrt(\n (node.center.x - point.x) ** 2 + (node.center.y - point.y) ** 2,\n )\n if (distance < minDistance) {\n minDistance = distance\n closestNode = node\n }\n }\n nodesForConnection.push(closestNode)\n }\n if (nodesForConnection.length < 2) {\n throw new Error(\n `Not enough nodes for connection \"${connection.name}\", only ${nodesForConnection.length} found`,\n )\n }\n connectionNameToGoalNodeIds.set(\n connection.name,\n nodesForConnection.map((n) => n.capacityMeshNodeId),\n )\n connectionsWithNodes.push({\n connection,\n nodes: nodesForConnection,\n pathFound: false,\n })\n }\n return { connectionsWithNodes, connectionNameToGoalNodeIds }\n }\n\n currentConnectionIndex = 0\n\n candidates?: Array<Candidate> | null\n visitedNodes?: Set<CapacityMeshNodeId> | null\n\n computeG(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return (\n prevCandidate.g + this.getDistanceBetweenNodes(prevCandidate.node, node)\n )\n }\n\n computeH(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return this.getDistanceBetweenNodes(node, endGoal)\n }\n\n getBacktrackedPath(candidate: Candidate) {\n const path: CapacityMeshNode[] = []\n let currentCandidate = candidate\n while (currentCandidate) {\n path.push(currentCandidate.node)\n currentCandidate = currentCandidate.prevCandidate!\n }\n return path\n }\n\n getNeighboringNodes(node: CapacityMeshNode) {\n return this.nodeEdgeMap\n .get(node.capacityMeshNodeId)!\n .flatMap((edge): CapacityMeshNodeId[] =>\n edge.nodeIds.filter((n) => n !== node.capacityMeshNodeId),\n )\n .map((n) => this.nodeMap.get(n)!)\n }\n\n getCapacityPaths() {\n const capacityPaths: CapacityPath[] = []\n for (const connection of this.connectionsWithNodes) {\n const path = connection.path\n if (path) {\n capacityPaths.push({\n capacityPathId: connection.connection.name,\n connectionName: connection.connection.name,\n nodeIds: path.map((node) => node.capacityMeshNodeId),\n })\n }\n }\n return capacityPaths\n }\n\n doesNodeHaveCapacityForTrace(node: CapacityMeshNode) {\n const usedCapacity =\n this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0\n const totalCapacity = this.getTotalCapacity(node)\n\n // Single layer nodes can't safely have multiple traces because there's no\n // way to cross over two traces without a via\n if (\n node.availableZ.length === 1 &&\n !node._containsTarget &&\n usedCapacity > 0\n )\n return false\n return usedCapacity < totalCapacity\n }\n\n canTravelThroughObstacle(node: CapacityMeshNode, connectionName: string) {\n const goalNodeIds = this.connectionNameToGoalNodeIds.get(connectionName)\n\n return goalNodeIds?.includes(node.capacityMeshNodeId) ?? false\n }\n\n getDistanceBetweenNodes(A: CapacityMeshNode, B: CapacityMeshNode) {\n return Math.sqrt(\n (A.center.x - B.center.x) ** 2 + (A.center.y - B.center.y) ** 2,\n )\n }\n\n reduceCapacityAlongPath(nextConnection: {\n path?: CapacityMeshNode[]\n }) {\n for (const node of nextConnection.path ?? []) {\n this.usedNodeCapacityMap.set(\n node.capacityMeshNodeId,\n this.usedNodeCapacityMap.get(node.capacityMeshNodeId)! + 1,\n )\n }\n }\n\n isConnectedToEndGoal(node: CapacityMeshNode, endGoal: CapacityMeshNode) {\n return this.nodeEdgeMap\n .get(node.capacityMeshNodeId)!\n .some((edge) => edge.nodeIds.includes(endGoal.capacityMeshNodeId))\n }\n\n _step() {\n const nextConnection =\n this.connectionsWithNodes[this.currentConnectionIndex]\n if (!nextConnection) {\n this.solved = true\n return\n }\n const [start, end] = nextConnection.nodes\n if (!this.candidates) {\n this.candidates = [{ prevCandidate: null, node: start, f: 0, g: 0, h: 0 }]\n this.debug_lastNodeCostMap = new Map()\n this.visitedNodes = new Set([start.capacityMeshNodeId])\n this.activeCandidateStraightLineDistance = distance(\n start.center,\n end.center,\n )\n }\n\n this.candidates.sort((a, b) => a.f - b.f)\n const currentCandidate = this.candidates.shift()\n if (!currentCandidate) {\n // TODO Track failed paths, make sure solver doesn't think it solved\n console.error(\n `Ran out of candidates on connection ${nextConnection.connection.name}`,\n )\n this.currentConnectionIndex++\n this.candidates = null\n this.visitedNodes = null\n return\n }\n if (this.isConnectedToEndGoal(currentCandidate.node, end)) {\n nextConnection.path = this.getBacktrackedPath({\n prevCandidate: currentCandidate,\n node: end,\n f: 0,\n g: 0,\n h: 0,\n })\n\n this.reduceCapacityAlongPath(nextConnection)\n\n this.currentConnectionIndex++\n this.candidates = null\n this.visitedNodes = null\n return\n }\n\n const neighborNodes = this.getNeighboringNodes(currentCandidate.node)\n for (const neighborNode of neighborNodes) {\n if (this.visitedNodes?.has(neighborNode.capacityMeshNodeId)) {\n continue\n }\n if (!this.doesNodeHaveCapacityForTrace(neighborNode)) {\n continue\n }\n const connectionName =\n this.connectionsWithNodes[this.currentConnectionIndex].connection.name\n if (\n neighborNode._containsObstacle &&\n !this.canTravelThroughObstacle(neighborNode, connectionName)\n ) {\n continue\n }\n const g = this.computeG(currentCandidate, neighborNode, end)\n const h = this.computeH(currentCandidate, neighborNode, end)\n const f = g + h * this.GREEDY_MULTIPLIER\n\n this.debug_lastNodeCostMap.set(neighborNode.capacityMeshNodeId, {\n f,\n g,\n h,\n })\n\n const newCandidate = {\n prevCandidate: currentCandidate,\n node: neighborNode,\n f,\n g,\n h,\n }\n this.candidates.push(newCandidate)\n }\n this.visitedNodes!.add(currentCandidate.node.capacityMeshNodeId)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n lines: [],\n points: [],\n rects: [],\n circles: [],\n }\n\n // Visualize each solved connection path (draw a line through each node's center)\n if (this.connectionsWithNodes) {\n for (let i = 0; i < this.connectionsWithNodes.length; i++) {\n const conn = this.connectionsWithNodes[i]\n if (conn.path && conn.path.length > 0) {\n const pathPoints = conn.path.map(({ center: { x, y }, width }) => ({\n // slight offset to allow viewing overlapping paths\n x: x + ((i % 10) + (i % 19)) * (0.01 * width),\n y: y + ((i % 10) + (i % 19)) * (0.01 * width),\n }))\n graphics.lines!.push({\n points: pathPoints,\n strokeColor: this.colorMap[conn.connection.name],\n })\n }\n }\n }\n\n for (const node of this.nodes) {\n const nodeCosts = this.debug_lastNodeCostMap.get(node.capacityMeshNodeId)\n graphics.rects!.push({\n ...createRectFromCapacityNode(node),\n label: [\n `${node.capacityMeshNodeId}`,\n `${this.usedNodeCapacityMap.get(node.capacityMeshNodeId)}/${this.getTotalCapacity(node).toFixed(2)}`,\n `${node.width.toFixed(2)}x${node.height.toFixed(2)}`,\n `g: ${nodeCosts?.g !== undefined ? nodeCosts.g.toFixed(2) : \"?\"}`,\n `h: ${nodeCosts?.h !== undefined ? nodeCosts.h.toFixed(2) : \"?\"}`,\n `f: ${nodeCosts?.f !== undefined ? nodeCosts.f.toFixed(2) : \"?\"}`,\n ].join(\"\\n\"),\n })\n }\n\n // Visualize connection points from each connection as circles\n if (this.connectionsWithNodes) {\n for (const conn of this.connectionsWithNodes) {\n if (conn.connection?.pointsToConnect) {\n for (const point of conn.connection.pointsToConnect) {\n graphics.points!.push({\n x: point.x,\n y: point.y,\n })\n }\n }\n }\n }\n\n // Draw a dashed line from the start node to the end node\n const nextConnection =\n this.connectionsWithNodes[this.currentConnectionIndex]\n if (nextConnection) {\n const [start, end] = nextConnection.connection.pointsToConnect\n graphics.lines!.push({\n points: [\n { x: start.x, y: start.y },\n { x: end.x, y: end.y },\n ],\n strokeColor: \"red\",\n strokeDash: \"10 5\",\n })\n }\n\n // Visualize backtracked path of highest ranked candidate\n if (this.candidates) {\n // Get top 10 candidates\n const topCandidates = this.candidates.slice(0, 5)\n const connectionName =\n this.connectionsWithNodes[this.currentConnectionIndex].connection.name\n\n // Add paths for each candidate with decreasing opacity\n topCandidates.forEach((candidate, index) => {\n const opacity = 0.5 * (1 - index / 5) // Opacity decreases from 0.5 to 0.05\n const backtrackedPath = this.getBacktrackedPath(candidate)\n graphics.lines!.push({\n points: backtrackedPath.map(({ center: { x, y } }) => ({ x, y })),\n strokeColor: safeTransparentize(\n this.colorMap[connectionName] ?? \"red\",\n 1 - opacity,\n ),\n })\n })\n }\n\n return graphics\n }\n}\n","import type { CapacityMeshNode } from \"lib/types\"\nimport { CapacityPathingSolver, type Candidate } from \"./CapacityPathingSolver\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\n\nexport class CapacityPathingSolver5 extends CapacityPathingSolver {\n NEGATIVE_CAPACITY_PENALTY_FACTOR = 1\n REDUCED_CAPACITY_PENALTY_FACTOR = 1\n\n constructor(...args: ConstructorParameters<typeof CapacityPathingSolver>) {\n super(...args)\n this.GREEDY_MULTIPLIER = 2.5\n }\n\n get maxCapacityFactor() {\n return this.hyperParameters.MAX_CAPACITY_FACTOR ?? 1\n }\n\n getTotalCapacity(node: CapacityMeshNode): number {\n return getTunedTotalCapacity1(node, this.maxCapacityFactor)\n }\n\n /**\n * Penalty you pay for using this node\n */\n getNodeCapacityPenalty(node: CapacityMeshNode): number {\n return 0.05\n if (node.availableZ.length === 1) {\n return 0\n }\n\n const totalCapacity = this.getTotalCapacity(node)\n const usedCapacity =\n this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0\n const remainingCapacity = totalCapacity - usedCapacity\n\n const dist = this.activeCandidateStraightLineDistance!\n\n if (remainingCapacity <= 0) {\n // | Total Cap | Remaining Cap | Remaining Cap Ratio | PenaltySLD |\n // | 1 | 0 | (-( 0) + 1) / 1 | 1^2 = 1 |\n // | 1 | -1 | (-(-1) + 1) / 1 | 2^2 = 4 |\n // | 1 | -2 | (-(-2) + 1) / 1 | 3^2 = 9 |\n // | 2 | 0 | (-( 0) + 1) / 2 | 0.5^2 = 0.25 |\n // | 2 | -1 | (-(-1) + 1) / 2 | 1^2 = 1 |\n // | 2 | -2 | (-(-2) + 1) / 2 | 2^2 = 4 |\n // | 2 | -3 | (-(-3) + 1) / 2 | 3^2 = 9 |\n // | 3 | 0 | (-( 0) + 1) / 3 | 0.333^2= 0.111|\n // | 3 | -1 | (-(-1) + 1) / 3 | 0.666^2= 0.444|\n // | 3 | -2 | (-(-2) + 1) / 3 | 1^2 = 1 |\n // | 3 | -3 | (-(-3) + 1) / 3 | 2^2 = 4 |\n const penalty =\n ((-remainingCapacity + 1) / totalCapacity) *\n dist *\n (this.NEGATIVE_CAPACITY_PENALTY_FACTOR / 4)\n\n return penalty ** 2\n }\n\n // This node still has capacity, but penalize as we reduce the capacity\n return (\n ((1 / remainingCapacity) * dist * this.REDUCED_CAPACITY_PENALTY_FACTOR) /\n 8\n )\n }\n\n /**\n * We're rewarding travel into big nodes.\n *\n * To minimize shortest path, you'd want to comment this out.\n */\n getDistanceBetweenNodes(A: CapacityMeshNode, B: CapacityMeshNode) {\n const dx = A.center.x - B.center.x\n const dy = A.center.y - B.center.y\n\n return Math.sqrt(dx ** 2 + dy ** 2)\n\n // REWARD BIG NODE TRAVEL\n // const szx = Math.max(A.width, B.width)\n // const szy = Math.max(A.height, B.height)\n\n // const dist = Math.sqrt(dx ** 2 + dy ** 2) / (szx * szy)\n\n // return dist\n }\n\n computeG(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return (\n prevCandidate.g +\n this.getDistanceBetweenNodes(prevCandidate.node, node) +\n this.getNodeCapacityPenalty(node)\n )\n }\n\n computeH(\n prevCandidate: Candidate,\n node: CapacityMeshNode,\n endGoal: CapacityMeshNode,\n ) {\n return this.getDistanceBetweenNodes(node, endGoal)\n }\n}\n","import { CapacityMeshNode } from \"lib/types/capacity-mesh-types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { getTunedTotalCapacity1 } from \"lib/utils/getTunedTotalCapacity1\"\n\nexport class StrawSolver extends BaseSolver {\n multiLayerNodes: CapacityMeshNode[]\n\n strawNodes: CapacityMeshNode[]\n skippedNodes: CapacityMeshNode[]\n\n unprocessedNodes: CapacityMeshNode[]\n strawSize: number\n\n nodeIdCounter: number\n\n constructor(params: {\n nodes: CapacityMeshNode[]\n strawSize?: number\n }) {\n super()\n this.strawSize = params.strawSize ?? 0.5\n this.multiLayerNodes = []\n this.strawNodes = []\n this.skippedNodes = []\n this.nodeIdCounter = 0\n this.unprocessedNodes = []\n for (const node of params.nodes) {\n if (node.availableZ.length === 1) {\n this.unprocessedNodes.push(node)\n } else {\n this.multiLayerNodes.push(node)\n }\n }\n }\n\n getCapacityOfMultiLayerNodesWithinBounds(bounds: {\n minX: number\n maxX: number\n minY: number\n maxY: number\n }): number {\n let totalCapacity = 0\n\n for (const node of this.multiLayerNodes) {\n // Calculate node bounds\n const nodeMinX = node.center.x - node.width / 2\n const nodeMaxX = node.center.x + node.width / 2\n const nodeMinY = node.center.y - node.height / 2\n const nodeMaxY = node.center.y + node.height / 2\n\n // Calculate overlap area\n const overlapMinX = Math.max(bounds.minX, nodeMinX)\n const overlapMaxX = Math.min(bounds.maxX, nodeMaxX)\n const overlapMinY = Math.max(bounds.minY, nodeMinY)\n const overlapMaxY = Math.min(bounds.maxY, nodeMaxY)\n\n // If there's an overlap\n if (overlapMinX < overlapMaxX && overlapMinY < overlapMaxY) {\n const overlapWidth = overlapMaxX - overlapMinX\n const overlapHeight = overlapMaxY - overlapMinY\n const overlapArea = overlapWidth * overlapHeight\n const nodeArea = node.width * node.height\n\n // Calculate proportion of node that overlaps\n const proportion = overlapArea / nodeArea\n\n // Add proportional capacity to total\n totalCapacity += getTunedTotalCapacity1(node) * proportion\n }\n }\n\n return totalCapacity\n }\n\n getSurroundingCapacities(node: CapacityMeshNode): {\n leftSurroundingCapacity: number\n rightSurroundingCapacity: number\n topSurroundingCapacity: number\n bottomSurroundingCapacity: number\n } {\n const searchDistance = Math.min(node.width, node.height)\n\n const leftSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x - node.width / 2 - searchDistance,\n maxX: node.center.x - node.width / 2,\n minY: node.center.y - node.height / 2,\n maxY: node.center.y + node.height / 2,\n })\n\n const rightSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x + node.width / 2,\n maxX: node.center.x + node.width / 2 + searchDistance,\n minY: node.center.y - node.height / 2,\n maxY: node.center.y + node.height / 2,\n })\n\n const topSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x - node.width / 2,\n maxX: node.center.x + node.width / 2,\n minY: node.center.y - node.height / 2 - searchDistance,\n maxY: node.center.y - node.height / 2,\n })\n\n const bottomSurroundingCapacity =\n this.getCapacityOfMultiLayerNodesWithinBounds({\n minX: node.center.x - node.width / 2,\n maxX: node.center.x + node.width / 2,\n minY: node.center.y + node.height / 2,\n maxY: node.center.y + node.height / 2 + searchDistance,\n })\n\n return {\n leftSurroundingCapacity,\n rightSurroundingCapacity,\n topSurroundingCapacity,\n bottomSurroundingCapacity,\n }\n }\n /**\n * Creates straw nodes from a single-layer node based on surrounding capacities\n */\n createStrawsForNode(node: CapacityMeshNode): CapacityMeshNode[] {\n const result: CapacityMeshNode[] = []\n const {\n leftSurroundingCapacity,\n rightSurroundingCapacity,\n topSurroundingCapacity,\n bottomSurroundingCapacity,\n } = this.getSurroundingCapacities(node)\n\n // Decide whether to create horizontal or vertical straws\n const horizontalCapacity =\n leftSurroundingCapacity + rightSurroundingCapacity\n const verticalCapacity = topSurroundingCapacity + bottomSurroundingCapacity\n\n // Layer-specific preferred direction\n // Layer 0 (top) prefers horizontal traces, Layer 1 (bottom) prefers vertical\n const layerPrefersFactor = 1 // node.availableZ[0] === 0 ? 1.3 : 0.7\n\n const effectiveHorizontalCapacity = horizontalCapacity * layerPrefersFactor\n\n // Create straws based on dimensions and surrounding capacity\n if (effectiveHorizontalCapacity > verticalCapacity) {\n // Create horizontal straws\n const numStraws = Math.floor(node.height / this.strawSize)\n const strawHeight = node.height / numStraws\n\n for (let i = 0; i < numStraws; i++) {\n const strawCenterY =\n node.center.y - node.height / 2 + i * strawHeight + strawHeight / 2\n\n result.push({\n capacityMeshNodeId: `${node.capacityMeshNodeId}_straw${i}`,\n center: { x: node.center.x, y: strawCenterY },\n width: node.width,\n height: strawHeight,\n layer: node.layer,\n availableZ: [...node.availableZ],\n _depth: node._depth,\n _strawNode: true,\n })\n }\n } else {\n // Create vertical straws\n const numStraws = Math.floor(node.width / this.strawSize)\n const strawWidth = node.width / numStraws\n\n for (let i = 0; i < numStraws; i++) {\n const strawCenterX =\n node.center.x - node.width / 2 + i * strawWidth + strawWidth / 2\n\n result.push({\n capacityMeshNodeId: `${node.capacityMeshNodeId}_straw${i}`,\n center: { x: strawCenterX, y: node.center.y },\n width: strawWidth,\n height: node.height,\n layer: node.layer,\n availableZ: [...node.availableZ],\n _depth: node._depth,\n _strawNode: true,\n })\n }\n }\n\n return result\n }\n\n getResultNodes(): CapacityMeshNode[] {\n return [...this.multiLayerNodes, ...this.strawNodes, ...this.skippedNodes]\n }\n\n _step() {\n const rootNode = this.unprocessedNodes.pop()\n\n if (!rootNode) {\n this.solved = true\n return\n }\n\n // Skip nodes that are too small to subdivide\n if (\n rootNode.width < this.strawSize * 5 &&\n rootNode.height < this.strawSize * 5\n ) {\n this.skippedNodes.push(rootNode)\n return\n }\n\n // Skip target nodes (keep them intact)\n if (rootNode._containsTarget) {\n this.skippedNodes.push(rootNode)\n return\n }\n\n // Create straws for this node\n const strawNodes = this.createStrawsForNode(rootNode)\n this.strawNodes.push(...strawNodes)\n }\n\n visualize(): GraphicsObject {\n const graphics: GraphicsObject = {\n rects: [],\n lines: [],\n points: [],\n circles: [],\n title: \"Straw Solver\",\n }\n\n // Draw unprocessed nodes\n for (const node of this.unprocessedNodes) {\n graphics.rects!.push({\n center: node.center,\n width: node.width,\n height: node.height,\n fill: \"rgba(200, 200, 200, 0.5)\",\n stroke: \"rgba(0, 0, 0, 0.5)\",\n label: `${node.capacityMeshNodeId}\\nUnprocessed\\n${node.width}x${node.height}`,\n })\n }\n\n // Draw straw nodes with different colors based on layer\n for (const node of this.strawNodes) {\n const color =\n node.availableZ[0] === 0\n ? \"rgba(0, 150, 255, 0.5)\"\n : \"rgba(255, 100, 0, 0.5)\"\n\n graphics.rects!.push({\n center: node.center,\n width: node.width,\n height: node.height,\n fill: color,\n stroke: \"rgba(0, 0, 0, 0.5)\",\n label: `${node.capacityMeshNodeId}\\nLayer: ${node.availableZ[0]}\\n${node.width}x${node.height}`,\n })\n }\n\n // Draw multi-layer nodes\n for (const node of this.multiLayerNodes) {\n graphics.rects!.push({\n center: node.center,\n width: node.width * 0.9,\n height: node.height * 0.9,\n fill: \"rgba(100, 255, 100, 0.5)\",\n stroke: \"rgba(0, 0, 0, 0.5)\",\n layer: `z${node.availableZ.join(\",\")}`,\n label: `${node.capacityMeshNodeId}\\nLayers: ${node.availableZ.join(\",\")}\\n${node.width}x${node.height}`,\n })\n }\n\n return graphics\n }\n}\n","import { CapacityMeshNode, CapacityMeshNodeId } from \"lib/types\"\nimport { BaseSolver } from \"../BaseSolver\"\nimport { areNodesBordering } from \"lib/utils/areNodesBordering\"\nimport { GraphicsObject } from \"graphics-debug\"\nimport { createRectFromCapacityNode } from \"lib/utils/createRectFromCapacityNode\"\n\nconst EPSILON = 0.005\n\n/**\n * Merges same layer nodes into larger nodes. Pre-processing stage necessary\n * for \"strawing\".\n */\nexport class SingleLayerNodeMergerSolver extends BaseSolver {\n nodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>\n currentBatchNodeIds: CapacityMeshNodeId[]\n\n absorbedNodeIds: Set<CapacityMeshNodeId>\n\n nextBatchNodeIds: CapacityMeshNodeId[]\n batchHadModifications: boolean\n\n newNodes: CapacityMeshNode[]\n constructor(nodes: CapacityMeshNode[]) {\n super()\n this.nodeMap = new Map()\n this.MAX_ITERATIONS = 100_000\n for (const node of nodes) {\n this.nodeMap.set(node.capacityMeshNodeId, node)\n }\n this.newNodes = []\n this.absorbedNodeIds = new Set()\n const nodeWithArea: Array<[string, number]> = []\n for (const node of nodes) {\n if (node.availableZ.length > 1) {\n this.newNodes.push(node)\n this.absorbedNodeIds.add(node.capacityMeshNodeId)\n } else {\n nodeWithArea.push([node.capacityMeshNodeId, node.width * node.height])\n }\n }\n nodeWithArea.sort((a, b) => a[1] - b[1])\n this.currentBatchNodeIds = nodeWithArea.map((n) => n[0])\n this.nextBatchNodeIds = []\n this.batchHadModifications = false\n }\n\n getAdjacentSameLayerUnprocessedNodes(rootNode: CapacityMeshNode) {\n const adjacentNodes: CapacityMeshNode[] = []\n for (const unprocessedNodeId of this.currentBatchNodeIds) {\n if (this.absorbedNodeIds.has(unprocessedNodeId)) continue\n const unprocessedNode = this.nodeMap.get(unprocessedNodeId)!\n if (unprocessedNode.availableZ[0] !== rootNode.availableZ[0]) continue\n if (\n unprocessedNode._containsTarget &&\n unprocessedNode._targetConnectionName !== rootNode._targetConnectionName\n )\n continue\n if (!areNodesBordering(rootNode, unprocessedNode)) continue\n adjacentNodes.push(unprocessedNode)\n }\n return adjacentNodes\n }\n\n _step() {\n let rootNodeId = this.currentBatchNodeIds.pop()\n while (rootNodeId && this.absorbedNodeIds.has(rootNodeId)) {\n rootNodeId = this.currentBatchNodeIds.pop()\n }\n\n if (!rootNodeId) {\n if (this.batchHadModifications) {\n this.currentBatchNodeIds = this.nextBatchNodeIds.sort((a, b) => {\n const A = this.nodeMap.get(a)!\n const B = this.nodeMap.get(b)!\n return A.width * A.height - B.width * B.height\n })\n this.nextBatchNodeIds = []\n this.batchHadModifications = false\n return\n }\n\n this.solved = true\n this.newNodes.push(\n ...this.nextBatchNodeIds.map((id) => this.nodeMap.get(id)!),\n )\n return\n }\n\n const rootNode = this.nodeMap.get(rootNodeId)!\n let rootNodeHasGrown = false\n\n const adjacentNodes = this.getAdjacentSameLayerUnprocessedNodes(rootNode)\n\n if (adjacentNodes.length === 0) {\n this.nextBatchNodeIds.push(rootNodeId)\n return\n }\n\n // Handle adjacent nodes to the LEFT\n const adjacentNodesToLeft = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.x < rootNode.center.x &&\n Math.abs(adjNode.center.y - rootNode.center.y) < rootNode.height / 2,\n )\n\n if (adjacentNodesToLeft.length > 0) {\n const { width: leftAdjNodeWidth, height: leftAdjNodeHeight } =\n adjacentNodesToLeft[0]\n const leftAdjNodesAreAllSameSize = adjacentNodesToLeft.every(\n (adjNode) =>\n adjNode.width === leftAdjNodeWidth &&\n adjNode.height === leftAdjNodeHeight,\n )\n\n const leftAdjNodesTakeUpEntireHeight =\n Math.abs(\n adjacentNodesToLeft.reduce((acc, adjNode) => {\n return acc + adjNode.height\n }, 0) - rootNode.height,\n ) < EPSILON\n\n if (leftAdjNodesTakeUpEntireHeight && leftAdjNodesAreAllSameSize) {\n rootNode.width += leftAdjNodeWidth\n rootNode.center.x = rootNode.center.x - leftAdjNodeWidth / 2\n\n for (const adjNode of adjacentNodesToLeft) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n // Handle adjacent nodes to the RIGHT\n const adjacentNodesToRight = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.x > rootNode.center.x &&\n Math.abs(adjNode.center.y - rootNode.center.y) < rootNode.height / 2,\n )\n\n if (adjacentNodesToRight.length > 0 && !rootNodeHasGrown) {\n const { width: rightAdjNodeWidth, height: rightAdjNodeHeight } =\n adjacentNodesToRight[0]\n const rightAdjNodesAreAllSameSize = adjacentNodesToRight.every(\n (adjNode) =>\n adjNode.width === rightAdjNodeWidth &&\n adjNode.height === rightAdjNodeHeight,\n )\n\n const rightAdjNodesTakeUpEntireHeight =\n Math.abs(\n adjacentNodesToRight.reduce((acc, adjNode) => {\n return acc + adjNode.height\n }, 0) - rootNode.height,\n ) < EPSILON\n\n if (rightAdjNodesTakeUpEntireHeight && rightAdjNodesAreAllSameSize) {\n rootNode.width += rightAdjNodeWidth\n rootNode.center.x = rootNode.center.x + rightAdjNodeWidth / 2\n\n for (const adjNode of adjacentNodesToRight) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n // Handle adjacent nodes to the TOP\n const adjacentNodesToTop = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.y > rootNode.center.y &&\n Math.abs(adjNode.center.x - rootNode.center.x) < rootNode.width / 2,\n )\n\n if (adjacentNodesToTop.length > 0 && !rootNodeHasGrown) {\n const { width: topAdjNodeWidth, height: topAdjNodeHeight } =\n adjacentNodesToTop[0]\n const topAdjNodesAreAllSameSize = adjacentNodesToTop.every(\n (adjNode) =>\n adjNode.width === topAdjNodeWidth &&\n adjNode.height === topAdjNodeHeight,\n )\n\n const topAdjNodesTakeUpEntireWidth =\n Math.abs(\n adjacentNodesToTop.reduce((acc, adjNode) => {\n return acc + adjNode.width\n }, 0) - rootNode.width,\n ) < EPSILON\n\n if (topAdjNodesTakeUpEntireWidth && topAdjNodesAreAllSameSize) {\n rootNode.height += topAdjNodeHeight\n rootNode.center.y = rootNode.center.y + topAdjNodeHeight / 2\n\n for (const adjNode of adjacentNodesToTop) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n // Handle adjacent nodes to the BOTTOM\n const adjacentNodesToBottom = adjacentNodes.filter(\n (adjNode) =>\n adjNode.center.y < rootNode.center.y &&\n Math.abs(adjNode.center.x - rootNode.center.x) < rootNode.width / 2,\n )\n\n if (adjacentNodesToBottom.length > 0 && !rootNodeHasGrown) {\n const { width: bottomAdjNodeWidth, height: bottomAdjNodeHeight } =\n adjacentNodesToBottom[0]\n const bottomAdjNodesAreAllSameSize = adjacentNodesToBottom.every(\n (adjNode) =>\n adjNode.width === bottomAdjNodeWidth &&\n adjNode.height === bottomAdjNodeHeight,\n )\n\n const bottomAdjNodesTakeUpEntireWidth =\n Math.abs(\n adjacentNodesToBottom.reduce((acc, adjNode) => {\n return acc + adjNode.width\n }, 0) - rootNode.width,\n ) < EPSILON\n\n if (bottomAdjNodesTakeUpEntireWidth && bottomAdjNodesAreAllSameSize) {\n rootNode.height += bottomAdjNodeHeight\n rootNode.center.y = rootNode.center.y - bottomAdjNodeHeight / 2\n\n for (const adjNode of adjacentNodesToBottom) {\n this.absorbedNodeIds.add(adjNode.capacityMeshNodeId)\n }\n\n rootNodeHasGrown = true\n }\n }\n\n if (rootNodeHasGrown) {\n this.batchHadModifications = true\n this.currentBatchNodeIds.push(rootNodeId)\n } else {\n this.nextBatchNodeIds.unshift(rootNodeId)\n // this.processedNodeIds.add(rootNodeId)\n // this.newNodes.push(rootNode)\n }\n }\n\n visualize(): GraphicsObject {\n const graphics = {\n circles: [],\n lines: [],\n points: [],\n rects: [],\n coordinateSystem: \"cartesian\",\n title: \"Same Layer Node Merger\",\n } as Required<GraphicsObject>\n\n for (const node of this.newNodes) {\n graphics.rects.push(createRectFromCapacityNode(node))\n }\n\n const nextNodeIdInBatch =\n this.currentBatchNodeIds[this.currentBatchNodeIds.length - 1]\n let adjacentNodes: CapacityMeshNode[] | undefined\n if (nextNodeIdInBatch) {\n adjacentNodes = this.getAdjacentSameLayerUnprocessedNodes(\n this.nodeMap.get(nextNodeIdInBatch)!,\n )\n }\n\n // Visualize unprocessed nodes with a different style\n for (const nodeId of this.currentBatchNodeIds) {\n const node = this.nodeMap.get(nodeId)\n if (this.absorbedNodeIds.has(nodeId)) continue\n if (node) {\n const rect = createRectFromCapacityNode(node, {\n rectMargin: 0.01,\n })\n if (nodeId === nextNodeIdInBatch) {\n rect.stroke = \"rgba(0, 255, 0, 0.8)\" // Green for next node in batch\n } else if (\n adjacentNodes?.some(\n (adjNode) => adjNode.capacityMeshNodeId === nodeId,\n )\n ) {\n rect.stroke = \"rgba(128, 0, 128, 0.8)\" // Purple for adjacent nodes\n } else {\n rect.stroke = \"rgba(255, 165, 0, 0.8)\" // Orange border for other nodes\n }\n rect.layer = `z${node.availableZ.join(\",\")}`\n rect.label = `${rect.label}\\n(unprocessed)`\n graphics.rects.push(rect)\n }\n }\n\n // Visualize next batch nodes with a different style\n for (const nodeId of this.nextBatchNodeIds) {\n const node = this.nodeMap.get(nodeId)\n if (this.absorbedNodeIds.has(nodeId)) continue\n if (node) {\n const rect = createRectFromCapacityNode(node, {\n rectMargin: 0.01,\n })\n rect.layer = `z${node.availableZ.join(\",\")}`\n rect.stroke = \"rgba(0, 217, 255, 0.8)\" // Green border\n rect.label = `${rect.label}\\nx: ${node.center.x}, y: ${node.center.y}\\n${node.width}x${node.height}\\n(next batch)`\n graphics.rects.push(rect)\n }\n }\n\n return graphics\n }\n}\n","import type { GraphicsObject } from \"graphics-debug\"\nimport { combineVisualizations } from \"../utils/combineVisualizations\"\nimport type {\n CapacityMeshNode,\n SimpleRouteJson,\n SimplifiedPcbTrace,\n SimplifiedPcbTraces,\n TraceId,\n} from \"../types\"\nimport { BaseSolver } from \"./BaseSolver\"\nimport { CapacityMeshEdgeSolver } from \"./CapacityMeshSolver/CapacityMeshEdgeSolver\"\nimport { CapacityMeshNodeSolver } from \"./CapacityMeshSolver/CapacityMeshNodeSolver1\"\nimport { CapacityMeshNodeSolver2_NodeUnderObstacle } from \"./CapacityMeshSolver/CapacityMeshNodeSolver2_NodesUnderObstacles\"\nimport { CapacityPathingSolver } from \"./CapacityPathingSolver/CapacityPathingSolver\"\nimport { CapacityEdgeToPortSegmentSolver } from \"./CapacityMeshSolver/CapacityEdgeToPortSegmentSolver\"\nimport { getColorMap } from \"./colors\"\nimport { CapacitySegmentToPointSolver } from \"./CapacityMeshSolver/CapacitySegmentToPointSolver\"\nimport { HighDensitySolver } from \"./HighDensitySolver/HighDensitySolver\"\nimport type { NodePortSegment } from \"../types/capacity-edges-to-port-segments-types\"\nimport { CapacityPathingSolver2_AvoidLowCapacity } from \"./CapacityPathingSolver/CapacityPathingSolver2_AvoidLowCapacity\"\nimport { CapacityPathingSolver3_FlexibleNegativeCapacity_AvoidLowCapacity } from \"./CapacityPathingSolver/CapacityPathingSolver3_FlexibleNegativeCapacity_AvoidLowCapacity\"\nimport { CapacityPathingSolver4_FlexibleNegativeCapacity } from \"./CapacityPathingSolver/CapacityPathingSolver4_FlexibleNegativeCapacity_AvoidLowCapacity_FixedDistanceCost\"\nimport { ConnectivityMap } from \"circuit-json-to-connectivity-map\"\nimport { getConnectivityMapFromSimpleRouteJson } from \"lib/utils/getConnectivityMapFromSimpleRouteJson\"\nimport { CapacityNodeTargetMerger } from \"./CapacityNodeTargetMerger/CapacityNodeTargetMerger\"\nimport { CapacitySegmentPointOptimizer } from \"./CapacitySegmentPointOptimizer/CapacitySegmentPointOptimizer\"\nimport { calculateOptimalCapacityDepth } from \"../utils/getTunedTotalCapacity1\"\nimport { NetToPointPairsSolver } from \"./NetToPointPairsSolver/NetToPointPairsSolver\"\nimport { convertHdRouteToSimplifiedRoute } from \"lib/utils/convertHdRouteToSimplifiedRoute\"\nimport { mergeRouteSegments } from \"lib/utils/mergeRouteSegments\"\nimport { mapLayerNameToZ } from \"lib/utils/mapLayerNameToZ\"\nimport { MultipleHighDensityRouteStitchSolver } from \"./RouteStitchingSolver/MultipleHighDensityRouteStitchSolver\"\nimport { convertSrjToGraphicsObject } from \"tests/fixtures/convertSrjToGraphicsObject\"\nimport { UnravelMultiSectionSolver } from \"./UnravelSolver/UnravelMultiSectionSolver\"\nimport { CapacityPathingSolver5 } from \"./CapacityPathingSolver/CapacityPathingSolver5\"\nimport { CapacityMeshNodeSolver3_LargerSingleLayerNodes } from \"./CapacityMeshSolver/CapacityMeshNodeSolver3_LargerSingleLayerNodes\"\nimport { StrawSolver } from \"./StrawSolver/StrawSolver\"\nimport { SingleLayerNodeMergerSolver } from \"./SingleLayerNodeMerger/SingleLayerNodeMergerSolver\"\nimport { CapacityNodeTargetMerger2 } from \"./CapacityNodeTargetMerger/CapacityNodeTargetMerger2\"\n\ninterface CapacityMeshSolverOptions {\n capacityDepth?: number\n targetMinCapacity?: number\n}\n\ntype PipelineStep<T extends new (...args: any[]) => BaseSolver> = {\n solverName: string\n solverClass: T\n getConstructorParams: (\n instance: CapacityMeshSolver,\n ) => ConstructorParameters<T>\n onSolved?: (instance: CapacityMeshSolver) => void\n}\n\nfunction definePipelineStep<\n T extends new (\n ...args: any[]\n ) => BaseSolver,\n const P extends ConstructorParameters<T>,\n>(\n solverName: keyof CapacityMeshSolver,\n solverClass: T,\n getConstructorParams: (instance: CapacityMeshSolver) => P,\n opts: {\n onSolved?: (instance: CapacityMeshSolver) => void\n } = {},\n): PipelineStep<T> {\n return {\n solverName,\n solverClass,\n getConstructorParams,\n onSolved: opts.onSolved,\n }\n}\n\nexport class CapacityMeshSolver extends BaseSolver {\n netToPointPairsSolver?: NetToPointPairsSolver\n nodeSolver?: CapacityMeshNodeSolver\n nodeTargetMerger?: CapacityNodeTargetMerger\n edgeSolver?: CapacityMeshEdgeSolver\n pathingSolver?: CapacityPathingSolver\n edgeToPortSegmentSolver?: CapacityEdgeToPortSegmentSolver\n colorMap: Record<string, string>\n segmentToPointSolver?: CapacitySegmentToPointSolver\n unravelMultiSectionSolver?: UnravelMultiSectionSolver\n segmentToPointOptimizer?: CapacitySegmentPointOptimizer\n highDensityRouteSolver?: HighDensitySolver\n highDensityStitchSolver?: MultipleHighDensityRouteStitchSolver\n singleLayerNodeMerger?: SingleLayerNodeMergerSolver\n strawSolver?: StrawSolver\n\n startTimeOfPhase: Record<string, number>\n endTimeOfPhase: Record<string, number>\n timeSpentOnPhase: Record<string, number>\n\n activeSubSolver?: BaseSolver | null = null\n connMap: ConnectivityMap\n srjWithPointPairs?: SimpleRouteJson\n capacityNodes: CapacityMeshNode[] | null = null\n\n pipelineDef = [\n definePipelineStep(\n \"netToPointPairsSolver\",\n NetToPointPairsSolver,\n (cms) => [cms.srj, cms.colorMap],\n {\n onSolved: (cms) => {\n cms.srjWithPointPairs =\n cms.netToPointPairsSolver?.getNewSimpleRouteJson()\n cms.colorMap = getColorMap(cms.srjWithPointPairs!, this.connMap)\n cms.connMap = getConnectivityMapFromSimpleRouteJson(\n cms.srjWithPointPairs!,\n )\n },\n },\n ),\n // definePipelineStep(\"nodeSolver\", CapacityMeshNodeSolver, (cms) => [\n // cms.netToPointPairsSolver?.getNewSimpleRouteJson() || cms.srj,\n // cms.opts,\n // ]),\n definePipelineStep(\n \"nodeSolver\",\n CapacityMeshNodeSolver2_NodeUnderObstacle,\n (cms) => [\n cms.netToPointPairsSolver?.getNewSimpleRouteJson() || cms.srj,\n cms.opts,\n ],\n ),\n // definePipelineStep(\"nodeTargetMerger\", CapacityNodeTargetMerger, (cms) => [\n // cms.nodeSolver?.finishedNodes || [],\n // cms.srj.obstacles,\n // cms.connMap,\n // ]),\n // definePipelineStep(\"nodeTargetMerger\", CapacityNodeTargetMerger2, (cms) => [\n // cms.nodeSolver?.finishedNodes || [],\n // cms.srj.obstacles,\n // cms.connMap,\n // cms.colorMap,\n // cms.srj.connections,\n // ]),\n definePipelineStep(\n \"singleLayerNodeMerger\",\n SingleLayerNodeMergerSolver,\n (cms) => [cms.nodeSolver?.finishedNodes!],\n ),\n definePipelineStep(\n \"strawSolver\",\n StrawSolver,\n (cms) => [{ nodes: cms.singleLayerNodeMerger?.newNodes! }],\n {\n onSolved: (cms) => {\n cms.capacityNodes = cms.strawSolver?.getResultNodes()!\n },\n },\n ),\n definePipelineStep(\"edgeSolver\", CapacityMeshEdgeSolver, (cms) => [\n cms.capacityNodes!,\n ]),\n definePipelineStep(\"pathingSolver\", CapacityPathingSolver5, (cms) => [\n {\n simpleRouteJson: cms.srjWithPointPairs!,\n nodes: cms.capacityNodes!,\n edges: cms.edgeSolver?.edges || [],\n colorMap: cms.colorMap,\n hyperParameters: {\n MAX_CAPACITY_FACTOR: 1,\n },\n },\n ]),\n definePipelineStep(\n \"edgeToPortSegmentSolver\",\n CapacityEdgeToPortSegmentSolver,\n (cms) => [\n {\n nodes: cms.capacityNodes!,\n edges: cms.edgeSolver?.edges || [],\n capacityPaths: cms.pathingSolver?.getCapacityPaths() || [],\n colorMap: cms.colorMap,\n },\n ],\n ),\n definePipelineStep(\n \"segmentToPointSolver\",\n CapacitySegmentToPointSolver,\n (cms) => {\n const allSegments: NodePortSegment[] = []\n if (cms.edgeToPortSegmentSolver?.nodePortSegments) {\n cms.edgeToPortSegmentSolver.nodePortSegments.forEach((segs) => {\n allSegments.push(...segs)\n })\n }\n return [\n {\n segments: allSegments,\n colorMap: cms.colorMap,\n nodes: cms.capacityNodes!,\n },\n ]\n },\n ),\n // definePipelineStep(\n // \"segmentToPointOptimizer\",\n // CapacitySegmentPointOptimizer,\n // (cms) => [\n // {\n // assignedSegments: cms.segmentToPointSolver?.solvedSegments || [],\n // colorMap: cms.colorMap,\n // nodes: cms.nodeTargetMerger?.newNodes || [],\n // },\n // ],\n // ),\n definePipelineStep(\n \"unravelMultiSectionSolver\",\n UnravelMultiSectionSolver,\n (cms) => [\n {\n assignedSegments: cms.segmentToPointSolver?.solvedSegments || [],\n colorMap: cms.colorMap,\n nodes: cms.capacityNodes!,\n },\n ],\n ),\n definePipelineStep(\"highDensityRouteSolver\", HighDensitySolver, (cms) => [\n {\n nodePortPoints:\n cms.unravelMultiSectionSolver?.getNodesWithPortPoints() ??\n cms.segmentToPointOptimizer?.getNodesWithPortPoints() ??\n [],\n colorMap: cms.colorMap,\n connMap: cms.connMap,\n },\n ]),\n definePipelineStep(\n \"highDensityStitchSolver\",\n MultipleHighDensityRouteStitchSolver,\n (cms) => [\n {\n connections: cms.srjWithPointPairs!.connections,\n hdRoutes: cms.highDensityRouteSolver!.routes,\n layerCount: cms.srj.layerCount,\n },\n ],\n ),\n ]\n\n constructor(\n public srj: SimpleRouteJson,\n public opts: CapacityMeshSolverOptions = {},\n ) {\n super()\n this.MAX_ITERATIONS = 1e6\n\n // If capacityDepth is not provided, calculate it automatically\n if (opts.capacityDepth === undefined) {\n // Calculate max width/height from bounds for initial node size\n const boundsWidth = srj.bounds.maxX - srj.bounds.minX\n const boundsHeight = srj.bounds.maxY - srj.bounds.minY\n const maxWidthHeight = Math.max(boundsWidth, boundsHeight)\n\n // Use the calculateOptimalCapacityDepth function to determine the right depth\n const targetMinCapacity = opts.targetMinCapacity ?? 0.5\n opts.capacityDepth = calculateOptimalCapacityDepth(\n maxWidthHeight,\n targetMinCapacity,\n )\n }\n\n this.connMap = getConnectivityMapFromSimpleRouteJson(srj)\n this.colorMap = getColorMap(srj, this.connMap)\n this.startTimeOfPhase = {}\n this.endTimeOfPhase = {}\n this.timeSpentOnPhase = {}\n }\n\n currentPipelineStepIndex = 0\n _step() {\n const pipelineStepDef = this.pipelineDef[this.currentPipelineStepIndex]\n if (!pipelineStepDef) {\n this.solved = true\n return\n }\n\n if (this.activeSubSolver) {\n this.activeSubSolver.step()\n if (this.activeSubSolver.solved) {\n this.endTimeOfPhase[pipelineStepDef.solverName] = performance.now()\n this.timeSpentOnPhase[pipelineStepDef.solverName] =\n this.endTimeOfPhase[pipelineStepDef.solverName] -\n this.startTimeOfPhase[pipelineStepDef.solverName]\n pipelineStepDef.onSolved?.(this)\n this.activeSubSolver = null\n this.currentPipelineStepIndex++\n } else if (this.activeSubSolver.failed) {\n this.error = this.activeSubSolver?.error\n this.failed = true\n this.activeSubSolver = null\n }\n return\n }\n\n const constructorParams = pipelineStepDef.getConstructorParams(this)\n // @ts-ignore\n this.activeSubSolver = new pipelineStepDef.solverClass(...constructorParams)\n ;(this as any)[pipelineStepDef.solverName] = this.activeSubSolver\n this.timeSpentOnPhase[pipelineStepDef.solverName] = 0\n this.startTimeOfPhase[pipelineStepDef.solverName] = performance.now()\n }\n\n getCurrentPhase(): string {\n return this.pipelineDef[this.currentPipelineStepIndex]?.solverName ?? \"none\"\n }\n\n visualize(): GraphicsObject {\n if (!this.solved && this.activeSubSolver)\n return this.activeSubSolver.visualize()\n const netToPPSolver = this.netToPointPairsSolver?.visualize()\n const nodeViz = this.nodeSolver?.visualize()\n const nodeTargetMergerViz = this.nodeTargetMerger?.visualize()\n const singleLayerNodeMergerViz = this.singleLayerNodeMerger?.visualize()\n const strawSolverViz = this.strawSolver?.visualize()\n const edgeViz = this.edgeSolver?.visualize()\n const pathingViz = this.pathingSolver?.visualize()\n const edgeToPortSegmentViz = this.edgeToPortSegmentSolver?.visualize()\n const segmentToPointViz = this.segmentToPointSolver?.visualize()\n const segmentOptimizationViz =\n this.unravelMultiSectionSolver?.visualize() ??\n this.segmentToPointOptimizer?.visualize()\n const highDensityViz = this.highDensityRouteSolver?.visualize()\n const highDensityStitchViz = this.highDensityStitchSolver?.visualize()\n const problemViz = {\n points: [...this.srj.connections.flatMap((c) => c.pointsToConnect)],\n rects: [\n ...(this.srj.obstacles ?? []).map((o) => ({\n ...o,\n fill: o.layers?.includes(\"top\")\n ? \"rgba(255,0,0,0.25)\"\n : o.layers?.includes(\"bottom\")\n ? \"rgba(0,0,255,0.25)\"\n : \"rgba(255,0,0,0.25)\",\n })),\n ],\n lines: [\n {\n points: [\n // Add five points representing the bounds of the PCB\n {\n x: this.srj.bounds?.minX ?? -50,\n y: this.srj.bounds?.minY ?? -50,\n },\n { x: this.srj.bounds?.maxX ?? 50, y: this.srj.bounds?.minY ?? -50 },\n { x: this.srj.bounds?.maxX ?? 50, y: this.srj.bounds?.maxY ?? 50 },\n { x: this.srj.bounds?.minX ?? -50, y: this.srj.bounds?.maxY ?? 50 },\n {\n x: this.srj.bounds?.minX ?? -50,\n y: this.srj.bounds?.minY ?? -50,\n }, // Close the rectangle\n ],\n strokeColor: \"rgba(255,0,0,0.25)\",\n },\n ],\n } as GraphicsObject\n const visualizations = [\n problemViz,\n netToPPSolver,\n nodeViz,\n nodeTargetMergerViz,\n singleLayerNodeMergerViz,\n strawSolverViz,\n edgeViz,\n pathingViz,\n edgeToPortSegmentViz,\n segmentToPointViz,\n segmentOptimizationViz,\n highDensityViz ? combineVisualizations(problemViz, highDensityViz) : null,\n highDensityStitchViz,\n this.solved\n ? combineVisualizations(\n problemViz,\n convertSrjToGraphicsObject(this.getOutputSimpleRouteJson()),\n )\n : null,\n ].filter(Boolean) as GraphicsObject[]\n // return visualizations[visualizations.length - 1]\n return combineVisualizations(...visualizations)\n }\n\n /**\n * Get original connection name from connection name with MST suffix\n * @param mstConnectionName The MST-suffixed connection name (e.g. \"connection1_mst0\")\n * @returns The original connection name (e.g. \"connection1\")\n */\n private getOriginalConnectionName(mstConnectionName: string): string {\n // MST connections are named like \"connection_mst0\", so extract the original name\n const match = mstConnectionName.match(/^(.+?)_mst\\d+$/)\n return match ? match[1] : mstConnectionName\n }\n\n /**\n * Returns the SimpleRouteJson with routes converted to SimplifiedPcbTraces\n */\n getOutputSimplifiedPcbTraces(): SimplifiedPcbTraces {\n if (!this.solved || !this.highDensityRouteSolver) {\n throw new Error(\"Cannot get output before solving is complete\")\n }\n\n const traces: SimplifiedPcbTraces = []\n\n for (const connection of this.netToPointPairsSolver?.newConnections ?? []) {\n const netConnection = this.srj.connections.find(\n (c) => c.name === connection.netConnectionName,\n )\n\n // Find all the hdRoutes that correspond to this connection\n const hdRoutes = this.highDensityStitchSolver!.mergedHdRoutes.filter(\n (r) => r.connectionName === connection.name,\n )\n\n for (let i = 0; i < hdRoutes.length; i++) {\n const hdRoute = hdRoutes[i]\n const simplifiedPcbTrace: SimplifiedPcbTrace = {\n type: \"pcb_trace\",\n pcb_trace_id: `${connection.name}_${i}`,\n connection_name: this.getOriginalConnectionName(connection.name),\n route: convertHdRouteToSimplifiedRoute(hdRoute, this.srj.layerCount),\n }\n\n traces.push(simplifiedPcbTrace)\n }\n }\n\n return traces\n }\n\n getOutputSimpleRouteJson(): SimpleRouteJson {\n return {\n ...this.srj,\n traces: this.getOutputSimplifiedPcbTraces(),\n }\n }\n}\n"],"mappings":"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","names":["t","e","t","t","_isNativeReflectConstruct","_wrapNativeSuper","t","PolishedError","pxtoFactory","reduceHexValue","isRgb","isRgba","isHsl","isHsla","clamp","node","distance","layerName","nodeId","distance"]}
|