@chengchenccc/tui 0.1.1-rc.1
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/autocomplete.d.ts +56 -0
- package/dist/autocomplete.d.ts.map +1 -0
- package/dist/autocomplete.js +647 -0
- package/dist/components/box.d.ts +22 -0
- package/dist/components/box.d.ts.map +1 -0
- package/dist/components/box.js +103 -0
- package/dist/components/card.d.ts +33 -0
- package/dist/components/card.d.ts.map +1 -0
- package/dist/components/card.js +49 -0
- package/dist/components/editor.d.ts +257 -0
- package/dist/components/editor.d.ts.map +1 -0
- package/dist/components/editor.js +1980 -0
- package/dist/components/input.d.ts +37 -0
- package/dist/components/input.d.ts.map +1 -0
- package/dist/components/input.js +389 -0
- package/dist/components/loader.d.ts +33 -0
- package/dist/components/loader.d.ts.map +1 -0
- package/dist/components/loader.js +100 -0
- package/dist/components/markdown.d.ts +108 -0
- package/dist/components/markdown.d.ts.map +1 -0
- package/dist/components/markdown.js +847 -0
- package/dist/components/markdown.test.d.ts +2 -0
- package/dist/components/markdown.test.d.ts.map +1 -0
- package/dist/components/markdown.test.js +81 -0
- package/dist/components/output-block.d.ts +44 -0
- package/dist/components/output-block.d.ts.map +1 -0
- package/dist/components/output-block.js +131 -0
- package/dist/components/select-list.d.ts +50 -0
- package/dist/components/select-list.d.ts.map +1 -0
- package/dist/components/select-list.js +166 -0
- package/dist/components/spacer.d.ts +12 -0
- package/dist/components/spacer.d.ts.map +1 -0
- package/dist/components/spacer.js +22 -0
- package/dist/components/statusline.d.ts +30 -0
- package/dist/components/statusline.d.ts.map +1 -0
- package/dist/components/statusline.js +46 -0
- package/dist/components/text.d.ts +19 -0
- package/dist/components/text.d.ts.map +1 -0
- package/dist/components/text.js +90 -0
- package/dist/components/truncated-text.d.ts +13 -0
- package/dist/components/truncated-text.d.ts.map +1 -0
- package/dist/components/truncated-text.js +50 -0
- package/dist/editor-component.d.ts +39 -0
- package/dist/editor-component.d.ts.map +1 -0
- package/dist/editor-component.js +1 -0
- package/dist/fuzzy.d.ts +16 -0
- package/dist/fuzzy.d.ts.map +1 -0
- package/dist/fuzzy.js +109 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/keybindings.d.ts +193 -0
- package/dist/keybindings.d.ts.map +1 -0
- package/dist/keybindings.js +191 -0
- package/dist/keys.d.ts +184 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +1191 -0
- package/dist/kill-ring.d.ts +28 -0
- package/dist/kill-ring.d.ts.map +1 -0
- package/dist/kill-ring.js +43 -0
- package/dist/mermaid.d.ts +23 -0
- package/dist/mermaid.d.ts.map +1 -0
- package/dist/mermaid.js +77 -0
- package/dist/mouse.d.ts +40 -0
- package/dist/mouse.d.ts.map +1 -0
- package/dist/mouse.js +39 -0
- package/dist/mouse.test.d.ts +2 -0
- package/dist/mouse.test.d.ts.map +1 -0
- package/dist/mouse.test.js +36 -0
- package/dist/native-modifiers.d.ts +3 -0
- package/dist/native-modifiers.d.ts.map +1 -0
- package/dist/native-modifiers.js +52 -0
- package/dist/stdin-buffer.d.ts +50 -0
- package/dist/stdin-buffer.d.ts.map +1 -0
- package/dist/stdin-buffer.js +360 -0
- package/dist/terminal-colors.d.ts +10 -0
- package/dist/terminal-colors.d.ts.map +1 -0
- package/dist/terminal-colors.js +58 -0
- package/dist/terminal-image.d.ts +90 -0
- package/dist/terminal-image.d.ts.map +1 -0
- package/dist/terminal-image.js +375 -0
- package/dist/terminal.d.ts +110 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +432 -0
- package/dist/tui-scrollback.test.d.ts +2 -0
- package/dist/tui-scrollback.test.d.ts.map +1 -0
- package/dist/tui-scrollback.test.js +51 -0
- package/dist/tui.d.ts +330 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +1568 -0
- package/dist/undo-stack.d.ts +17 -0
- package/dist/undo-stack.d.ts.map +1 -0
- package/dist/undo-stack.js +24 -0
- package/dist/utils.d.ts +85 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +1066 -0
- package/dist/vendor/mermaid-ascii/ascii/ansi.d.ts +42 -0
- package/dist/vendor/mermaid-ascii/ascii/ansi.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/ansi.js +361 -0
- package/dist/vendor/mermaid-ascii/ascii/canvas.d.ts +90 -0
- package/dist/vendor/mermaid-ascii/ascii/canvas.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/canvas.js +414 -0
- package/dist/vendor/mermaid-ascii/ascii/class-diagram.d.ts +8 -0
- package/dist/vendor/mermaid-ascii/ascii/class-diagram.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/class-diagram.js +623 -0
- package/dist/vendor/mermaid-ascii/ascii/converter.d.ts +13 -0
- package/dist/vendor/mermaid-ascii/ascii/converter.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/converter.js +233 -0
- package/dist/vendor/mermaid-ascii/ascii/draw.d.ts +67 -0
- package/dist/vendor/mermaid-ascii/ascii/draw.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/draw.js +1313 -0
- package/dist/vendor/mermaid-ascii/ascii/edge-bundling.d.ts +49 -0
- package/dist/vendor/mermaid-ascii/ascii/edge-bundling.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/edge-bundling.js +289 -0
- package/dist/vendor/mermaid-ascii/ascii/edge-routing.d.ts +44 -0
- package/dist/vendor/mermaid-ascii/ascii/edge-routing.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/edge-routing.js +302 -0
- package/dist/vendor/mermaid-ascii/ascii/er-diagram.d.ts +8 -0
- package/dist/vendor/mermaid-ascii/ascii/er-diagram.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/er-diagram.js +380 -0
- package/dist/vendor/mermaid-ascii/ascii/grid.d.ts +57 -0
- package/dist/vendor/mermaid-ascii/ascii/grid.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/grid.js +516 -0
- package/dist/vendor/mermaid-ascii/ascii/index.d.ts +66 -0
- package/dist/vendor/mermaid-ascii/ascii/index.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/index.js +133 -0
- package/dist/vendor/mermaid-ascii/ascii/multiline-utils.d.ts +28 -0
- package/dist/vendor/mermaid-ascii/ascii/multiline-utils.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/multiline-utils.js +60 -0
- package/dist/vendor/mermaid-ascii/ascii/pathfinder.d.ts +18 -0
- package/dist/vendor/mermaid-ascii/ascii/pathfinder.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/pathfinder.js +224 -0
- package/dist/vendor/mermaid-ascii/ascii/sequence.d.ts +8 -0
- package/dist/vendor/mermaid-ascii/ascii/sequence.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/sequence.js +416 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/circle.d.ts +12 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/circle.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/circle.js +22 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/corners.d.ts +35 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/corners.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/corners.js +91 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/diamond.d.ts +12 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/diamond.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/diamond.js +22 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/hexagon.d.ts +12 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/hexagon.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/hexagon.js +22 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/index.d.ts +27 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/index.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/index.js +66 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/rectangle.d.ts +32 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/rectangle.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/rectangle.js +149 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/rounded.d.ts +12 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/rounded.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/rounded.js +22 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/special.d.ts +60 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/special.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/special.js +253 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/stadium.d.ts +18 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/stadium.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/stadium.js +103 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/state.d.ts +31 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/state.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/state.js +167 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/types.d.ts +56 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/types.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/shapes/types.js +4 -0
- package/dist/vendor/mermaid-ascii/ascii/types.d.ts +207 -0
- package/dist/vendor/mermaid-ascii/ascii/types.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/types.js +39 -0
- package/dist/vendor/mermaid-ascii/ascii/validate.d.ts +52 -0
- package/dist/vendor/mermaid-ascii/ascii/validate.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/validate.js +97 -0
- package/dist/vendor/mermaid-ascii/ascii/xychart.d.ts +3 -0
- package/dist/vendor/mermaid-ascii/ascii/xychart.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/ascii/xychart.js +719 -0
- package/dist/vendor/mermaid-ascii/class/parser.d.ts +7 -0
- package/dist/vendor/mermaid-ascii/class/parser.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/class/parser.js +265 -0
- package/dist/vendor/mermaid-ascii/class/types.d.ts +103 -0
- package/dist/vendor/mermaid-ascii/class/types.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/class/types.js +7 -0
- package/dist/vendor/mermaid-ascii/er/parser.d.ts +7 -0
- package/dist/vendor/mermaid-ascii/er/parser.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/er/parser.js +162 -0
- package/dist/vendor/mermaid-ascii/er/types.d.ts +77 -0
- package/dist/vendor/mermaid-ascii/er/types.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/er/types.js +7 -0
- package/dist/vendor/mermaid-ascii/index.d.ts +2 -0
- package/dist/vendor/mermaid-ascii/index.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/index.js +13 -0
- package/dist/vendor/mermaid-ascii/multiline-utils.d.ts +10 -0
- package/dist/vendor/mermaid-ascii/multiline-utils.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/multiline-utils.js +29 -0
- package/dist/vendor/mermaid-ascii/parser.d.ts +8 -0
- package/dist/vendor/mermaid-ascii/parser.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/parser.js +558 -0
- package/dist/vendor/mermaid-ascii/sequence/parser.d.ts +7 -0
- package/dist/vendor/mermaid-ascii/sequence/parser.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/sequence/parser.js +182 -0
- package/dist/vendor/mermaid-ascii/sequence/types.d.ts +131 -0
- package/dist/vendor/mermaid-ascii/sequence/types.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/sequence/types.js +7 -0
- package/dist/vendor/mermaid-ascii/text-metrics.d.ts +24 -0
- package/dist/vendor/mermaid-ascii/text-metrics.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/text-metrics.js +69 -0
- package/dist/vendor/mermaid-ascii/types.d.ts +115 -0
- package/dist/vendor/mermaid-ascii/types.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/types.js +4 -0
- package/dist/vendor/mermaid-ascii/xychart/colors.d.ts +26 -0
- package/dist/vendor/mermaid-ascii/xychart/colors.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/xychart/colors.js +145 -0
- package/dist/vendor/mermaid-ascii/xychart/parser.d.ts +7 -0
- package/dist/vendor/mermaid-ascii/xychart/parser.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/xychart/parser.js +105 -0
- package/dist/vendor/mermaid-ascii/xychart/types.d.ts +146 -0
- package/dist/vendor/mermaid-ascii/xychart/types.d.ts.map +1 -0
- package/dist/vendor/mermaid-ascii/xychart/types.js +8 -0
- package/dist/virtual-terminal.d.ts +80 -0
- package/dist/virtual-terminal.d.ts.map +1 -0
- package/dist/virtual-terminal.js +284 -0
- package/dist/word-navigation.d.ts +25 -0
- package/dist/word-navigation.d.ts.map +1 -0
- package/dist/word-navigation.js +97 -0
- package/package.json +38 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// ASCII renderer — direction system and edge path determination
|
|
3
|
+
//
|
|
4
|
+
// Ported from AlexanderGrooff/mermaid-ascii cmd/direction.go + cmd/mapping_edge.go.
|
|
5
|
+
// Handles direction constants, edge attachment point selection,
|
|
6
|
+
// and dual-path comparison for optimal edge routing.
|
|
7
|
+
// ============================================================================
|
|
8
|
+
import { Up, Down, Left, Right, UpperRight, UpperLeft, LowerRight, LowerLeft, Middle, gridCoordDirection, } from "./types.js";
|
|
9
|
+
import { getPath, mergePath } from "./pathfinder.js";
|
|
10
|
+
import { getNodeSubgraph } from "./grid.js";
|
|
11
|
+
import { displayWidth } from "../text-metrics.js";
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Direction utilities
|
|
14
|
+
// ============================================================================
|
|
15
|
+
export function getOpposite(d) {
|
|
16
|
+
if (d === Up)
|
|
17
|
+
return Down;
|
|
18
|
+
if (d === Down)
|
|
19
|
+
return Up;
|
|
20
|
+
if (d === Left)
|
|
21
|
+
return Right;
|
|
22
|
+
if (d === Right)
|
|
23
|
+
return Left;
|
|
24
|
+
if (d === UpperRight)
|
|
25
|
+
return LowerLeft;
|
|
26
|
+
if (d === UpperLeft)
|
|
27
|
+
return LowerRight;
|
|
28
|
+
if (d === LowerRight)
|
|
29
|
+
return UpperLeft;
|
|
30
|
+
if (d === LowerLeft)
|
|
31
|
+
return UpperRight;
|
|
32
|
+
return Middle;
|
|
33
|
+
}
|
|
34
|
+
/** Compare directions by value (not reference). */
|
|
35
|
+
export function dirEquals(a, b) {
|
|
36
|
+
return a.x === b.x && a.y === b.y;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Determine 8-way direction from one coordinate to another.
|
|
40
|
+
* Uses the coordinate difference to pick one of 8 cardinal/ordinal directions.
|
|
41
|
+
*/
|
|
42
|
+
export function determineDirection(from, to) {
|
|
43
|
+
if (from.x === to.x) {
|
|
44
|
+
return from.y < to.y ? Down : Up;
|
|
45
|
+
}
|
|
46
|
+
else if (from.y === to.y) {
|
|
47
|
+
return from.x < to.x ? Right : Left;
|
|
48
|
+
}
|
|
49
|
+
else if (from.x < to.x) {
|
|
50
|
+
return from.y < to.y ? LowerRight : UpperRight;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return from.y < to.y ? LowerLeft : UpperLeft;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Start/end direction selection for edges
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/** Self-reference routing (node points to itself). */
|
|
60
|
+
function selfReferenceDirection(graphDirection) {
|
|
61
|
+
if (graphDirection === 'LR')
|
|
62
|
+
return [Right, Down, Down, Right];
|
|
63
|
+
return [Down, Right, Right, Down];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Determine preferred and alternative start/end directions for an edge.
|
|
67
|
+
* Returns [preferredStart, preferredEnd, alternativeStart, alternativeEnd].
|
|
68
|
+
*
|
|
69
|
+
* The edge routing tries both pairs and picks the shorter path.
|
|
70
|
+
* Direction selection depends on relative node positions and graph direction (LR vs TD).
|
|
71
|
+
*/
|
|
72
|
+
export function determineStartAndEndDir(edge, graphDirection) {
|
|
73
|
+
if (edge.from === edge.to)
|
|
74
|
+
return selfReferenceDirection(graphDirection);
|
|
75
|
+
const d = determineDirection(edge.from.gridCoord, edge.to.gridCoord);
|
|
76
|
+
let preferredDir;
|
|
77
|
+
let preferredOppositeDir;
|
|
78
|
+
let alternativeDir;
|
|
79
|
+
let alternativeOppositeDir;
|
|
80
|
+
const isBackwards = graphDirection === 'LR'
|
|
81
|
+
? (dirEquals(d, Left) || dirEquals(d, UpperLeft) || dirEquals(d, LowerLeft))
|
|
82
|
+
: (dirEquals(d, Up) || dirEquals(d, UpperLeft) || dirEquals(d, UpperRight));
|
|
83
|
+
if (dirEquals(d, LowerRight)) {
|
|
84
|
+
if (graphDirection === 'LR') {
|
|
85
|
+
preferredDir = Down;
|
|
86
|
+
preferredOppositeDir = Left;
|
|
87
|
+
alternativeDir = Right;
|
|
88
|
+
alternativeOppositeDir = Up;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
preferredDir = Right;
|
|
92
|
+
preferredOppositeDir = Up;
|
|
93
|
+
alternativeDir = Down;
|
|
94
|
+
alternativeOppositeDir = Left;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (dirEquals(d, UpperRight)) {
|
|
98
|
+
if (graphDirection === 'LR') {
|
|
99
|
+
preferredDir = Up;
|
|
100
|
+
preferredOppositeDir = Left;
|
|
101
|
+
alternativeDir = Right;
|
|
102
|
+
alternativeOppositeDir = Down;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
preferredDir = Right;
|
|
106
|
+
preferredOppositeDir = Down;
|
|
107
|
+
alternativeDir = Up;
|
|
108
|
+
alternativeOppositeDir = Left;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else if (dirEquals(d, LowerLeft)) {
|
|
112
|
+
if (graphDirection === 'LR') {
|
|
113
|
+
preferredDir = Down;
|
|
114
|
+
preferredOppositeDir = Down;
|
|
115
|
+
alternativeDir = Left;
|
|
116
|
+
alternativeOppositeDir = Up;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
preferredDir = Left;
|
|
120
|
+
preferredOppositeDir = Up;
|
|
121
|
+
alternativeDir = Down;
|
|
122
|
+
alternativeOppositeDir = Right;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (dirEquals(d, UpperLeft)) {
|
|
126
|
+
if (graphDirection === 'LR') {
|
|
127
|
+
preferredDir = Down;
|
|
128
|
+
preferredOppositeDir = Down;
|
|
129
|
+
alternativeDir = Left;
|
|
130
|
+
alternativeOppositeDir = Down;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
preferredDir = Right;
|
|
134
|
+
preferredOppositeDir = Right;
|
|
135
|
+
alternativeDir = Up;
|
|
136
|
+
alternativeOppositeDir = Right;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (isBackwards) {
|
|
140
|
+
if (graphDirection === 'LR' && dirEquals(d, Left)) {
|
|
141
|
+
preferredDir = Down;
|
|
142
|
+
preferredOppositeDir = Down;
|
|
143
|
+
alternativeDir = Left;
|
|
144
|
+
alternativeOppositeDir = Right;
|
|
145
|
+
}
|
|
146
|
+
else if (graphDirection === 'TD' && dirEquals(d, Up)) {
|
|
147
|
+
preferredDir = Right;
|
|
148
|
+
preferredOppositeDir = Right;
|
|
149
|
+
alternativeDir = Up;
|
|
150
|
+
alternativeOppositeDir = Down;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
preferredDir = d;
|
|
154
|
+
preferredOppositeDir = getOpposite(d);
|
|
155
|
+
alternativeDir = d;
|
|
156
|
+
alternativeOppositeDir = getOpposite(d);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
// Default: go in the natural direction
|
|
161
|
+
preferredDir = d;
|
|
162
|
+
preferredOppositeDir = getOpposite(d);
|
|
163
|
+
alternativeDir = d;
|
|
164
|
+
alternativeOppositeDir = getOpposite(d);
|
|
165
|
+
}
|
|
166
|
+
return [preferredDir, preferredOppositeDir, alternativeDir, alternativeOppositeDir];
|
|
167
|
+
}
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// Edge path determination
|
|
170
|
+
// ============================================================================
|
|
171
|
+
/**
|
|
172
|
+
* Determine the path for an edge by trying two candidate routes (preferred + alternative)
|
|
173
|
+
* and picking the shorter one. Sets edge.path, edge.startDir, edge.endDir.
|
|
174
|
+
*
|
|
175
|
+
* When both A* paths fail (common for edges crossing subgraph boundaries), falls back
|
|
176
|
+
* to a direct path using the start/end points. This ensures edges always have a path
|
|
177
|
+
* for arrowhead rendering.
|
|
178
|
+
*
|
|
179
|
+
* Uses the effective direction for edge routing, respecting subgraph direction overrides
|
|
180
|
+
* when both source and target are in the same subgraph.
|
|
181
|
+
*/
|
|
182
|
+
export function determinePath(graph, edge) {
|
|
183
|
+
// Determine effective direction for this edge
|
|
184
|
+
// If both nodes are in the same subgraph with a direction override, use it
|
|
185
|
+
// Otherwise, use the graph's direction (not source's effective direction)
|
|
186
|
+
const sourceSg = getNodeSubgraph(graph, edge.from);
|
|
187
|
+
const targetSg = getNodeSubgraph(graph, edge.to);
|
|
188
|
+
const effectiveDir = (sourceSg && sourceSg === targetSg && sourceSg.direction)
|
|
189
|
+
? sourceSg.direction
|
|
190
|
+
: graph.config.graphDirection;
|
|
191
|
+
const [preferredDir, preferredOppositeDir, alternativeDir, alternativeOppositeDir] = determineStartAndEndDir(edge, effectiveDir);
|
|
192
|
+
// Try preferred path
|
|
193
|
+
const prefFrom = gridCoordDirection(edge.from.gridCoord, preferredDir);
|
|
194
|
+
const prefTo = gridCoordDirection(edge.to.gridCoord, preferredOppositeDir);
|
|
195
|
+
let preferredPath = getPath(graph.grid, prefFrom, prefTo);
|
|
196
|
+
// Try alternative path
|
|
197
|
+
const altFrom = gridCoordDirection(edge.from.gridCoord, alternativeDir);
|
|
198
|
+
const altTo = gridCoordDirection(edge.to.gridCoord, alternativeOppositeDir);
|
|
199
|
+
let alternativePath = getPath(graph.grid, altFrom, altTo);
|
|
200
|
+
// Case 1: Both paths found — pick the shorter one
|
|
201
|
+
if (preferredPath !== null && alternativePath !== null) {
|
|
202
|
+
preferredPath = mergePath(preferredPath);
|
|
203
|
+
alternativePath = mergePath(alternativePath);
|
|
204
|
+
if (preferredPath.length <= alternativePath.length) {
|
|
205
|
+
edge.startDir = preferredDir;
|
|
206
|
+
edge.endDir = preferredOppositeDir;
|
|
207
|
+
edge.path = preferredPath;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
edge.startDir = alternativeDir;
|
|
211
|
+
edge.endDir = alternativeOppositeDir;
|
|
212
|
+
edge.path = alternativePath;
|
|
213
|
+
}
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
// Case 2: Only preferred path found
|
|
217
|
+
if (preferredPath !== null) {
|
|
218
|
+
edge.startDir = preferredDir;
|
|
219
|
+
edge.endDir = preferredOppositeDir;
|
|
220
|
+
edge.path = mergePath(preferredPath);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Case 3: Only alternative path found
|
|
224
|
+
if (alternativePath !== null) {
|
|
225
|
+
edge.startDir = alternativeDir;
|
|
226
|
+
edge.endDir = alternativeOppositeDir;
|
|
227
|
+
edge.path = mergePath(alternativePath);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// Case 4: Both paths failed — create a direct fallback path
|
|
231
|
+
// This happens for edges crossing subgraph boundaries where A* can't find
|
|
232
|
+
// a clear route. We create a direct path from source to target exit points
|
|
233
|
+
// so arrowheads can still be rendered correctly.
|
|
234
|
+
edge.startDir = preferredDir;
|
|
235
|
+
edge.endDir = preferredOppositeDir;
|
|
236
|
+
edge.path = [prefFrom, prefTo];
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Find the best line segment in an edge's path to place a label on.
|
|
240
|
+
* Prefers vertical segments for TD/BT graphs and horizontal for LR/RL to avoid
|
|
241
|
+
* label collisions when multiple edges share initial segments.
|
|
242
|
+
* Falls back to the widest segment if none are suitable.
|
|
243
|
+
* Also increases the column width at the label position to fit the text.
|
|
244
|
+
*/
|
|
245
|
+
export function determineLabelLine(graph, edge) {
|
|
246
|
+
if (edge.text.length === 0)
|
|
247
|
+
return;
|
|
248
|
+
const lenLabel = displayWidth(edge.text);
|
|
249
|
+
const pathLen = edge.path.length;
|
|
250
|
+
const isVerticalFlow = graph.config.graphDirection === 'TD';
|
|
251
|
+
// Collect all segments with their widths and orientation
|
|
252
|
+
const segments = [];
|
|
253
|
+
for (let i = 1; i < pathLen; i++) {
|
|
254
|
+
const p1 = edge.path[i - 1];
|
|
255
|
+
const p2 = edge.path[i];
|
|
256
|
+
const line = [p1, p2];
|
|
257
|
+
const width = calculateLineWidth(graph, line);
|
|
258
|
+
// A segment is vertical if X coords are same, horizontal if Y coords are same
|
|
259
|
+
const isVertical = p1.x === p2.x;
|
|
260
|
+
segments.push({ line, width, index: i, isVertical });
|
|
261
|
+
}
|
|
262
|
+
// Find segments wide enough for the label, excluding the first segment
|
|
263
|
+
// The first segment is often shared between edges from the same source node
|
|
264
|
+
const suitableSegments = segments.filter(s => s.width >= lenLabel && s.index > 1);
|
|
265
|
+
let largestLine;
|
|
266
|
+
if (suitableSegments.length > 0) {
|
|
267
|
+
// Prefer segments near the end of the path (closer to target)
|
|
268
|
+
// This avoids the shared initial segments from source
|
|
269
|
+
suitableSegments.sort((a, b) => b.index - a.index);
|
|
270
|
+
largestLine = suitableSegments[0].line;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
// Fall back to any suitable segment including the first
|
|
274
|
+
const fallbackSegments = segments.filter(s => s.width >= lenLabel);
|
|
275
|
+
if (fallbackSegments.length > 0) {
|
|
276
|
+
fallbackSegments.sort((a, b) => b.index - a.index);
|
|
277
|
+
largestLine = fallbackSegments[0].line;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// No segment wide enough — use the widest one
|
|
281
|
+
segments.sort((a, b) => b.width - a.width);
|
|
282
|
+
largestLine = segments[0]?.line ?? [edge.path[0], edge.path[1]];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Ensure column at midpoint is wide enough for the label
|
|
286
|
+
const minX = Math.min(largestLine[0].x, largestLine[1].x);
|
|
287
|
+
const maxX = Math.max(largestLine[0].x, largestLine[1].x);
|
|
288
|
+
const middleX = minX + Math.floor((maxX - minX) / 2);
|
|
289
|
+
const current = graph.columnWidth.get(middleX) ?? 0;
|
|
290
|
+
graph.columnWidth.set(middleX, Math.max(current, lenLabel + 2));
|
|
291
|
+
edge.labelLine = [largestLine[0], largestLine[1]];
|
|
292
|
+
}
|
|
293
|
+
/** Calculate the total character width of a line segment by summing column widths. */
|
|
294
|
+
function calculateLineWidth(graph, line) {
|
|
295
|
+
let total = 0;
|
|
296
|
+
const startX = Math.min(line[0].x, line[1].x);
|
|
297
|
+
const endX = Math.max(line[0].x, line[1].x);
|
|
298
|
+
for (let x = startX; x <= endX; x++) {
|
|
299
|
+
total += graph.columnWidth.get(x) ?? 0;
|
|
300
|
+
}
|
|
301
|
+
return total;
|
|
302
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AsciiConfig, AsciiTheme, ColorMode } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Render a Mermaid ER diagram to ASCII/Unicode text.
|
|
4
|
+
*
|
|
5
|
+
* Pipeline: parse → build boxes → component-aware layout → draw boxes → draw relationships → string.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderErAscii(text: string, config: AsciiConfig, colorMode?: ColorMode, theme?: AsciiTheme): string;
|
|
8
|
+
//# sourceMappingURL=er-diagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"er-diagram.d.ts","sourceRoot":"","sources":["../../../../src/vendor/mermaid-ascii/ascii/er-diagram.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAU,WAAW,EAAwB,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AA6IlG;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAyRlH"}
|