@cristianormazabal/triton-core 0.1.0 → 0.1.2
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/contracts/anchors.js +20 -0
- package/dist/contracts/anchors.js.map +1 -0
- package/dist/contracts/animations.d.ts +5 -0
- package/dist/contracts/animations.d.ts.map +1 -0
- package/dist/contracts/animations.js +15 -0
- package/dist/contracts/animations.js.map +1 -0
- package/dist/contracts/crosslink.d.ts +21 -41
- package/dist/contracts/crosslink.d.ts.map +1 -1
- package/dist/contracts/crosslink.js +17 -0
- package/dist/contracts/crosslink.js.map +1 -0
- package/dist/contracts/diagram.js +24 -0
- package/dist/contracts/diagram.js.map +1 -0
- package/dist/contracts/index.d.ts +6 -3
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +21 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/overlay.js +22 -0
- package/dist/contracts/overlay.js.map +1 -0
- package/dist/contracts/primitives.js +13 -0
- package/dist/contracts/primitives.js.map +1 -0
- package/dist/contracts/renderer.js +15 -0
- package/dist/contracts/renderer.js.map +1 -0
- package/dist/contracts/result.js +26 -0
- package/dist/contracts/result.js.map +1 -0
- package/dist/contracts/routing.d.ts +4 -0
- package/dist/contracts/routing.d.ts.map +1 -1
- package/dist/contracts/routing.js +14 -0
- package/dist/contracts/routing.js.map +1 -0
- package/dist/contracts/scene.d.ts +5 -1
- package/dist/contracts/scene.d.ts.map +1 -1
- package/dist/contracts/scene.js +18 -0
- package/dist/contracts/scene.js.map +1 -0
- package/dist/contracts/theme.js +18 -0
- package/dist/contracts/theme.js.map +1 -0
- package/dist/crosslink/connectors.d.ts +66 -0
- package/dist/crosslink/connectors.d.ts.map +1 -0
- package/dist/crosslink/connectors.js +130 -0
- package/dist/crosslink/connectors.js.map +1 -0
- package/dist/crosslink/engine2.d.ts +2 -2
- package/dist/crosslink/engine2.d.ts.map +1 -1
- package/dist/crosslink/engine2.js +783 -0
- package/dist/crosslink/engine2.js.map +1 -0
- package/dist/crosslink/engine3.d.ts +2 -2
- package/dist/crosslink/engine3.d.ts.map +1 -1
- package/dist/crosslink/engine3.js +968 -0
- package/dist/crosslink/engine3.js.map +1 -0
- package/dist/crosslink/index.d.ts +2 -0
- package/dist/crosslink/index.d.ts.map +1 -1
- package/dist/crosslink/index.js +4 -0
- package/dist/crosslink/index.js.map +1 -0
- package/dist/crosslink/render.d.ts +2 -2
- package/dist/crosslink/render.d.ts.map +1 -1
- package/dist/crosslink/render.js +997 -0
- package/dist/crosslink/render.js.map +1 -0
- package/dist/crosslink/resolve.js +331 -0
- package/dist/crosslink/resolve.js.map +1 -0
- package/dist/diagrams/{c4 → mermaid/c4}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/c4/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/c4/index.js +14 -0
- package/dist/diagrams/mermaid/c4/index.js.map +1 -0
- package/dist/diagrams/{c4 → mermaid/c4}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/c4/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/c4/ir.js +2 -0
- package/dist/diagrams/mermaid/c4/ir.js.map +1 -0
- package/dist/diagrams/{c4 → mermaid/c4}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/c4/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/c4/layout.js +110 -0
- package/dist/diagrams/mermaid/c4/layout.js.map +1 -0
- package/dist/diagrams/{class → mermaid/class}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/class/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/class/index.js +14 -0
- package/dist/diagrams/mermaid/class/index.js.map +1 -0
- package/dist/diagrams/{class → mermaid/class}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/class/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/class/ir.js +2 -0
- package/dist/diagrams/mermaid/class/ir.js.map +1 -0
- package/dist/diagrams/{class → mermaid/class}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/class/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/class/layout.js +877 -0
- package/dist/diagrams/mermaid/class/layout.js.map +1 -0
- package/dist/diagrams/{er → mermaid/er}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/er/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/er/index.js +14 -0
- package/dist/diagrams/mermaid/er/index.js.map +1 -0
- package/dist/diagrams/{er → mermaid/er}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/er/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/er/ir.js +2 -0
- package/dist/diagrams/mermaid/er/ir.js.map +1 -0
- package/dist/diagrams/{er → mermaid/er}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/er/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/er/layout.js +116 -0
- package/dist/diagrams/mermaid/er/layout.js.map +1 -0
- package/dist/diagrams/{flowchart → mermaid/flowchart}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/flowchart/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/flowchart/index.js +24 -0
- package/dist/diagrams/mermaid/flowchart/index.js.map +1 -0
- package/dist/diagrams/{flowchart → mermaid/flowchart}/ir.d.ts +7 -1
- package/dist/diagrams/mermaid/flowchart/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/flowchart/ir.js +2 -0
- package/dist/diagrams/mermaid/flowchart/ir.js.map +1 -0
- package/dist/diagrams/mermaid/flowchart/layout.d.ts +5 -0
- package/dist/diagrams/mermaid/flowchart/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/flowchart/layout.js +652 -0
- package/dist/diagrams/mermaid/flowchart/layout.js.map +1 -0
- package/dist/diagrams/{gantt → mermaid/gantt}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/gantt/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/gantt/index.js +89 -0
- package/dist/diagrams/mermaid/gantt/index.js.map +1 -0
- package/dist/diagrams/{gantt → mermaid/gantt}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/gantt/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/gantt/ir.js +2 -0
- package/dist/diagrams/mermaid/gantt/ir.js.map +1 -0
- package/dist/diagrams/{gantt → mermaid/gantt}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/gantt/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/gantt/layout.js +95 -0
- package/dist/diagrams/mermaid/gantt/layout.js.map +1 -0
- package/dist/diagrams/{gitgraph → mermaid/gitgraph}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/gitgraph/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/gitgraph/index.js +58 -0
- package/dist/diagrams/mermaid/gitgraph/index.js.map +1 -0
- package/dist/diagrams/{gitgraph → mermaid/gitgraph}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/gitgraph/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/gitgraph/ir.js +2 -0
- package/dist/diagrams/mermaid/gitgraph/ir.js.map +1 -0
- package/dist/diagrams/{gitgraph → mermaid/gitgraph}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/gitgraph/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/gitgraph/layout.js +89 -0
- package/dist/diagrams/mermaid/gitgraph/layout.js.map +1 -0
- package/dist/diagrams/{journey → mermaid/journey}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/journey/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/journey/index.js +14 -0
- package/dist/diagrams/mermaid/journey/index.js.map +1 -0
- package/dist/diagrams/{journey → mermaid/journey}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/journey/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/journey/ir.js +2 -0
- package/dist/diagrams/mermaid/journey/ir.js.map +1 -0
- package/dist/diagrams/{journey → mermaid/journey}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/journey/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/journey/layout.js +92 -0
- package/dist/diagrams/mermaid/journey/layout.js.map +1 -0
- package/dist/diagrams/{kanban → mermaid/kanban}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/kanban/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/kanban/index.js +14 -0
- package/dist/diagrams/mermaid/kanban/index.js.map +1 -0
- package/dist/diagrams/{kanban → mermaid/kanban}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/kanban/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/kanban/ir.js +2 -0
- package/dist/diagrams/mermaid/kanban/ir.js.map +1 -0
- package/dist/diagrams/{kanban → mermaid/kanban}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/kanban/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/kanban/layout.js +68 -0
- package/dist/diagrams/mermaid/kanban/layout.js.map +1 -0
- package/dist/diagrams/{mindmap → mermaid/mindmap}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/mindmap/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/mindmap/index.js +52 -0
- package/dist/diagrams/mermaid/mindmap/index.js.map +1 -0
- package/dist/diagrams/{mindmap → mermaid/mindmap}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/mindmap/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/mindmap/ir.js +2 -0
- package/dist/diagrams/mermaid/mindmap/ir.js.map +1 -0
- package/dist/diagrams/{mindmap → mermaid/mindmap}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/mindmap/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/mindmap/layout.js +100 -0
- package/dist/diagrams/mermaid/mindmap/layout.js.map +1 -0
- package/dist/diagrams/{pie → mermaid/pie}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/pie/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/pie/index.js +14 -0
- package/dist/diagrams/mermaid/pie/index.js.map +1 -0
- package/dist/diagrams/{pie → mermaid/pie}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/pie/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/pie/ir.js +2 -0
- package/dist/diagrams/mermaid/pie/ir.js.map +1 -0
- package/dist/diagrams/{pie → mermaid/pie}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/pie/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/pie/layout.js +84 -0
- package/dist/diagrams/mermaid/pie/layout.js.map +1 -0
- package/dist/diagrams/{quadrant → mermaid/quadrant}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/quadrant/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/quadrant/index.js +14 -0
- package/dist/diagrams/mermaid/quadrant/index.js.map +1 -0
- package/dist/diagrams/{quadrant → mermaid/quadrant}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/quadrant/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/quadrant/ir.js +2 -0
- package/dist/diagrams/mermaid/quadrant/ir.js.map +1 -0
- package/dist/diagrams/{quadrant → mermaid/quadrant}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/quadrant/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/quadrant/layout.js +83 -0
- package/dist/diagrams/mermaid/quadrant/layout.js.map +1 -0
- package/dist/diagrams/{radar → mermaid/radar}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/radar/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/radar/index.js +14 -0
- package/dist/diagrams/mermaid/radar/index.js.map +1 -0
- package/dist/diagrams/{radar → mermaid/radar}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/radar/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/radar/ir.js +2 -0
- package/dist/diagrams/mermaid/radar/ir.js.map +1 -0
- package/dist/diagrams/{radar → mermaid/radar}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/radar/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/radar/layout.js +91 -0
- package/dist/diagrams/mermaid/radar/layout.js.map +1 -0
- package/dist/diagrams/{requirement → mermaid/requirement}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/requirement/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/requirement/index.js +14 -0
- package/dist/diagrams/mermaid/requirement/index.js.map +1 -0
- package/dist/diagrams/{requirement → mermaid/requirement}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/requirement/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/requirement/ir.js +2 -0
- package/dist/diagrams/mermaid/requirement/ir.js.map +1 -0
- package/dist/diagrams/{requirement → mermaid/requirement}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/requirement/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/requirement/layout.js +79 -0
- package/dist/diagrams/mermaid/requirement/layout.js.map +1 -0
- package/dist/diagrams/{sankey → mermaid/sankey}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/sankey/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/sankey/index.js +14 -0
- package/dist/diagrams/mermaid/sankey/index.js.map +1 -0
- package/dist/diagrams/{sankey → mermaid/sankey}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/sankey/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/sankey/ir.js +2 -0
- package/dist/diagrams/mermaid/sankey/ir.js.map +1 -0
- package/dist/diagrams/{sankey → mermaid/sankey}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/sankey/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/sankey/layout.js +124 -0
- package/dist/diagrams/mermaid/sankey/layout.js.map +1 -0
- package/dist/diagrams/{sequence → mermaid/sequence}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/sequence/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/sequence/index.js +14 -0
- package/dist/diagrams/mermaid/sequence/index.js.map +1 -0
- package/dist/diagrams/{sequence → mermaid/sequence}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/sequence/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/sequence/ir.js +2 -0
- package/dist/diagrams/mermaid/sequence/ir.js.map +1 -0
- package/dist/diagrams/{sequence → mermaid/sequence}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/sequence/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/sequence/layout.js +168 -0
- package/dist/diagrams/mermaid/sequence/layout.js.map +1 -0
- package/dist/diagrams/{state → mermaid/state}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/state/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/state/index.js +14 -0
- package/dist/diagrams/mermaid/state/index.js.map +1 -0
- package/dist/diagrams/{state → mermaid/state}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/state/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/state/ir.js +2 -0
- package/dist/diagrams/mermaid/state/ir.js.map +1 -0
- package/dist/diagrams/{state → mermaid/state}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/state/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/state/layout.js +172 -0
- package/dist/diagrams/mermaid/state/layout.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/timeline/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/index.js +23 -0
- package/dist/diagrams/mermaid/timeline/index.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/timeline/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/ir.js +2 -0
- package/dist/diagrams/mermaid/timeline/ir.js.map +1 -0
- package/dist/diagrams/mermaid/timeline/layout.d.ts +5 -0
- package/dist/diagrams/mermaid/timeline/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/layout.js +228 -0
- package/dist/diagrams/mermaid/timeline/layout.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/numbered.d.ts +2 -2
- package/dist/diagrams/mermaid/timeline/numbered.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/numbered.js +112 -0
- package/dist/diagrams/mermaid/timeline/numbered.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/roadmap.d.ts +2 -2
- package/dist/diagrams/mermaid/timeline/roadmap.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/roadmap.js +125 -0
- package/dist/diagrams/mermaid/timeline/roadmap.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/serpentine.d.ts +2 -2
- package/dist/diagrams/mermaid/timeline/serpentine.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/serpentine.js +152 -0
- package/dist/diagrams/mermaid/timeline/serpentine.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/shared.d.ts +1 -1
- package/dist/diagrams/mermaid/timeline/shared.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/shared.js +47 -0
- package/dist/diagrams/mermaid/timeline/shared.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/timeline-columns.d.ts +2 -2
- package/dist/diagrams/mermaid/timeline/timeline-columns.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/timeline-columns.js +136 -0
- package/dist/diagrams/mermaid/timeline/timeline-columns.js.map +1 -0
- package/dist/diagrams/{timeline → mermaid/timeline}/vertical-spine.d.ts +2 -2
- package/dist/diagrams/mermaid/timeline/vertical-spine.d.ts.map +1 -0
- package/dist/diagrams/mermaid/timeline/vertical-spine.js +136 -0
- package/dist/diagrams/mermaid/timeline/vertical-spine.js.map +1 -0
- package/dist/diagrams/{xychart → mermaid/xychart}/index.d.ts +1 -1
- package/dist/diagrams/mermaid/xychart/index.d.ts.map +1 -0
- package/dist/diagrams/mermaid/xychart/index.js +14 -0
- package/dist/diagrams/mermaid/xychart/index.js.map +1 -0
- package/dist/diagrams/{xychart → mermaid/xychart}/ir.d.ts +1 -1
- package/dist/diagrams/mermaid/xychart/ir.d.ts.map +1 -0
- package/dist/diagrams/mermaid/xychart/ir.js +2 -0
- package/dist/diagrams/mermaid/xychart/ir.js.map +1 -0
- package/dist/diagrams/{xychart → mermaid/xychart}/layout.d.ts +2 -2
- package/dist/diagrams/mermaid/xychart/layout.d.ts.map +1 -0
- package/dist/diagrams/mermaid/xychart/layout.js +120 -0
- package/dist/diagrams/mermaid/xychart/layout.js.map +1 -0
- package/dist/diagrams/{architecture → triton/architecture}/index.d.ts +1 -1
- package/dist/diagrams/triton/architecture/index.d.ts.map +1 -0
- package/dist/diagrams/triton/architecture/index.js +14 -0
- package/dist/diagrams/triton/architecture/index.js.map +1 -0
- package/dist/diagrams/{architecture → triton/architecture}/ir.d.ts +1 -1
- package/dist/diagrams/triton/architecture/ir.d.ts.map +1 -0
- package/dist/diagrams/triton/architecture/ir.js +2 -0
- package/dist/diagrams/triton/architecture/ir.js.map +1 -0
- package/dist/diagrams/{architecture → triton/architecture}/layout.d.ts +2 -2
- package/dist/diagrams/triton/architecture/layout.d.ts.map +1 -0
- package/dist/diagrams/triton/architecture/layout.js +124 -0
- package/dist/diagrams/triton/architecture/layout.js.map +1 -0
- package/dist/diagrams/{block → triton/block}/index.d.ts +1 -1
- package/dist/diagrams/triton/block/index.d.ts.map +1 -0
- package/dist/diagrams/triton/block/index.js +14 -0
- package/dist/diagrams/triton/block/index.js.map +1 -0
- package/dist/diagrams/{block → triton/block}/ir.d.ts +1 -1
- package/dist/diagrams/triton/block/ir.d.ts.map +1 -0
- package/dist/diagrams/triton/block/ir.js +2 -0
- package/dist/diagrams/triton/block/ir.js.map +1 -0
- package/dist/diagrams/{block → triton/block}/layout.d.ts +2 -2
- package/dist/diagrams/triton/block/layout.d.ts.map +1 -0
- package/dist/diagrams/triton/block/layout.js +73 -0
- package/dist/diagrams/triton/block/layout.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/graph/graph.d.ts +1 -1
- package/dist/diagrams/triton/ds/graph/graph.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/graph/graph.js +140 -0
- package/dist/diagrams/triton/ds/graph/graph.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/hashmap/hashmap.d.ts +1 -1
- package/dist/diagrams/triton/ds/hashmap/hashmap.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/hashmap/hashmap.js +131 -0
- package/dist/diagrams/triton/ds/hashmap/hashmap.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/matrix/matrix.d.ts +1 -1
- package/dist/diagrams/triton/ds/matrix/matrix.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/matrix/matrix.js +113 -0
- package/dist/diagrams/triton/ds/matrix/matrix.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/queue/cqueue.d.ts +5 -3
- package/dist/diagrams/triton/ds/queue/cqueue.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/queue/cqueue.js +195 -0
- package/dist/diagrams/triton/ds/queue/cqueue.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/queue/deque.d.ts +3 -1
- package/dist/diagrams/triton/ds/queue/deque.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/queue/deque.js +118 -0
- package/dist/diagrams/triton/ds/queue/deque.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/queue/pqueue.d.ts +5 -3
- package/dist/diagrams/triton/ds/queue/pqueue.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/queue/pqueue.js +129 -0
- package/dist/diagrams/triton/ds/queue/pqueue.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/queue/queue.d.ts +3 -1
- package/dist/diagrams/triton/ds/queue/queue.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/queue/queue.js +128 -0
- package/dist/diagrams/triton/ds/queue/queue.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/queue/shared.d.ts +18 -2
- package/dist/diagrams/triton/ds/queue/shared.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/queue/shared.js +186 -0
- package/dist/diagrams/triton/ds/queue/shared.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/stack/stack.d.ts +3 -1
- package/dist/diagrams/triton/ds/stack/stack.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/stack/stack.js +119 -0
- package/dist/diagrams/triton/ds/stack/stack.js.map +1 -0
- package/dist/diagrams/triton/ds/struct/array.d.ts +52 -0
- package/dist/diagrams/triton/ds/struct/array.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/struct/array.js +491 -0
- package/dist/diagrams/triton/ds/struct/array.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/struct/linkedlist.d.ts +1 -1
- package/dist/diagrams/triton/ds/struct/linkedlist.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/struct/linkedlist.js +99 -0
- package/dist/diagrams/triton/ds/struct/linkedlist.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/struct/memory.d.ts +1 -1
- package/dist/diagrams/triton/ds/struct/memory.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/struct/memory.js +172 -0
- package/dist/diagrams/triton/ds/struct/memory.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/struct/page.d.ts +1 -1
- package/dist/diagrams/triton/ds/struct/page.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/struct/page.js +137 -0
- package/dist/diagrams/triton/ds/struct/page.js.map +1 -0
- package/dist/diagrams/triton/ds/struct/shared.d.ts +17 -0
- package/dist/diagrams/triton/ds/struct/shared.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/struct/shared.js +60 -0
- package/dist/diagrams/triton/ds/struct/shared.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/avl.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/avl.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/avl.js +87 -0
- package/dist/diagrams/triton/ds/tree/avl.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/btree.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/btree.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/btree.js +76 -0
- package/dist/diagrams/triton/ds/tree/btree.js.map +1 -0
- package/dist/diagrams/triton/ds/tree/build.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/build.js +51 -0
- package/dist/diagrams/triton/ds/tree/build.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/heap.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/heap.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/heap.js +48 -0
- package/dist/diagrams/triton/ds/tree/heap.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/index.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/index.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/index.js +20 -0
- package/dist/diagrams/triton/ds/tree/index.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/ir.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/ir.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/ir.js +10 -0
- package/dist/diagrams/triton/ds/tree/ir.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/layout.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/layout.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/layout.js +281 -0
- package/dist/diagrams/triton/ds/tree/layout.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/plan.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/plan.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/plan.js +48 -0
- package/dist/diagrams/triton/ds/tree/plan.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/radix.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/radix.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/radix.js +88 -0
- package/dist/diagrams/triton/ds/tree/radix.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/rbtree.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/rbtree.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/rbtree.js +78 -0
- package/dist/diagrams/triton/ds/tree/rbtree.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/tree/segtree.d.ts +1 -1
- package/dist/diagrams/triton/ds/tree/segtree.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/tree/segtree.js +51 -0
- package/dist/diagrams/triton/ds/tree/segtree.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/trie/trie.d.ts +1 -1
- package/dist/diagrams/triton/ds/trie/trie.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/trie/trie.js +58 -0
- package/dist/diagrams/triton/ds/trie/trie.js.map +1 -0
- package/dist/diagrams/{ds → triton/ds}/unionfind/unionfind.d.ts +1 -1
- package/dist/diagrams/triton/ds/unionfind/unionfind.d.ts.map +1 -0
- package/dist/diagrams/triton/ds/unionfind/unionfind.js +110 -0
- package/dist/diagrams/triton/ds/unionfind/unionfind.js.map +1 -0
- package/dist/diagrams/{packet → triton/packet}/index.d.ts +1 -1
- package/dist/diagrams/triton/packet/index.d.ts.map +1 -0
- package/dist/diagrams/triton/packet/index.js +14 -0
- package/dist/diagrams/triton/packet/index.js.map +1 -0
- package/dist/diagrams/{packet → triton/packet}/ir.d.ts +1 -1
- package/dist/diagrams/triton/packet/ir.d.ts.map +1 -0
- package/dist/diagrams/triton/packet/ir.js +2 -0
- package/dist/diagrams/triton/packet/ir.js.map +1 -0
- package/dist/diagrams/{packet → triton/packet}/layout.d.ts +2 -2
- package/dist/diagrams/triton/packet/layout.d.ts.map +1 -0
- package/dist/diagrams/triton/packet/layout.js +69 -0
- package/dist/diagrams/triton/packet/layout.js.map +1 -0
- package/dist/diagrams/{poster → triton/poster}/index.d.ts +1 -1
- package/dist/diagrams/triton/poster/index.d.ts.map +1 -0
- package/dist/diagrams/triton/poster/index.js +127 -0
- package/dist/diagrams/triton/poster/index.js.map +1 -0
- package/dist/diagrams/{poster → triton/poster}/ir.d.ts +1 -3
- package/dist/diagrams/{poster → triton/poster}/ir.d.ts.map +1 -1
- package/dist/diagrams/triton/poster/ir.js +2 -0
- package/dist/diagrams/triton/poster/ir.js.map +1 -0
- package/dist/diagrams/{poster → triton/poster}/layout.d.ts +2 -2
- package/dist/diagrams/triton/poster/layout.d.ts.map +1 -0
- package/dist/diagrams/triton/poster/layout.js +517 -0
- package/dist/diagrams/triton/poster/layout.js.map +1 -0
- package/dist/diagrams/{topology → triton/topology}/topology.d.ts +2 -2
- package/dist/diagrams/triton/topology/topology.d.ts.map +1 -0
- package/dist/diagrams/triton/topology/topology.js +198 -0
- package/dist/diagrams/triton/topology/topology.js.map +1 -0
- package/dist/frontend/detect.js +94 -0
- package/dist/frontend/detect.js.map +1 -0
- package/dist/frontend/index.d.ts +4 -4
- package/dist/frontend/index.d.ts.map +1 -1
- package/dist/frontend/index.js +196 -0
- package/dist/frontend/index.js.map +1 -0
- package/dist/frontend/preprocess.d.ts +28 -0
- package/dist/frontend/preprocess.d.ts.map +1 -0
- package/dist/frontend/preprocess.js +60 -0
- package/dist/frontend/preprocess.js.map +1 -0
- package/dist/frontend/registry.js +25 -0
- package/dist/frontend/registry.js.map +1 -0
- package/dist/graph/connect.js +44 -0
- package/dist/graph/connect.js.map +1 -0
- package/dist/graph/layered.d.ts +65 -5
- package/dist/graph/layered.d.ts.map +1 -1
- package/dist/graph/layered.js +936 -0
- package/dist/graph/layered.js.map +1 -0
- package/dist/graph/tree.js +107 -0
- package/dist/graph/tree.js.map +1 -0
- package/dist/index.js +4691 -2735
- package/dist/index.js.map +4 -4
- package/dist/overlay/apply.js +22 -0
- package/dist/overlay/apply.js.map +1 -0
- package/dist/overlay/compiler.js +48 -0
- package/dist/overlay/compiler.js.map +1 -0
- package/dist/overlay/layout.js +242 -0
- package/dist/overlay/layout.js.map +1 -0
- package/dist/palette/categorical.js +21 -0
- package/dist/palette/categorical.js.map +1 -0
- package/dist/render/registry.js +22 -0
- package/dist/render/registry.js.map +1 -0
- package/dist/render/svg.d.ts.map +1 -1
- package/dist/render/svg.js +287 -0
- package/dist/render/svg.js.map +1 -0
- package/dist/routing/d3-curves.d.ts +31 -0
- package/dist/routing/d3-curves.d.ts.map +1 -0
- package/dist/routing/d3-curves.js +58 -0
- package/dist/routing/d3-curves.js.map +1 -0
- package/dist/routing/registry.js +22 -0
- package/dist/routing/registry.js.map +1 -0
- package/dist/routing/router.d.ts +3 -0
- package/dist/routing/router.d.ts.map +1 -1
- package/dist/routing/router.js +849 -0
- package/dist/routing/router.js.map +1 -0
- package/dist/scene/build.d.ts +3 -1
- package/dist/scene/build.d.ts.map +1 -1
- package/dist/scene/build.js +57 -0
- package/dist/scene/build.js.map +1 -0
- package/dist/scene/strip.js +46 -0
- package/dist/scene/strip.js.map +1 -0
- package/dist/style/cost.js +39 -0
- package/dist/style/cost.js.map +1 -0
- package/dist/text/metrics.js +62 -0
- package/dist/text/metrics.js.map +1 -0
- package/dist/text/wrap.js +84 -0
- package/dist/text/wrap.js.map +1 -0
- package/dist/theme/preset.d.ts +2 -0
- package/dist/theme/preset.d.ts.map +1 -1
- package/dist/theme/preset.js +295 -0
- package/dist/theme/preset.js.map +1 -0
- package/dist/theme/resolver.js +15 -0
- package/dist/theme/resolver.js.map +1 -0
- package/dist/time/dates.js +301 -0
- package/dist/time/dates.js.map +1 -0
- package/dist/util/round.js +17 -0
- package/dist/util/round.js.map +1 -0
- package/package.json +1 -1
- package/dist/diagrams/architecture/index.d.ts.map +0 -1
- package/dist/diagrams/architecture/ir.d.ts.map +0 -1
- package/dist/diagrams/architecture/layout.d.ts.map +0 -1
- package/dist/diagrams/block/index.d.ts.map +0 -1
- package/dist/diagrams/block/ir.d.ts.map +0 -1
- package/dist/diagrams/block/layout.d.ts.map +0 -1
- package/dist/diagrams/c4/index.d.ts.map +0 -1
- package/dist/diagrams/c4/ir.d.ts.map +0 -1
- package/dist/diagrams/c4/layout.d.ts.map +0 -1
- package/dist/diagrams/class/index.d.ts.map +0 -1
- package/dist/diagrams/class/ir.d.ts.map +0 -1
- package/dist/diagrams/class/layout.d.ts.map +0 -1
- package/dist/diagrams/ds/graph/graph.d.ts.map +0 -1
- package/dist/diagrams/ds/hashmap/hashmap.d.ts.map +0 -1
- package/dist/diagrams/ds/matrix/matrix.d.ts.map +0 -1
- package/dist/diagrams/ds/queue/cqueue.d.ts.map +0 -1
- package/dist/diagrams/ds/queue/deque.d.ts.map +0 -1
- package/dist/diagrams/ds/queue/pqueue.d.ts.map +0 -1
- package/dist/diagrams/ds/queue/queue.d.ts.map +0 -1
- package/dist/diagrams/ds/queue/shared.d.ts.map +0 -1
- package/dist/diagrams/ds/stack/stack.d.ts.map +0 -1
- package/dist/diagrams/ds/struct/array.d.ts +0 -28
- package/dist/diagrams/ds/struct/array.d.ts.map +0 -1
- package/dist/diagrams/ds/struct/linkedlist.d.ts.map +0 -1
- package/dist/diagrams/ds/struct/memory.d.ts.map +0 -1
- package/dist/diagrams/ds/struct/page.d.ts.map +0 -1
- package/dist/diagrams/ds/struct/shared.d.ts +0 -9
- package/dist/diagrams/ds/struct/shared.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/avl.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/btree.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/build.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/heap.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/index.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/ir.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/layout.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/plan.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/radix.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/rbtree.d.ts.map +0 -1
- package/dist/diagrams/ds/tree/segtree.d.ts.map +0 -1
- package/dist/diagrams/ds/trie/trie.d.ts.map +0 -1
- package/dist/diagrams/ds/unionfind/unionfind.d.ts.map +0 -1
- package/dist/diagrams/er/index.d.ts.map +0 -1
- package/dist/diagrams/er/ir.d.ts.map +0 -1
- package/dist/diagrams/er/layout.d.ts.map +0 -1
- package/dist/diagrams/flowchart/index.d.ts.map +0 -1
- package/dist/diagrams/flowchart/ir.d.ts.map +0 -1
- package/dist/diagrams/flowchart/layout.d.ts +0 -5
- package/dist/diagrams/flowchart/layout.d.ts.map +0 -1
- package/dist/diagrams/gantt/index.d.ts.map +0 -1
- package/dist/diagrams/gantt/ir.d.ts.map +0 -1
- package/dist/diagrams/gantt/layout.d.ts.map +0 -1
- package/dist/diagrams/gitgraph/index.d.ts.map +0 -1
- package/dist/diagrams/gitgraph/ir.d.ts.map +0 -1
- package/dist/diagrams/gitgraph/layout.d.ts.map +0 -1
- package/dist/diagrams/journey/index.d.ts.map +0 -1
- package/dist/diagrams/journey/ir.d.ts.map +0 -1
- package/dist/diagrams/journey/layout.d.ts.map +0 -1
- package/dist/diagrams/kanban/index.d.ts.map +0 -1
- package/dist/diagrams/kanban/ir.d.ts.map +0 -1
- package/dist/diagrams/kanban/layout.d.ts.map +0 -1
- package/dist/diagrams/mindmap/index.d.ts.map +0 -1
- package/dist/diagrams/mindmap/ir.d.ts.map +0 -1
- package/dist/diagrams/mindmap/layout.d.ts.map +0 -1
- package/dist/diagrams/packet/index.d.ts.map +0 -1
- package/dist/diagrams/packet/ir.d.ts.map +0 -1
- package/dist/diagrams/packet/layout.d.ts.map +0 -1
- package/dist/diagrams/pie/index.d.ts.map +0 -1
- package/dist/diagrams/pie/ir.d.ts.map +0 -1
- package/dist/diagrams/pie/layout.d.ts.map +0 -1
- package/dist/diagrams/poster/index.d.ts.map +0 -1
- package/dist/diagrams/poster/layout.d.ts.map +0 -1
- package/dist/diagrams/quadrant/index.d.ts.map +0 -1
- package/dist/diagrams/quadrant/ir.d.ts.map +0 -1
- package/dist/diagrams/quadrant/layout.d.ts.map +0 -1
- package/dist/diagrams/radar/index.d.ts.map +0 -1
- package/dist/diagrams/radar/ir.d.ts.map +0 -1
- package/dist/diagrams/radar/layout.d.ts.map +0 -1
- package/dist/diagrams/requirement/index.d.ts.map +0 -1
- package/dist/diagrams/requirement/ir.d.ts.map +0 -1
- package/dist/diagrams/requirement/layout.d.ts.map +0 -1
- package/dist/diagrams/sankey/index.d.ts.map +0 -1
- package/dist/diagrams/sankey/ir.d.ts.map +0 -1
- package/dist/diagrams/sankey/layout.d.ts.map +0 -1
- package/dist/diagrams/sequence/index.d.ts.map +0 -1
- package/dist/diagrams/sequence/ir.d.ts.map +0 -1
- package/dist/diagrams/sequence/layout.d.ts.map +0 -1
- package/dist/diagrams/state/index.d.ts.map +0 -1
- package/dist/diagrams/state/ir.d.ts.map +0 -1
- package/dist/diagrams/state/layout.d.ts.map +0 -1
- package/dist/diagrams/timeline/index.d.ts.map +0 -1
- package/dist/diagrams/timeline/ir.d.ts.map +0 -1
- package/dist/diagrams/timeline/layout.d.ts +0 -5
- package/dist/diagrams/timeline/layout.d.ts.map +0 -1
- package/dist/diagrams/timeline/numbered.d.ts.map +0 -1
- package/dist/diagrams/timeline/roadmap.d.ts.map +0 -1
- package/dist/diagrams/timeline/serpentine.d.ts.map +0 -1
- package/dist/diagrams/timeline/shared.d.ts.map +0 -1
- package/dist/diagrams/timeline/timeline-columns.d.ts.map +0 -1
- package/dist/diagrams/timeline/vertical-spine.d.ts.map +0 -1
- package/dist/diagrams/topology/topology.d.ts.map +0 -1
- package/dist/diagrams/xychart/index.d.ts.map +0 -1
- package/dist/diagrams/xychart/ir.d.ts.map +0 -1
- package/dist/diagrams/xychart/layout.d.ts.map +0 -1
- /package/dist/diagrams/{ds → triton/ds}/tree/build.d.ts +0 -0
|
@@ -0,0 +1,783 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Link Engine v2 — Global Cost-Function Routing
|
|
3
|
+
*
|
|
4
|
+
* Replaces the two-step resolve.ts + render.ts pipeline with a single unified
|
|
5
|
+
* pass that uses a global cost function for port selection.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* 1. For each link, generate all 16 (srcWall × dstWall) port-pair candidates
|
|
9
|
+
* 2. Score each candidate against already-committed routes using a unified
|
|
10
|
+
* cost function: side preference, crossing count, port conflict, bend
|
|
11
|
+
* count, path length, and alignment penalty
|
|
12
|
+
* 3. Commit the best candidate greedily (longest links first, so the most
|
|
13
|
+
* spatially constrained routes claim cleaner corridors first)
|
|
14
|
+
* 4. Post-route: border nudge → channel separation → label stagger → label de-collision
|
|
15
|
+
*
|
|
16
|
+
* Cost function:
|
|
17
|
+
* cost = W_CROSS × crossings(candidate, committed_routes)
|
|
18
|
+
* + W_SIDE × wrong_side_penalty(srcWall, dstWall, Δx, Δy)
|
|
19
|
+
* + W_PORT × port_conflict_penalty(ports, committed_ports)
|
|
20
|
+
* + W_BENDS × bend_count
|
|
21
|
+
* + W_LEN × path_length
|
|
22
|
+
* + W_ALIGN × alignment_penalty (short jog segments < SNAP_THRESHOLD)
|
|
23
|
+
*/
|
|
24
|
+
import { isRenderedConnectorAnimation } from '../contracts/crosslink.js';
|
|
25
|
+
import { createRouter } from '../routing/router.js';
|
|
26
|
+
// ─── Cost weights ─────────────────────────────────────────────────────────────
|
|
27
|
+
/** Per crossing with an already-committed route. */
|
|
28
|
+
const W_CROSS = 10_000;
|
|
29
|
+
/** Per wrong-side step on source or destination wall. */
|
|
30
|
+
const W_SIDE = 800;
|
|
31
|
+
/** Per committed port within CONFLICT_RADIUS on the same node+wall. */
|
|
32
|
+
const W_PORT_CONFLICT = 600;
|
|
33
|
+
/** Per bend beyond the minimum (points.length − 2). */
|
|
34
|
+
const W_BENDS = 50;
|
|
35
|
+
/** Per pixel of total path length. */
|
|
36
|
+
const W_LEN = 1;
|
|
37
|
+
/** Flat penalty per short jog segment shorter than SNAP_THRESHOLD. */
|
|
38
|
+
const W_ALIGN = 400;
|
|
39
|
+
/** Jog segments shorter than this are penalised and snapped away. */
|
|
40
|
+
const SNAP_THRESHOLD = 14;
|
|
41
|
+
/** Ports within this distance on the same wall count as conflicting. */
|
|
42
|
+
const CONFLICT_RADIUS = 24;
|
|
43
|
+
/** Shrink intermediate cell rects by this amount for routing obstacles. */
|
|
44
|
+
const CELL_SHRINK = 12;
|
|
45
|
+
/** Gap between parallel overlapping segments after channel separation. */
|
|
46
|
+
const CHANNEL_GAP = 12;
|
|
47
|
+
/** Clearance around obstacles when routing. */
|
|
48
|
+
const ROUTE_PADDING = 12;
|
|
49
|
+
// ─── SVG marker IDs ───────────────────────────────────────────────────────────
|
|
50
|
+
const ARROW_ID = 'triton-crosslink-arrow';
|
|
51
|
+
const BI_ARROW_ID = 'triton-crosslink-arrow-both';
|
|
52
|
+
// ─── Entry point ──────────────────────────────────────────────────────────────
|
|
53
|
+
/**
|
|
54
|
+
* Unified routing + rendering pass for all cross-links in a poster.
|
|
55
|
+
*
|
|
56
|
+
* Drop-in replacement for `resolveCrossLinks` + `renderCrossLinks` but takes
|
|
57
|
+
* the raw CrossLink array instead of pre-resolved port positions.
|
|
58
|
+
*/
|
|
59
|
+
export function routeAndRenderCrossLinks2(links, theme, anchors, occupiedRects, routingObstacles, cellRects) {
|
|
60
|
+
const { palette, typography, edges: edgeTheme } = theme;
|
|
61
|
+
const elements = [];
|
|
62
|
+
const defs = [];
|
|
63
|
+
// ── Colour assignment (same logic as render.ts) ───────────────────────────
|
|
64
|
+
const PALETTE = [
|
|
65
|
+
'#E11D48', '#16A34A', '#9333EA', '#0891B2',
|
|
66
|
+
'#CA8A04', '#DC2626', '#2563EB', '#7C3AED',
|
|
67
|
+
];
|
|
68
|
+
let explicitColorIdx = 0;
|
|
69
|
+
// All node bounds used as routing obstacles
|
|
70
|
+
const allNodeBounds = Object.values(anchors).map(a => a.bounds);
|
|
71
|
+
// ── Address → registry key helper ────────────────────────────────────────
|
|
72
|
+
const addrKey = (addr) => [...addr.cellPath, addr.nodeId].join('.');
|
|
73
|
+
function centerOf(key) {
|
|
74
|
+
const a = anchors[key];
|
|
75
|
+
if (!a)
|
|
76
|
+
return { x: 0, y: 0 };
|
|
77
|
+
return { x: a.bounds.x + a.bounds.width / 2, y: a.bounds.y + a.bounds.height / 2 };
|
|
78
|
+
}
|
|
79
|
+
// ── Filter to resolvable links, sort axis-aligned-first ──────────────────
|
|
80
|
+
// Routes that are nearly horizontal or vertical have exactly one natural
|
|
81
|
+
// corridor — commit them first so they claim a clean straight path.
|
|
82
|
+
// Diagonal routes are more flexible and route around already-committed ones.
|
|
83
|
+
//
|
|
84
|
+
// Sort key: min(|dx|,|dy|) / (max(|dx|,|dy|)+1) → 0 = axis-aligned, 1 = diagonal.
|
|
85
|
+
const resolvable = links.filter(l => anchors[addrKey(l.from)] && anchors[addrKey(l.to)]);
|
|
86
|
+
const sortedLinks = [...resolvable].sort((a, b) => {
|
|
87
|
+
const ca = centerOf(addrKey(a.from)), cb = centerOf(addrKey(a.to));
|
|
88
|
+
const cc = centerOf(addrKey(b.from)), cd = centerOf(addrKey(b.to));
|
|
89
|
+
const axA = Math.abs(cb.x - ca.x), ayA = Math.abs(cb.y - ca.y);
|
|
90
|
+
const axB = Math.abs(cd.x - cc.x), ayB = Math.abs(cd.y - cc.y);
|
|
91
|
+
const sA = Math.min(axA, ayA) / (Math.max(axA, ayA) + 1);
|
|
92
|
+
const sB = Math.min(axB, ayB) / (Math.max(axB, ayB) + 1);
|
|
93
|
+
if (Math.abs(sA - sB) > 0.05)
|
|
94
|
+
return sA - sB; // more aligned first
|
|
95
|
+
// Tie-break: longer route first (more spatially constrained)
|
|
96
|
+
return Math.hypot(cb.x - ca.x, cb.y - ca.y) - Math.hypot(cd.x - cc.x, cd.y - cc.y);
|
|
97
|
+
}).reverse(); // within same alignment group, longest first
|
|
98
|
+
// ── Phase 1: Global port selection + routing ──────────────────────────────
|
|
99
|
+
const committed = [];
|
|
100
|
+
// workingByOriginalIdx preserves the original link order for colour assignment
|
|
101
|
+
const workingByOriginalIdx = new Map();
|
|
102
|
+
for (const link of sortedLinks) {
|
|
103
|
+
const srcKey = addrKey(link.from);
|
|
104
|
+
const dstKey = addrKey(link.to);
|
|
105
|
+
const srcAnchor = anchors[srcKey];
|
|
106
|
+
const dstAnchor = anchors[dstKey];
|
|
107
|
+
const srcCenter = centerOf(srcKey);
|
|
108
|
+
const dstCenter = centerOf(dstKey);
|
|
109
|
+
// Per-link routing obstacles: node bounds + shrunken intermediate cells
|
|
110
|
+
const linkObstacles = [...allNodeBounds];
|
|
111
|
+
if (cellRects) {
|
|
112
|
+
const srcCellId = link.from.cellPath.join('.');
|
|
113
|
+
const dstCellId = link.to.cellPath.join('.');
|
|
114
|
+
for (const [cellId, r] of cellRects) {
|
|
115
|
+
if (cellId === srcCellId || cellId === dstCellId)
|
|
116
|
+
continue;
|
|
117
|
+
const sw = r.width - 2 * CELL_SHRINK;
|
|
118
|
+
const sh = r.height - 2 * CELL_SHRINK;
|
|
119
|
+
if (sw > 0 && sh > 0) {
|
|
120
|
+
linkObstacles.push({ x: r.x + CELL_SHRINK, y: r.y + CELL_SHRINK, width: sw, height: sh });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const sides = ['N', 'S', 'E', 'W'];
|
|
125
|
+
const routeStyle = link.routing ?? 'orthogonal';
|
|
126
|
+
let bestPoints = [];
|
|
127
|
+
let bestEffectivePts = []; // sampled curve pts for crossing detection
|
|
128
|
+
let bestIsBezier = false;
|
|
129
|
+
let bestScore = Infinity;
|
|
130
|
+
let bestSrcSide = 'E';
|
|
131
|
+
let bestDstSide = 'W';
|
|
132
|
+
let bestSrcPort = midport(srcAnchor.bounds, 'E');
|
|
133
|
+
let bestDstPort = midport(dstAnchor.bounds, 'W');
|
|
134
|
+
for (const ss of sides) {
|
|
135
|
+
for (const ds of sides) {
|
|
136
|
+
// Try three port positions per wall: 25 %, 50 %, 75 % of edge length.
|
|
137
|
+
// The port-conflict penalty then naturally spreads connectors that
|
|
138
|
+
// share the same wall to different positions instead of stacking them.
|
|
139
|
+
for (const spBase of wallPorts(srcAnchor.bounds, ss)) {
|
|
140
|
+
for (const dpBase of wallPorts(dstAnchor.bounds, ds)) {
|
|
141
|
+
// Port alignment snap: if both ports exit on the same axis and
|
|
142
|
+
// the perpendicular offset is tiny, snap to exact alignment.
|
|
143
|
+
const snapped = snapAlignment(ss, spBase, ds, dpBase);
|
|
144
|
+
const sp = snapped.srcPort;
|
|
145
|
+
const dp = snapped.dstPort;
|
|
146
|
+
// Route using the link's preferred style
|
|
147
|
+
const router = createRouter(routeStyle);
|
|
148
|
+
const route = router.route({
|
|
149
|
+
from: sp,
|
|
150
|
+
to: dp,
|
|
151
|
+
style: routeStyle,
|
|
152
|
+
obstacles: linkObstacles,
|
|
153
|
+
padding: ROUTE_PADDING,
|
|
154
|
+
fromDir: ss,
|
|
155
|
+
toDir: ds,
|
|
156
|
+
});
|
|
157
|
+
const pts = route.points;
|
|
158
|
+
// Bezier router returns [from, cp1, cp2, to] — these are control
|
|
159
|
+
// points, NOT path points. Using them as a polyline gives wrong
|
|
160
|
+
// crossing counts and wrong arc length. Sample the actual cubic
|
|
161
|
+
// bezier curve for scoring.
|
|
162
|
+
const isBez = routeStyle === 'bezier' && pts.length === 4;
|
|
163
|
+
const effectivePts = isBez
|
|
164
|
+
? sampleCubicBezierPts(pts[0], pts[1], pts[2], pts[3], 12)
|
|
165
|
+
: pts;
|
|
166
|
+
// ── Unified cost function ────────────────────────────────────
|
|
167
|
+
const score = sidePenalty(ss, ds, srcCenter, dstCenter) +
|
|
168
|
+
crossingPenalty(effectivePts, committed) +
|
|
169
|
+
portConflictPenalty(srcKey, ss, sp, dstKey, ds, dp, committed) +
|
|
170
|
+
(isBez ? 0 : Math.max(0, pts.length - 2) * W_BENDS) +
|
|
171
|
+
pathLen(effectivePts) * W_LEN +
|
|
172
|
+
(isBez ? 0 : alignPenalty(pts));
|
|
173
|
+
if (score < bestScore) {
|
|
174
|
+
bestScore = score;
|
|
175
|
+
bestPoints = pts;
|
|
176
|
+
bestEffectivePts = effectivePts;
|
|
177
|
+
bestIsBezier = isBez;
|
|
178
|
+
bestSrcSide = ss;
|
|
179
|
+
bestDstSide = ds;
|
|
180
|
+
bestSrcPort = sp;
|
|
181
|
+
bestDstPort = dp;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
committed.push({
|
|
188
|
+
srcKey, dstKey,
|
|
189
|
+
srcSide: bestSrcSide, dstSide: bestDstSide,
|
|
190
|
+
srcPort: bestSrcPort, dstPort: bestDstPort,
|
|
191
|
+
points: bestEffectivePts, // sampled points for accurate future crossing detection
|
|
192
|
+
});
|
|
193
|
+
// Colour
|
|
194
|
+
let color;
|
|
195
|
+
{
|
|
196
|
+
color = PALETTE[explicitColorIdx % PALETTE.length];
|
|
197
|
+
explicitColorIdx++;
|
|
198
|
+
}
|
|
199
|
+
const dash = edgeStyleToDash(link.style);
|
|
200
|
+
const animation = link.animation === 'none' ? undefined :
|
|
201
|
+
isRenderedConnectorAnimation(link.animation) ? link.animation :
|
|
202
|
+
dash ? 'march' : undefined;
|
|
203
|
+
let markerEnd;
|
|
204
|
+
let markerStart;
|
|
205
|
+
if (link.direction === 'directed') {
|
|
206
|
+
markerEnd = ARROW_ID;
|
|
207
|
+
}
|
|
208
|
+
else if (link.direction === 'bidirectional') {
|
|
209
|
+
markerEnd = ARROW_ID;
|
|
210
|
+
markerStart = BI_ARROW_ID;
|
|
211
|
+
}
|
|
212
|
+
// Record with original link index so colours match original declaration order
|
|
213
|
+
const origIdx = links.indexOf(link);
|
|
214
|
+
workingByOriginalIdx.set(origIdx >= 0 ? origIdx : workingByOriginalIdx.size, {
|
|
215
|
+
points: [...bestPoints],
|
|
216
|
+
...(bestIsBezier ? { isBezier: true } : {}),
|
|
217
|
+
color,
|
|
218
|
+
...(dash ? { dash } : {}),
|
|
219
|
+
...(animation ? { animation } : {}),
|
|
220
|
+
...(markerEnd ? { markerEnd } : {}),
|
|
221
|
+
...(markerStart ? { markerStart } : {}),
|
|
222
|
+
...(link.label ? { label: link.label } : {}),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
// Reconstruct in original link order
|
|
226
|
+
const workingRoutes = [];
|
|
227
|
+
for (let i = 0; i < links.length; i++) {
|
|
228
|
+
const wr = workingByOriginalIdx.get(i);
|
|
229
|
+
if (wr)
|
|
230
|
+
workingRoutes.push(wr);
|
|
231
|
+
}
|
|
232
|
+
// ── Phase 2: Border nudging ───────────────────────────────────────────────
|
|
233
|
+
if (routingObstacles && routingObstacles.length > 0) {
|
|
234
|
+
nudgeOffBorders(workingRoutes, routingObstacles);
|
|
235
|
+
}
|
|
236
|
+
// ── Phase 3: Channel separation ───────────────────────────────────────────
|
|
237
|
+
separateChannels(workingRoutes);
|
|
238
|
+
// ── Phase 4: Label staggering ─────────────────────────────────────────────
|
|
239
|
+
const CORRIDOR_TOL = 20;
|
|
240
|
+
const labelFractions = new Array(workingRoutes.length).fill(0.5);
|
|
241
|
+
const labeledIdxs = workingRoutes.map((r, i) => r.label ? i : -1).filter(i => i >= 0);
|
|
242
|
+
const staggered = new Set();
|
|
243
|
+
for (const i of labeledIdxs) {
|
|
244
|
+
if (staggered.has(i))
|
|
245
|
+
continue;
|
|
246
|
+
const wrI = workingRoutes[i];
|
|
247
|
+
const ptsI = wrI.isBezier
|
|
248
|
+
? sampleCubicBezierPts(wrI.points[0], wrI.points[1], wrI.points[2], wrI.points[3], 12)
|
|
249
|
+
: wrI.points;
|
|
250
|
+
const infoI = dominantSegment(ptsI);
|
|
251
|
+
const group = [i];
|
|
252
|
+
for (const j of labeledIdxs) {
|
|
253
|
+
if (j === i || staggered.has(j))
|
|
254
|
+
continue;
|
|
255
|
+
const wrJ = workingRoutes[j];
|
|
256
|
+
const ptsJ = wrJ.isBezier
|
|
257
|
+
? sampleCubicBezierPts(wrJ.points[0], wrJ.points[1], wrJ.points[2], wrJ.points[3], 12)
|
|
258
|
+
: wrJ.points;
|
|
259
|
+
const infoJ = dominantSegment(ptsJ);
|
|
260
|
+
if (infoI.axis === infoJ.axis && Math.abs(infoI.coord - infoJ.coord) < CORRIDOR_TOL) {
|
|
261
|
+
group.push(j);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (group.length > 1) {
|
|
265
|
+
group.sort((a, b) => a - b);
|
|
266
|
+
group.forEach((idx, k) => { labelFractions[idx] = (k + 1) / (group.length + 1); });
|
|
267
|
+
group.forEach(idx => staggered.add(idx));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// ── Phase 5: Emit path elements ───────────────────────────────────────────
|
|
271
|
+
let needsArrow = false;
|
|
272
|
+
let needsBiArrow = false;
|
|
273
|
+
const pendingLabels = [];
|
|
274
|
+
for (let i = 0; i < workingRoutes.length; i++) {
|
|
275
|
+
const wr = workingRoutes[i];
|
|
276
|
+
const path = wr.isBezier
|
|
277
|
+
? `M ${wr.points[0].x} ${wr.points[0].y} C ${wr.points[1].x} ${wr.points[1].y} ${wr.points[2].x} ${wr.points[2].y} ${wr.points[3].x} ${wr.points[3].y}`
|
|
278
|
+
: wr.points.map((p, pi) => `${pi === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ');
|
|
279
|
+
if (wr.markerEnd === ARROW_ID)
|
|
280
|
+
needsArrow = true;
|
|
281
|
+
if (wr.markerStart === BI_ARROW_ID)
|
|
282
|
+
needsBiArrow = true;
|
|
283
|
+
elements.push({
|
|
284
|
+
type: 'path',
|
|
285
|
+
d: path,
|
|
286
|
+
stroke: wr.color,
|
|
287
|
+
strokeWidth: edgeTheme.strokeWidth + 0.5,
|
|
288
|
+
...(wr.dash ? { strokeDasharray: wr.dash } : {}),
|
|
289
|
+
...(wr.animation ? { animated: wr.animation } : {}),
|
|
290
|
+
...(wr.markerEnd ? { markerEnd: wr.markerEnd } : {}),
|
|
291
|
+
...(wr.markerStart ? { markerStart: wr.markerStart } : {}),
|
|
292
|
+
});
|
|
293
|
+
if (wr.label) {
|
|
294
|
+
const labelPts = wr.isBezier
|
|
295
|
+
? sampleCubicBezierPts(wr.points[0], wr.points[1], wr.points[2], wr.points[3], 12)
|
|
296
|
+
: wr.points;
|
|
297
|
+
const labelPos = pointAtFrac(labelPts, labelFractions[i] ?? 0.5);
|
|
298
|
+
pendingLabels.push({
|
|
299
|
+
content: wr.label,
|
|
300
|
+
x: labelPos.x,
|
|
301
|
+
y: labelPos.y - 6,
|
|
302
|
+
fontSize: edgeTheme.labelFontSize,
|
|
303
|
+
fontFamily: typography.fontFamily,
|
|
304
|
+
fill: wr.color,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// ── Phase 6: Label de-collision ───────────────────────────────────────────
|
|
309
|
+
const CHAR_W = 0.65;
|
|
310
|
+
const LABEL_PAD = 4;
|
|
311
|
+
const fixedRects = [...allNodeBounds, ...(occupiedRects ?? [])];
|
|
312
|
+
const labelRects = pendingLabels.map(l => ({
|
|
313
|
+
x: l.x - (l.content.length * l.fontSize * CHAR_W) / 2 - LABEL_PAD,
|
|
314
|
+
y: l.y - l.fontSize,
|
|
315
|
+
width: l.content.length * l.fontSize * CHAR_W + LABEL_PAD * 2,
|
|
316
|
+
height: l.fontSize + LABEL_PAD * 2,
|
|
317
|
+
}));
|
|
318
|
+
deCollideLabels(labelRects, fixedRects);
|
|
319
|
+
for (let i = 0; i < pendingLabels.length; i++) {
|
|
320
|
+
const l = pendingLabels[i];
|
|
321
|
+
const r = labelRects[i];
|
|
322
|
+
elements.push({
|
|
323
|
+
type: 'text',
|
|
324
|
+
content: l.content,
|
|
325
|
+
position: { x: r.x + r.width / 2, y: r.y + r.height - LABEL_PAD },
|
|
326
|
+
fontSize: l.fontSize,
|
|
327
|
+
fontFamily: l.fontFamily,
|
|
328
|
+
fill: l.fill,
|
|
329
|
+
anchor: 'middle',
|
|
330
|
+
fontWeight: 'bold',
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
// ── Defs ──────────────────────────────────────────────────────────────────
|
|
334
|
+
if (needsArrow) {
|
|
335
|
+
const s = edgeTheme.arrowSize;
|
|
336
|
+
defs.push(`<marker id="${ARROW_ID}" markerWidth="${s}" markerHeight="${s * 0.7}" refX="${s - 1}" refY="${s * 0.35}" orient="auto">` +
|
|
337
|
+
`<polygon points="0 0, ${s} ${s * 0.35}, 0 ${s * 0.7}" fill="currentColor" /></marker>`);
|
|
338
|
+
}
|
|
339
|
+
if (needsBiArrow) {
|
|
340
|
+
const s = edgeTheme.arrowSize;
|
|
341
|
+
defs.push(`<marker id="${BI_ARROW_ID}" markerWidth="${s}" markerHeight="${s * 0.7}" refX="1" refY="${s * 0.35}" orient="auto">` +
|
|
342
|
+
`<polygon points="${s} 0, 0 ${s * 0.35}, ${s} ${s * 0.7}" fill="currentColor" /></marker>`);
|
|
343
|
+
}
|
|
344
|
+
return { defs, elements };
|
|
345
|
+
}
|
|
346
|
+
// ─── Cost function ────────────────────────────────────────────────────────────
|
|
347
|
+
/** Opposite of a cardinal side. */
|
|
348
|
+
function opp(side) {
|
|
349
|
+
return side === 'N' ? 'S' : side === 'S' ? 'N' : side === 'E' ? 'W' : 'E';
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Side preference penalty.
|
|
353
|
+
*
|
|
354
|
+
* Ideal source wall: the one facing the direction of the target centre.
|
|
355
|
+
* Ideal dest wall: the opposite wall (facing back toward the source).
|
|
356
|
+
*
|
|
357
|
+
* Returns 0 for the ideal combination, W_SIDE × 1 for an adjacent wall, and
|
|
358
|
+
* W_SIDE × 2 for the directly opposite (worst) wall.
|
|
359
|
+
*/
|
|
360
|
+
function sidePenalty(srcSide, dstSide, srcCenter, dstCenter) {
|
|
361
|
+
const dx = dstCenter.x - srcCenter.x;
|
|
362
|
+
const dy = dstCenter.y - srcCenter.y;
|
|
363
|
+
const absX = Math.abs(dx), absY = Math.abs(dy);
|
|
364
|
+
// Ideal: exit from the wall that faces the target
|
|
365
|
+
const idealSrc = absX >= absY ? (dx >= 0 ? 'E' : 'W') : (dy >= 0 ? 'S' : 'N');
|
|
366
|
+
const idealDst = opp(idealSrc);
|
|
367
|
+
const steps = (actual, ideal) => actual === ideal ? 0 : actual === opp(ideal) ? 2 : 1;
|
|
368
|
+
return (steps(srcSide, idealSrc) + steps(dstSide, idealDst)) * W_SIDE;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Count proper crossings between the candidate route and each already-committed
|
|
372
|
+
* route, weighted by W_CROSS. A "proper crossing" is a strict intersection —
|
|
373
|
+
* touching at a shared endpoint does not count.
|
|
374
|
+
*/
|
|
375
|
+
function crossingPenalty(points, committed) {
|
|
376
|
+
let count = 0;
|
|
377
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
378
|
+
const a = points[i], b = points[i + 1];
|
|
379
|
+
for (const cr of committed) {
|
|
380
|
+
for (let j = 0; j < cr.points.length - 1; j++) {
|
|
381
|
+
if (properlyCross(a, b, cr.points[j], cr.points[j + 1]))
|
|
382
|
+
count++;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return count * W_CROSS;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Penalise candidates whose ports land very close to ports that are already
|
|
390
|
+
* committed on the same node+wall. This spreads ports out naturally — later
|
|
391
|
+
* routes prefer unused positions on the wall.
|
|
392
|
+
*/
|
|
393
|
+
function portConflictPenalty(srcKey, srcSide, srcPort, dstKey, dstSide, dstPort, committed) {
|
|
394
|
+
let penalty = 0;
|
|
395
|
+
for (const cr of committed) {
|
|
396
|
+
// Compare against both endpoints of each committed route
|
|
397
|
+
const crPorts = [
|
|
398
|
+
[cr.srcKey, cr.srcSide, cr.srcPort],
|
|
399
|
+
[cr.dstKey, cr.dstSide, cr.dstPort],
|
|
400
|
+
];
|
|
401
|
+
for (const [key, side, pt] of crPorts) {
|
|
402
|
+
if (key === srcKey && side === srcSide) {
|
|
403
|
+
const d = Math.hypot(srcPort.x - pt.x, srcPort.y - pt.y);
|
|
404
|
+
if (d < CONFLICT_RADIUS)
|
|
405
|
+
penalty += W_PORT_CONFLICT * (1 - d / CONFLICT_RADIUS);
|
|
406
|
+
}
|
|
407
|
+
if (key === dstKey && side === dstSide) {
|
|
408
|
+
const d = Math.hypot(dstPort.x - pt.x, dstPort.y - pt.y);
|
|
409
|
+
if (d < CONFLICT_RADIUS)
|
|
410
|
+
penalty += W_PORT_CONFLICT * (1 - d / CONFLICT_RADIUS);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return penalty;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Flat W_ALIGN penalty per short "jog" segment.
|
|
418
|
+
* Jog segments arise when source and destination ports are on the same axis
|
|
419
|
+
* but not exactly aligned, producing a tiny perpendicular segment in an
|
|
420
|
+
* otherwise straight route. Penalising them here causes the cost function
|
|
421
|
+
* to prefer the snapped (straight) alternative.
|
|
422
|
+
*/
|
|
423
|
+
function alignPenalty(points) {
|
|
424
|
+
let penalty = 0;
|
|
425
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
426
|
+
const a = points[i], b = points[i + 1];
|
|
427
|
+
if (Math.hypot(b.x - a.x, b.y - a.y) < SNAP_THRESHOLD)
|
|
428
|
+
penalty += W_ALIGN;
|
|
429
|
+
}
|
|
430
|
+
return penalty;
|
|
431
|
+
}
|
|
432
|
+
// ─── Port alignment snap ──────────────────────────────────────────────────────
|
|
433
|
+
/**
|
|
434
|
+
* If both ports exit on the same axis (E/W or N/S) and their perpendicular
|
|
435
|
+
* offset is within SNAP_THRESHOLD, snap both to the average coordinate.
|
|
436
|
+
*
|
|
437
|
+
* This turns a 3-segment H→V→H route (with a tiny V jog) into a single
|
|
438
|
+
* perfectly horizontal segment — the most common "jagged connector" fix.
|
|
439
|
+
* Similarly for V→H→V routes in the vertical case.
|
|
440
|
+
*/
|
|
441
|
+
function snapAlignment(ss, sp, ds, dp) {
|
|
442
|
+
const sH = ss === 'E' || ss === 'W';
|
|
443
|
+
const dH = ds === 'E' || ds === 'W';
|
|
444
|
+
if (sH && dH && Math.abs(sp.y - dp.y) < SNAP_THRESHOLD) {
|
|
445
|
+
const avgY = (sp.y + dp.y) / 2;
|
|
446
|
+
return {
|
|
447
|
+
srcPort: { x: sp.x, y: avgY },
|
|
448
|
+
dstPort: { x: dp.x, y: avgY },
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
const sV = ss === 'N' || ss === 'S';
|
|
452
|
+
const dV = ds === 'N' || ds === 'S';
|
|
453
|
+
if (sV && dV && Math.abs(sp.x - dp.x) < SNAP_THRESHOLD) {
|
|
454
|
+
const avgX = (sp.x + dp.x) / 2;
|
|
455
|
+
return {
|
|
456
|
+
srcPort: { x: avgX, y: sp.y },
|
|
457
|
+
dstPort: { x: avgX, y: dp.y },
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
return { srcPort: sp, dstPort: dp };
|
|
461
|
+
}
|
|
462
|
+
// ─── Geometry helpers ─────────────────────────────────────────────────────────
|
|
463
|
+
/** Mid-edge port of a bounding rect on the given cardinal side. */
|
|
464
|
+
function midport(bounds, side) {
|
|
465
|
+
const cx = bounds.x + bounds.width / 2;
|
|
466
|
+
const cy = bounds.y + bounds.height / 2;
|
|
467
|
+
switch (side) {
|
|
468
|
+
case 'N': return { x: cx, y: bounds.y };
|
|
469
|
+
case 'S': return { x: cx, y: bounds.y + bounds.height };
|
|
470
|
+
case 'E': return { x: bounds.x + bounds.width, y: cy };
|
|
471
|
+
case 'W': return { x: bounds.x, y: cy };
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Three port positions along a wall at 25 %, 50 %, 75 % of edge length.
|
|
476
|
+
* Trying all three per wall (4×4×3×3 = 144 candidates) lets the port-conflict
|
|
477
|
+
* penalty push simultaneous arrivals on the same wall to different positions.
|
|
478
|
+
*/
|
|
479
|
+
function wallPorts(bounds, side) {
|
|
480
|
+
const { x, y, width, height } = bounds;
|
|
481
|
+
switch (side) {
|
|
482
|
+
case 'N': return [
|
|
483
|
+
{ x: x + width * 0.25, y },
|
|
484
|
+
{ x: x + width * 0.5, y },
|
|
485
|
+
{ x: x + width * 0.75, y },
|
|
486
|
+
];
|
|
487
|
+
case 'S': return [
|
|
488
|
+
{ x: x + width * 0.25, y: y + height },
|
|
489
|
+
{ x: x + width * 0.5, y: y + height },
|
|
490
|
+
{ x: x + width * 0.75, y: y + height },
|
|
491
|
+
];
|
|
492
|
+
case 'W': return [
|
|
493
|
+
{ x, y: y + height * 0.25 },
|
|
494
|
+
{ x, y: y + height * 0.5 },
|
|
495
|
+
{ x, y: y + height * 0.75 },
|
|
496
|
+
];
|
|
497
|
+
case 'E': return [
|
|
498
|
+
{ x: x + width, y: y + height * 0.25 },
|
|
499
|
+
{ x: x + width, y: y + height * 0.5 },
|
|
500
|
+
{ x: x + width, y: y + height * 0.75 },
|
|
501
|
+
];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Sample n+1 evenly-spaced points along a cubic bezier curve.
|
|
506
|
+
* Used to convert bezier control-point arrays into actual path points for
|
|
507
|
+
* crossing detection and arc-length computation.
|
|
508
|
+
*/
|
|
509
|
+
function sampleCubicBezierPts(p0, p1, p2, p3, n) {
|
|
510
|
+
const pts = [];
|
|
511
|
+
for (let i = 0; i <= n; i++) {
|
|
512
|
+
const t = i / n;
|
|
513
|
+
const t2 = t * t, t3 = t2 * t;
|
|
514
|
+
const mt = 1 - t, mt2 = mt * mt, mt3 = mt2 * mt;
|
|
515
|
+
pts.push({
|
|
516
|
+
x: mt3 * p0.x + 3 * mt2 * t * p1.x + 3 * mt * t2 * p2.x + t3 * p3.x,
|
|
517
|
+
y: mt3 * p0.y + 3 * mt2 * t * p1.y + 3 * mt * t2 * p2.y + t3 * p3.y,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
return pts;
|
|
521
|
+
}
|
|
522
|
+
/** True iff two line segments properly cross (not merely touch). */
|
|
523
|
+
function properlyCross(p1, p2, p3, p4) {
|
|
524
|
+
const d1 = cross2(p3, p4, p1), d2 = cross2(p3, p4, p2);
|
|
525
|
+
const d3 = cross2(p1, p2, p3), d4 = cross2(p1, p2, p4);
|
|
526
|
+
return ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
|
|
527
|
+
((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0));
|
|
528
|
+
}
|
|
529
|
+
function cross2(a, b, c) {
|
|
530
|
+
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
|
|
531
|
+
}
|
|
532
|
+
/** Total Euclidean length of a polyline. */
|
|
533
|
+
function pathLen(points) {
|
|
534
|
+
let len = 0;
|
|
535
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
536
|
+
const a = points[i], b = points[i + 1];
|
|
537
|
+
len += Math.hypot(b.x - a.x, b.y - a.y);
|
|
538
|
+
}
|
|
539
|
+
return len;
|
|
540
|
+
}
|
|
541
|
+
/** Point at fraction t (0..1) of total Euclidean path length. */
|
|
542
|
+
function pointAtFrac(points, t) {
|
|
543
|
+
if (points.length === 0)
|
|
544
|
+
return { x: 0, y: 0 };
|
|
545
|
+
if (points.length === 1)
|
|
546
|
+
return points[0];
|
|
547
|
+
const lens = [];
|
|
548
|
+
let total = 0;
|
|
549
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
550
|
+
const a = points[i], b = points[i + 1];
|
|
551
|
+
const l = Math.hypot(b.x - a.x, b.y - a.y);
|
|
552
|
+
lens.push(l);
|
|
553
|
+
total += l;
|
|
554
|
+
}
|
|
555
|
+
if (total === 0)
|
|
556
|
+
return points[0];
|
|
557
|
+
const target = total * Math.min(Math.max(t, 0), 1);
|
|
558
|
+
let acc = 0;
|
|
559
|
+
for (let i = 0; i < lens.length; i++) {
|
|
560
|
+
const l = lens[i];
|
|
561
|
+
if (acc + l >= target) {
|
|
562
|
+
const frac = l > 0 ? (target - acc) / l : 0;
|
|
563
|
+
const a = points[i], b = points[i + 1];
|
|
564
|
+
return { x: a.x + (b.x - a.x) * frac, y: a.y + (b.y - a.y) * frac };
|
|
565
|
+
}
|
|
566
|
+
acc += l;
|
|
567
|
+
}
|
|
568
|
+
return points[points.length - 1];
|
|
569
|
+
}
|
|
570
|
+
/** Axis and fixed coordinate of the dominant (longest) segment. */
|
|
571
|
+
function dominantSegment(points) {
|
|
572
|
+
let bestLen = 0, axis = 'h', coord = 0;
|
|
573
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
574
|
+
const a = points[i], b = points[i + 1];
|
|
575
|
+
const dx = Math.abs(b.x - a.x), dy = Math.abs(b.y - a.y);
|
|
576
|
+
const len = dx + dy;
|
|
577
|
+
if (len > bestLen) {
|
|
578
|
+
bestLen = len;
|
|
579
|
+
if (dy > dx) {
|
|
580
|
+
axis = 'v';
|
|
581
|
+
coord = (a.x + b.x) / 2;
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
axis = 'h';
|
|
585
|
+
coord = (a.y + b.y) / 2;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return { axis, coord };
|
|
590
|
+
}
|
|
591
|
+
function rectsOverlap(a, b) {
|
|
592
|
+
return a.x < b.x + b.width && a.x + a.width > b.x &&
|
|
593
|
+
a.y < b.y + b.height && a.y + a.height > b.y;
|
|
594
|
+
}
|
|
595
|
+
// ─── Post-route: border nudging ───────────────────────────────────────────────
|
|
596
|
+
/**
|
|
597
|
+
* Nudge segments that run parallel along cell borders away from the border.
|
|
598
|
+
* A horizontal segment at y ≈ borderY is shifted vertically by NUDGE.
|
|
599
|
+
* A vertical segment at x ≈ borderX is shifted horizontally by NUDGE.
|
|
600
|
+
* Perpendicular crossings are not affected.
|
|
601
|
+
*/
|
|
602
|
+
function nudgeOffBorders(routes, borders) {
|
|
603
|
+
const TOLERANCE = 3;
|
|
604
|
+
const NUDGE = 8;
|
|
605
|
+
const hBorderYs = [];
|
|
606
|
+
const vBorderXs = [];
|
|
607
|
+
for (const b of borders) {
|
|
608
|
+
if (b.width > b.height)
|
|
609
|
+
hBorderYs.push(b.y + b.height / 2);
|
|
610
|
+
else
|
|
611
|
+
vBorderXs.push(b.x + b.width / 2);
|
|
612
|
+
}
|
|
613
|
+
for (const route of routes) {
|
|
614
|
+
if (route.isBezier)
|
|
615
|
+
continue; // bezier control points are not path segments
|
|
616
|
+
const pts = route.points;
|
|
617
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
618
|
+
const a = pts[i], b = pts[i + 1];
|
|
619
|
+
const dx = Math.abs(b.x - a.x), dy = Math.abs(b.y - a.y);
|
|
620
|
+
if (dy < 1 && dx > 1) {
|
|
621
|
+
for (const borderY of hBorderYs) {
|
|
622
|
+
if (Math.abs(a.y - borderY) < TOLERANCE) {
|
|
623
|
+
const midY = (Math.min(...pts.map(p => p.y)) + Math.max(...pts.map(p => p.y))) / 2;
|
|
624
|
+
const nudgeD = a.y < midY ? -NUDGE : NUDGE;
|
|
625
|
+
pts[i] = { x: a.x, y: a.y + nudgeD };
|
|
626
|
+
pts[i + 1] = { x: b.x, y: b.y + nudgeD };
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
else if (dx < 1 && dy > 1) {
|
|
632
|
+
for (const borderX of vBorderXs) {
|
|
633
|
+
if (Math.abs(a.x - borderX) < TOLERANCE) {
|
|
634
|
+
const midX = (Math.min(...pts.map(p => p.x)) + Math.max(...pts.map(p => p.x))) / 2;
|
|
635
|
+
const nudgeD = a.x < midX ? -NUDGE : NUDGE;
|
|
636
|
+
pts[i] = { x: a.x + nudgeD, y: a.y };
|
|
637
|
+
pts[i + 1] = { x: b.x + nudgeD, y: b.y };
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
// ─── Post-route: channel separation ──────────────────────────────────────────
|
|
646
|
+
/**
|
|
647
|
+
* Detect overlapping parallel segments across routes and offset them by
|
|
648
|
+
* CHANNEL_GAP so they form a visible bundle rather than drawing on top of
|
|
649
|
+
* each other. Mutates route point arrays in place.
|
|
650
|
+
*/
|
|
651
|
+
function separateChannels(routes) {
|
|
652
|
+
const segs = [];
|
|
653
|
+
for (let ri = 0; ri < routes.length; ri++) {
|
|
654
|
+
if (routes[ri].isBezier)
|
|
655
|
+
continue; // bezier control points are not segments
|
|
656
|
+
const pts = routes[ri].points;
|
|
657
|
+
for (let si = 0; si < pts.length - 1; si++) {
|
|
658
|
+
const a = pts[si], b = pts[si + 1];
|
|
659
|
+
const dx = Math.abs(b.x - a.x), dy = Math.abs(b.y - a.y);
|
|
660
|
+
if (dx < 1 && dy > 1) {
|
|
661
|
+
segs.push({ routeIdx: ri, segIdx: si, isV: true, coord: (a.x + b.x) / 2, lo: Math.min(a.y, b.y), hi: Math.max(a.y, b.y) });
|
|
662
|
+
}
|
|
663
|
+
else if (dy < 1 && dx > 1) {
|
|
664
|
+
segs.push({ routeIdx: ri, segIdx: si, isV: false, coord: (a.y + b.y) / 2, lo: Math.min(a.x, b.x), hi: Math.max(a.x, b.x) });
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
const COORD_TOL = 10;
|
|
669
|
+
const used = new Set();
|
|
670
|
+
for (let i = 0; i < segs.length; i++) {
|
|
671
|
+
if (used.has(i))
|
|
672
|
+
continue;
|
|
673
|
+
const si = segs[i];
|
|
674
|
+
const group = [i];
|
|
675
|
+
for (let j = i + 1; j < segs.length; j++) {
|
|
676
|
+
if (used.has(j))
|
|
677
|
+
continue;
|
|
678
|
+
const sj = segs[j];
|
|
679
|
+
if (sj.isV !== si.isV)
|
|
680
|
+
continue;
|
|
681
|
+
if (Math.abs(sj.coord - si.coord) > COORD_TOL)
|
|
682
|
+
continue;
|
|
683
|
+
if (sj.hi - si.lo > 8 && si.hi - sj.lo > 8) { // ranges overlap
|
|
684
|
+
group.push(j);
|
|
685
|
+
used.add(j);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
used.add(i);
|
|
689
|
+
if (group.length < 2)
|
|
690
|
+
continue;
|
|
691
|
+
const n = group.length;
|
|
692
|
+
for (let k = 0; k < n; k++) {
|
|
693
|
+
const seg = segs[group[k]];
|
|
694
|
+
const offset = (k - (n - 1) / 2) * CHANNEL_GAP;
|
|
695
|
+
const pts = routes[seg.routeIdx].points;
|
|
696
|
+
if (seg.isV) {
|
|
697
|
+
pts[seg.segIdx] = { x: pts[seg.segIdx].x + offset, y: pts[seg.segIdx].y };
|
|
698
|
+
pts[seg.segIdx + 1] = { x: pts[seg.segIdx + 1].x + offset, y: pts[seg.segIdx + 1].y };
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
pts[seg.segIdx] = { x: pts[seg.segIdx].x, y: pts[seg.segIdx].y + offset };
|
|
702
|
+
pts[seg.segIdx + 1] = { x: pts[seg.segIdx + 1].x, y: pts[seg.segIdx + 1].y + offset };
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
// ─── Post-route: label de-collision ──────────────────────────────────────────
|
|
708
|
+
/**
|
|
709
|
+
* Iteratively push overlapping label rectangles away from each other and from
|
|
710
|
+
* fixed obstacles. Uses the minimum-translation-vector (MTV) approach.
|
|
711
|
+
* Mutates labelRects in place.
|
|
712
|
+
*/
|
|
713
|
+
function deCollideLabels(labelRects, fixedRects) {
|
|
714
|
+
const MAX_PASSES = 20;
|
|
715
|
+
const NUDGE = 2;
|
|
716
|
+
for (let pass = 0; pass < MAX_PASSES; pass++) {
|
|
717
|
+
let moved = false;
|
|
718
|
+
// Push labels away from fixed rects
|
|
719
|
+
for (const lr of labelRects) {
|
|
720
|
+
for (const fr of fixedRects) {
|
|
721
|
+
if (!rectsOverlap(lr, fr))
|
|
722
|
+
continue;
|
|
723
|
+
const ox = Math.min(lr.x + lr.width, fr.x + fr.width) - Math.max(lr.x, fr.x);
|
|
724
|
+
const oy = Math.min(lr.y + lr.height, fr.y + fr.height) - Math.max(lr.y, fr.y);
|
|
725
|
+
if (ox <= oy) {
|
|
726
|
+
lr.x = (lr.x + lr.width / 2) <= (fr.x + fr.width / 2)
|
|
727
|
+
? fr.x - lr.width - NUDGE
|
|
728
|
+
: fr.x + fr.width + NUDGE;
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
lr.y = (lr.y + lr.height / 2) <= (fr.y + fr.height / 2)
|
|
732
|
+
? fr.y - lr.height - NUDGE
|
|
733
|
+
: fr.y + fr.height + NUDGE;
|
|
734
|
+
}
|
|
735
|
+
moved = true;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
// Push labels away from each other
|
|
739
|
+
for (let i = 0; i < labelRects.length; i++) {
|
|
740
|
+
for (let j = i + 1; j < labelRects.length; j++) {
|
|
741
|
+
const a = labelRects[i], b = labelRects[j];
|
|
742
|
+
if (!rectsOverlap(a, b))
|
|
743
|
+
continue;
|
|
744
|
+
const ox = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);
|
|
745
|
+
const oy = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
|
|
746
|
+
if (ox <= oy) {
|
|
747
|
+
if ((a.x + a.width / 2) <= (b.x + b.width / 2)) {
|
|
748
|
+
a.x -= ox / 2;
|
|
749
|
+
b.x += ox / 2;
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
a.x += ox / 2;
|
|
753
|
+
b.x -= ox / 2;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
if ((a.y + a.height / 2) <= (b.y + b.height / 2)) {
|
|
758
|
+
const ov = (a.y + a.height) - b.y;
|
|
759
|
+
a.y -= (ov + NUDGE) / 2;
|
|
760
|
+
b.y += (ov + NUDGE) / 2;
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
const ov = (b.y + b.height) - a.y;
|
|
764
|
+
b.y -= (ov + NUDGE) / 2;
|
|
765
|
+
a.y += (ov + NUDGE) / 2;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
moved = true;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
if (!moved)
|
|
772
|
+
break;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
// ─── Edge style ───────────────────────────────────────────────────────────────
|
|
776
|
+
function edgeStyleToDash(style) {
|
|
777
|
+
switch (style) {
|
|
778
|
+
case 'dashed': return '8 4';
|
|
779
|
+
case 'dotted': return '4 3';
|
|
780
|
+
default: return undefined;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
//# sourceMappingURL=engine2.js.map
|