@knowvah/dot-engine 2.2.0 → 2.3.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/index.js +274 -257
- package/dist/index.js.map +4 -4
- package/dist/layout/dot/edge-route.d.ts.map +1 -1
- package/dist/layout/dot/ortho-adapter.d.ts +1 -1
- package/dist/layout/dot/ortho-adapter.d.ts.map +1 -1
- package/dist/layout/dot/splines-flat-multi.d.ts +3 -1
- package/dist/layout/dot/splines-flat-multi.d.ts.map +1 -1
- package/dist/layout/dot/splines-flat.d.ts +3 -4
- package/dist/layout/dot/splines-flat.d.ts.map +1 -1
- package/dist/pathplan/route.d.ts.map +1 -1
- package/dist/pathplan/solvers.d.ts +15 -3
- package/dist/pathplan/solvers.d.ts.map +1 -1
- package/dist/render.js +274 -257
- package/dist/render.js.map +4 -4
- package/package.json +5 -3
- package/src/layout/dot/edge-route.ts +17 -7
- package/src/layout/dot/ortho-adapter.ts +4 -3
- package/src/layout/dot/splines-flat-multi.ts +17 -4
- package/src/layout/dot/splines-flat.ts +12 -12
- package/src/parser/dot.js +68 -94
- package/src/parser/dot.pegjs +7 -6
- package/src/pathplan/route.ts +79 -34
- package/src/pathplan/solvers.ts +78 -50
package/dist/index.js
CHANGED
|
@@ -265,22 +265,19 @@ function peg$parse(input, options) {
|
|
|
265
265
|
function peg$f17(defs, rest) {
|
|
266
266
|
return defs.concat(rest);
|
|
267
267
|
}
|
|
268
|
-
function peg$f18(
|
|
269
|
-
return defs;
|
|
270
|
-
}
|
|
271
|
-
function peg$f19() {
|
|
268
|
+
function peg$f18() {
|
|
272
269
|
return [];
|
|
273
270
|
}
|
|
274
|
-
function peg$
|
|
271
|
+
function peg$f19(a) {
|
|
275
272
|
return a;
|
|
276
273
|
}
|
|
277
|
-
function peg$
|
|
274
|
+
function peg$f20(pairs) {
|
|
278
275
|
return pairs;
|
|
279
276
|
}
|
|
280
|
-
function peg$
|
|
277
|
+
function peg$f21(k, v) {
|
|
281
278
|
return { key: k, value: v };
|
|
282
279
|
}
|
|
283
|
-
function peg$
|
|
280
|
+
function peg$f22(head, chain, attrs) {
|
|
284
281
|
if (chain.length > 0) {
|
|
285
282
|
const nodes = [head].concat(chain);
|
|
286
283
|
return { type: "edge", nodes, attrs };
|
|
@@ -291,70 +288,70 @@ function peg$parse(input, options) {
|
|
|
291
288
|
return { type: "node", id: head, attrs };
|
|
292
289
|
}
|
|
293
290
|
}
|
|
294
|
-
function peg$
|
|
291
|
+
function peg$f23(s) {
|
|
295
292
|
return s;
|
|
296
293
|
}
|
|
297
|
-
function peg$
|
|
294
|
+
function peg$f24(n) {
|
|
298
295
|
return n;
|
|
299
296
|
}
|
|
300
|
-
function peg$
|
|
297
|
+
function peg$f25(id, port, compass) {
|
|
301
298
|
return { id, port, compass };
|
|
302
299
|
}
|
|
303
|
-
function peg$
|
|
300
|
+
function peg$f26(id, port) {
|
|
304
301
|
return { id, port, compass: null };
|
|
305
302
|
}
|
|
306
|
-
function peg$
|
|
303
|
+
function peg$f27(id) {
|
|
307
304
|
return { id, port: null, compass: null };
|
|
308
305
|
}
|
|
309
|
-
function peg$
|
|
306
|
+
function peg$f28(s, rest) {
|
|
310
307
|
return [s].concat(rest);
|
|
311
308
|
}
|
|
312
|
-
function peg$
|
|
309
|
+
function peg$f29() {
|
|
313
310
|
return [];
|
|
314
311
|
}
|
|
315
|
-
function peg$
|
|
312
|
+
function peg$f30(id, stmts) {
|
|
316
313
|
return { type: "subgraph", id, stmts };
|
|
317
314
|
}
|
|
318
|
-
function peg$
|
|
315
|
+
function peg$f31(stmts) {
|
|
319
316
|
return { type: "subgraph", id: null, stmts };
|
|
320
317
|
}
|
|
321
|
-
function peg$
|
|
318
|
+
function peg$f32(stmts) {
|
|
322
319
|
return { type: "subgraph", id: null, stmts };
|
|
323
320
|
}
|
|
324
|
-
function peg$
|
|
321
|
+
function peg$f33(first, s) {
|
|
325
322
|
return s;
|
|
326
323
|
}
|
|
327
|
-
function peg$
|
|
324
|
+
function peg$f34(first, rest) {
|
|
328
325
|
return rest.length > 0 ? first + rest.join("") : first;
|
|
329
326
|
}
|
|
330
|
-
function peg$
|
|
327
|
+
function peg$f35(chars) {
|
|
331
328
|
return chars.join("");
|
|
332
329
|
}
|
|
333
|
-
function peg$
|
|
330
|
+
function peg$f36() {
|
|
334
331
|
return '"';
|
|
335
332
|
}
|
|
336
|
-
function peg$
|
|
333
|
+
function peg$f37() {
|
|
337
334
|
return "";
|
|
338
335
|
}
|
|
339
|
-
function peg$
|
|
336
|
+
function peg$f38(c) {
|
|
340
337
|
return "\\" + c;
|
|
341
338
|
}
|
|
342
|
-
function peg$
|
|
339
|
+
function peg$f39(content) {
|
|
343
340
|
return "" + content;
|
|
344
341
|
}
|
|
345
|
-
function peg$
|
|
342
|
+
function peg$f40(chars) {
|
|
346
343
|
return chars.join("");
|
|
347
344
|
}
|
|
348
|
-
function peg$
|
|
345
|
+
function peg$f41(nested2, content) {
|
|
349
346
|
return "<" + content + ">";
|
|
350
347
|
}
|
|
351
|
-
function peg$
|
|
348
|
+
function peg$f42(n) {
|
|
352
349
|
return n;
|
|
353
350
|
}
|
|
354
|
-
function peg$
|
|
351
|
+
function peg$f43(first, rest) {
|
|
355
352
|
return first + rest.join("");
|
|
356
353
|
}
|
|
357
|
-
function peg$
|
|
354
|
+
function peg$f44(s) {
|
|
358
355
|
return Array.isArray(s) ? s.flat(Infinity).filter((x) => x !== null && x !== void 0).join("") : String(s);
|
|
359
356
|
}
|
|
360
357
|
let peg$currPos = options.peg$currPos | 0;
|
|
@@ -730,7 +727,7 @@ function peg$parse(input, options) {
|
|
|
730
727
|
s12 = peg$parseAttrType();
|
|
731
728
|
if (s12 !== peg$FAILED) {
|
|
732
729
|
s2 = peg$parse_();
|
|
733
|
-
s3 = peg$
|
|
730
|
+
s3 = peg$parseAttrListReq();
|
|
734
731
|
if (s3 !== peg$FAILED) {
|
|
735
732
|
peg$savedPos = s0;
|
|
736
733
|
s0 = peg$f12(s12, s3);
|
|
@@ -782,7 +779,7 @@ function peg$parse(input, options) {
|
|
|
782
779
|
}
|
|
783
780
|
return s0;
|
|
784
781
|
}
|
|
785
|
-
function peg$
|
|
782
|
+
function peg$parseAttrListReq() {
|
|
786
783
|
let s0, s12, s2, s3, s4, s5, s6, s7;
|
|
787
784
|
s0 = peg$currPos;
|
|
788
785
|
s12 = peg$parse_();
|
|
@@ -825,49 +822,17 @@ function peg$parse(input, options) {
|
|
|
825
822
|
peg$currPos = s0;
|
|
826
823
|
s0 = peg$FAILED;
|
|
827
824
|
}
|
|
825
|
+
return s0;
|
|
826
|
+
}
|
|
827
|
+
function peg$parseAttrList() {
|
|
828
|
+
let s0, s12;
|
|
829
|
+
s0 = peg$parseAttrListReq();
|
|
828
830
|
if (s0 === peg$FAILED) {
|
|
829
831
|
s0 = peg$currPos;
|
|
830
|
-
s12 =
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
} else {
|
|
835
|
-
s2 = peg$FAILED;
|
|
836
|
-
if (peg$silentFails === 0) {
|
|
837
|
-
peg$fail(peg$e3);
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
if (s2 !== peg$FAILED) {
|
|
841
|
-
s3 = peg$parse_();
|
|
842
|
-
s4 = peg$parseAttrDefs();
|
|
843
|
-
s5 = peg$parse_();
|
|
844
|
-
if (input.charCodeAt(peg$currPos) === 93) {
|
|
845
|
-
s6 = peg$c4;
|
|
846
|
-
peg$currPos++;
|
|
847
|
-
} else {
|
|
848
|
-
s6 = peg$FAILED;
|
|
849
|
-
if (peg$silentFails === 0) {
|
|
850
|
-
peg$fail(peg$e4);
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
if (s6 !== peg$FAILED) {
|
|
854
|
-
peg$savedPos = s0;
|
|
855
|
-
s0 = peg$f18(s4);
|
|
856
|
-
} else {
|
|
857
|
-
peg$currPos = s0;
|
|
858
|
-
s0 = peg$FAILED;
|
|
859
|
-
}
|
|
860
|
-
} else {
|
|
861
|
-
peg$currPos = s0;
|
|
862
|
-
s0 = peg$FAILED;
|
|
863
|
-
}
|
|
864
|
-
if (s0 === peg$FAILED) {
|
|
865
|
-
s0 = peg$currPos;
|
|
866
|
-
s12 = "";
|
|
867
|
-
peg$savedPos = s0;
|
|
868
|
-
s12 = peg$f19();
|
|
869
|
-
s0 = s12;
|
|
870
|
-
}
|
|
832
|
+
s12 = "";
|
|
833
|
+
peg$savedPos = s0;
|
|
834
|
+
s12 = peg$f18();
|
|
835
|
+
s0 = s12;
|
|
871
836
|
}
|
|
872
837
|
return s0;
|
|
873
838
|
}
|
|
@@ -901,7 +866,7 @@ function peg$parse(input, options) {
|
|
|
901
866
|
s5 = null;
|
|
902
867
|
}
|
|
903
868
|
peg$savedPos = s2;
|
|
904
|
-
s2 = peg$
|
|
869
|
+
s2 = peg$f19(s3);
|
|
905
870
|
} else {
|
|
906
871
|
peg$currPos = s2;
|
|
907
872
|
s2 = peg$FAILED;
|
|
@@ -934,14 +899,14 @@ function peg$parse(input, options) {
|
|
|
934
899
|
s5 = null;
|
|
935
900
|
}
|
|
936
901
|
peg$savedPos = s2;
|
|
937
|
-
s2 = peg$
|
|
902
|
+
s2 = peg$f19(s3);
|
|
938
903
|
} else {
|
|
939
904
|
peg$currPos = s2;
|
|
940
905
|
s2 = peg$FAILED;
|
|
941
906
|
}
|
|
942
907
|
}
|
|
943
908
|
peg$savedPos = s0;
|
|
944
|
-
s12 = peg$
|
|
909
|
+
s12 = peg$f20(s12);
|
|
945
910
|
s0 = s12;
|
|
946
911
|
return s0;
|
|
947
912
|
}
|
|
@@ -965,7 +930,7 @@ function peg$parse(input, options) {
|
|
|
965
930
|
s5 = peg$parseAtom();
|
|
966
931
|
if (s5 !== peg$FAILED) {
|
|
967
932
|
peg$savedPos = s0;
|
|
968
|
-
s0 = peg$
|
|
933
|
+
s0 = peg$f21(s12, s5);
|
|
969
934
|
} else {
|
|
970
935
|
peg$currPos = s0;
|
|
971
936
|
s0 = peg$FAILED;
|
|
@@ -992,7 +957,7 @@ function peg$parse(input, options) {
|
|
|
992
957
|
s5 = peg$parseAttrList();
|
|
993
958
|
if (s5 !== peg$FAILED) {
|
|
994
959
|
peg$savedPos = s0;
|
|
995
|
-
s0 = peg$
|
|
960
|
+
s0 = peg$f22(s12, s3, s5);
|
|
996
961
|
} else {
|
|
997
962
|
peg$currPos = s0;
|
|
998
963
|
s0 = peg$FAILED;
|
|
@@ -1013,7 +978,7 @@ function peg$parse(input, options) {
|
|
|
1013
978
|
s12 = peg$parseSubgraph();
|
|
1014
979
|
if (s12 !== peg$FAILED) {
|
|
1015
980
|
peg$savedPos = s0;
|
|
1016
|
-
s12 = peg$
|
|
981
|
+
s12 = peg$f23(s12);
|
|
1017
982
|
}
|
|
1018
983
|
s0 = s12;
|
|
1019
984
|
if (s0 === peg$FAILED) {
|
|
@@ -1021,7 +986,7 @@ function peg$parse(input, options) {
|
|
|
1021
986
|
s12 = peg$parseNode();
|
|
1022
987
|
if (s12 !== peg$FAILED) {
|
|
1023
988
|
peg$savedPos = s0;
|
|
1024
|
-
s12 = peg$
|
|
989
|
+
s12 = peg$f24(s12);
|
|
1025
990
|
}
|
|
1026
991
|
s0 = s12;
|
|
1027
992
|
}
|
|
@@ -1061,7 +1026,7 @@ function peg$parse(input, options) {
|
|
|
1061
1026
|
s9 = peg$parseAtom();
|
|
1062
1027
|
if (s9 !== peg$FAILED) {
|
|
1063
1028
|
peg$savedPos = s0;
|
|
1064
|
-
s0 = peg$
|
|
1029
|
+
s0 = peg$f25(s12, s5, s9);
|
|
1065
1030
|
} else {
|
|
1066
1031
|
peg$currPos = s0;
|
|
1067
1032
|
s0 = peg$FAILED;
|
|
@@ -1101,7 +1066,7 @@ function peg$parse(input, options) {
|
|
|
1101
1066
|
s5 = peg$parseAtom();
|
|
1102
1067
|
if (s5 !== peg$FAILED) {
|
|
1103
1068
|
peg$savedPos = s0;
|
|
1104
|
-
s0 = peg$
|
|
1069
|
+
s0 = peg$f26(s12, s5);
|
|
1105
1070
|
} else {
|
|
1106
1071
|
peg$currPos = s0;
|
|
1107
1072
|
s0 = peg$FAILED;
|
|
@@ -1119,7 +1084,7 @@ function peg$parse(input, options) {
|
|
|
1119
1084
|
s12 = peg$parseAtom();
|
|
1120
1085
|
if (s12 !== peg$FAILED) {
|
|
1121
1086
|
peg$savedPos = s0;
|
|
1122
|
-
s12 = peg$
|
|
1087
|
+
s12 = peg$f27(s12);
|
|
1123
1088
|
}
|
|
1124
1089
|
s0 = s12;
|
|
1125
1090
|
}
|
|
@@ -1138,7 +1103,7 @@ function peg$parse(input, options) {
|
|
|
1138
1103
|
s5 = peg$parseEdgeChain();
|
|
1139
1104
|
if (s5 !== peg$FAILED) {
|
|
1140
1105
|
peg$savedPos = s0;
|
|
1141
|
-
s0 = peg$
|
|
1106
|
+
s0 = peg$f28(s3, s5);
|
|
1142
1107
|
} else {
|
|
1143
1108
|
peg$currPos = s0;
|
|
1144
1109
|
s0 = peg$FAILED;
|
|
@@ -1155,7 +1120,7 @@ function peg$parse(input, options) {
|
|
|
1155
1120
|
s0 = peg$currPos;
|
|
1156
1121
|
s12 = "";
|
|
1157
1122
|
peg$savedPos = s0;
|
|
1158
|
-
s12 = peg$
|
|
1123
|
+
s12 = peg$f29();
|
|
1159
1124
|
s0 = s12;
|
|
1160
1125
|
}
|
|
1161
1126
|
return s0;
|
|
@@ -1226,7 +1191,7 @@ function peg$parse(input, options) {
|
|
|
1226
1191
|
}
|
|
1227
1192
|
if (s9 !== peg$FAILED) {
|
|
1228
1193
|
peg$savedPos = s0;
|
|
1229
|
-
s0 = peg$
|
|
1194
|
+
s0 = peg$f30(s3, s7);
|
|
1230
1195
|
} else {
|
|
1231
1196
|
peg$currPos = s0;
|
|
1232
1197
|
s0 = peg$FAILED;
|
|
@@ -1277,7 +1242,7 @@ function peg$parse(input, options) {
|
|
|
1277
1242
|
}
|
|
1278
1243
|
if (s7 !== peg$FAILED) {
|
|
1279
1244
|
peg$savedPos = s0;
|
|
1280
|
-
s0 = peg$
|
|
1245
|
+
s0 = peg$f31(s5);
|
|
1281
1246
|
} else {
|
|
1282
1247
|
peg$currPos = s0;
|
|
1283
1248
|
s0 = peg$FAILED;
|
|
@@ -1321,7 +1286,7 @@ function peg$parse(input, options) {
|
|
|
1321
1286
|
}
|
|
1322
1287
|
if (s5 !== peg$FAILED) {
|
|
1323
1288
|
peg$savedPos = s0;
|
|
1324
|
-
s0 = peg$
|
|
1289
|
+
s0 = peg$f32(s3);
|
|
1325
1290
|
} else {
|
|
1326
1291
|
peg$currPos = s0;
|
|
1327
1292
|
s0 = peg$FAILED;
|
|
@@ -1360,7 +1325,7 @@ function peg$parse(input, options) {
|
|
|
1360
1325
|
s7 = peg$parseQAtom();
|
|
1361
1326
|
if (s7 !== peg$FAILED) {
|
|
1362
1327
|
peg$savedPos = s3;
|
|
1363
|
-
s3 = peg$
|
|
1328
|
+
s3 = peg$f33(s12, s7);
|
|
1364
1329
|
} else {
|
|
1365
1330
|
peg$currPos = s3;
|
|
1366
1331
|
s3 = peg$FAILED;
|
|
@@ -1387,7 +1352,7 @@ function peg$parse(input, options) {
|
|
|
1387
1352
|
s7 = peg$parseQAtom();
|
|
1388
1353
|
if (s7 !== peg$FAILED) {
|
|
1389
1354
|
peg$savedPos = s3;
|
|
1390
|
-
s3 = peg$
|
|
1355
|
+
s3 = peg$f33(s12, s7);
|
|
1391
1356
|
} else {
|
|
1392
1357
|
peg$currPos = s3;
|
|
1393
1358
|
s3 = peg$FAILED;
|
|
@@ -1398,7 +1363,7 @@ function peg$parse(input, options) {
|
|
|
1398
1363
|
}
|
|
1399
1364
|
}
|
|
1400
1365
|
peg$savedPos = s0;
|
|
1401
|
-
s0 = peg$
|
|
1366
|
+
s0 = peg$f34(s12, s2);
|
|
1402
1367
|
} else {
|
|
1403
1368
|
peg$currPos = s0;
|
|
1404
1369
|
s0 = peg$FAILED;
|
|
@@ -1446,7 +1411,7 @@ function peg$parse(input, options) {
|
|
|
1446
1411
|
}
|
|
1447
1412
|
if (s3 !== peg$FAILED) {
|
|
1448
1413
|
peg$savedPos = s0;
|
|
1449
|
-
s0 = peg$
|
|
1414
|
+
s0 = peg$f35(s2);
|
|
1450
1415
|
} else {
|
|
1451
1416
|
peg$currPos = s0;
|
|
1452
1417
|
s0 = peg$FAILED;
|
|
@@ -1471,7 +1436,7 @@ function peg$parse(input, options) {
|
|
|
1471
1436
|
}
|
|
1472
1437
|
if (s12 !== peg$FAILED) {
|
|
1473
1438
|
peg$savedPos = s0;
|
|
1474
|
-
s12 = peg$
|
|
1439
|
+
s12 = peg$f36();
|
|
1475
1440
|
}
|
|
1476
1441
|
s0 = s12;
|
|
1477
1442
|
if (s0 === peg$FAILED) {
|
|
@@ -1487,7 +1452,7 @@ function peg$parse(input, options) {
|
|
|
1487
1452
|
}
|
|
1488
1453
|
if (s12 !== peg$FAILED) {
|
|
1489
1454
|
peg$savedPos = s0;
|
|
1490
|
-
s12 = peg$
|
|
1455
|
+
s12 = peg$f37();
|
|
1491
1456
|
}
|
|
1492
1457
|
s0 = s12;
|
|
1493
1458
|
if (s0 === peg$FAILED) {
|
|
@@ -1513,7 +1478,7 @@ function peg$parse(input, options) {
|
|
|
1513
1478
|
}
|
|
1514
1479
|
if (s2 !== peg$FAILED) {
|
|
1515
1480
|
peg$savedPos = s0;
|
|
1516
|
-
s0 = peg$
|
|
1481
|
+
s0 = peg$f38(s2);
|
|
1517
1482
|
} else {
|
|
1518
1483
|
peg$currPos = s0;
|
|
1519
1484
|
s0 = peg$FAILED;
|
|
@@ -1562,7 +1527,7 @@ function peg$parse(input, options) {
|
|
|
1562
1527
|
}
|
|
1563
1528
|
if (s3 !== peg$FAILED) {
|
|
1564
1529
|
peg$savedPos = s0;
|
|
1565
|
-
s0 = peg$
|
|
1530
|
+
s0 = peg$f39(s2);
|
|
1566
1531
|
} else {
|
|
1567
1532
|
peg$currPos = s0;
|
|
1568
1533
|
s0 = peg$FAILED;
|
|
@@ -1583,7 +1548,7 @@ function peg$parse(input, options) {
|
|
|
1583
1548
|
s2 = peg$parseHtmlChar();
|
|
1584
1549
|
}
|
|
1585
1550
|
peg$savedPos = s0;
|
|
1586
|
-
s12 = peg$
|
|
1551
|
+
s12 = peg$f40(s12);
|
|
1587
1552
|
s0 = s12;
|
|
1588
1553
|
return s0;
|
|
1589
1554
|
}
|
|
@@ -1613,7 +1578,7 @@ function peg$parse(input, options) {
|
|
|
1613
1578
|
}
|
|
1614
1579
|
if (s3 !== peg$FAILED) {
|
|
1615
1580
|
peg$savedPos = s0;
|
|
1616
|
-
s0 = peg$
|
|
1581
|
+
s0 = peg$f41(s12, s2);
|
|
1617
1582
|
} else {
|
|
1618
1583
|
peg$currPos = s0;
|
|
1619
1584
|
s0 = peg$FAILED;
|
|
@@ -1658,7 +1623,7 @@ function peg$parse(input, options) {
|
|
|
1658
1623
|
s2 = peg$parseName();
|
|
1659
1624
|
if (s2 !== peg$FAILED) {
|
|
1660
1625
|
peg$savedPos = s0;
|
|
1661
|
-
s0 = peg$
|
|
1626
|
+
s0 = peg$f42(s2);
|
|
1662
1627
|
} else {
|
|
1663
1628
|
peg$currPos = s0;
|
|
1664
1629
|
s0 = peg$FAILED;
|
|
@@ -1706,7 +1671,7 @@ function peg$parse(input, options) {
|
|
|
1706
1671
|
}
|
|
1707
1672
|
}
|
|
1708
1673
|
peg$savedPos = s0;
|
|
1709
|
-
s0 = peg$
|
|
1674
|
+
s0 = peg$f43(s12, s2);
|
|
1710
1675
|
} else {
|
|
1711
1676
|
peg$currPos = s0;
|
|
1712
1677
|
s0 = peg$FAILED;
|
|
@@ -1927,7 +1892,7 @@ function peg$parse(input, options) {
|
|
|
1927
1892
|
}
|
|
1928
1893
|
if (s12 !== peg$FAILED) {
|
|
1929
1894
|
peg$savedPos = s0;
|
|
1930
|
-
s12 = peg$
|
|
1895
|
+
s12 = peg$f44(s12);
|
|
1931
1896
|
}
|
|
1932
1897
|
s0 = s12;
|
|
1933
1898
|
return s0;
|
|
@@ -29134,56 +29099,63 @@ function setEndTheta(P, e, merge) {
|
|
|
29134
29099
|
|
|
29135
29100
|
// src/pathplan/solvers.ts
|
|
29136
29101
|
var EPS2 = 1e-7;
|
|
29137
|
-
|
|
29138
|
-
|
|
29139
|
-
|
|
29140
|
-
|
|
29141
|
-
|
|
29142
|
-
|
|
29143
|
-
|
|
29144
|
-
|
|
29145
|
-
|
|
29146
|
-
|
|
29147
|
-
|
|
29148
|
-
|
|
29149
|
-
|
|
29150
|
-
|
|
29151
|
-
if (disc > 0) {
|
|
29152
|
-
r[0] = -b2a + Math.sqrt(disc);
|
|
29153
|
-
r[1] = -2 * b2a - r[0];
|
|
29154
|
-
return 2;
|
|
29155
|
-
}
|
|
29156
|
-
r[0] = -b2a;
|
|
29157
|
-
return 1;
|
|
29158
|
-
}
|
|
29159
|
-
static solve3neg(disc, q, b3a, r) {
|
|
29160
|
-
const rr = 0.5 * Math.sqrt(-disc + q * q);
|
|
29102
|
+
function aeq02(x) {
|
|
29103
|
+
return x < EPS2 && x > -EPS2;
|
|
29104
|
+
}
|
|
29105
|
+
function solve3(coeff, roots) {
|
|
29106
|
+
const a = coeff[3], b = coeff[2], c = coeff[1], d = coeff[0];
|
|
29107
|
+
if (aeq02(a)) return solve2(coeff, roots);
|
|
29108
|
+
const bOver3a = b / (3 * a), cOverA = c / a, dOverA = d / a;
|
|
29109
|
+
let p = bOver3a * bOver3a;
|
|
29110
|
+
const q = dOverA + fma(2 * bOver3a, p, -(bOver3a * cOverA));
|
|
29111
|
+
p = cOverA / 3 - p;
|
|
29112
|
+
const disc = fma(q, q, 4 * p * p * p);
|
|
29113
|
+
let rootn;
|
|
29114
|
+
if (disc < 0) {
|
|
29115
|
+
const r = 0.5 * Math.sqrt(fma(q, q, -disc));
|
|
29161
29116
|
const theta = Math.atan2(Math.sqrt(-disc), -q);
|
|
29162
|
-
const temp = 2 * Math.cbrt(
|
|
29163
|
-
|
|
29164
|
-
|
|
29165
|
-
|
|
29166
|
-
|
|
29117
|
+
const temp = 2 * Math.cbrt(r);
|
|
29118
|
+
roots[0] = temp * Math.cos(theta / 3);
|
|
29119
|
+
roots[1] = temp * Math.cos((theta + Math.PI + Math.PI) / 3);
|
|
29120
|
+
roots[2] = temp * Math.cos((theta - Math.PI - Math.PI) / 3);
|
|
29121
|
+
rootn = 3;
|
|
29122
|
+
} else {
|
|
29123
|
+
const alpha = 0.5 * (Math.sqrt(disc) - q);
|
|
29124
|
+
const beta = -q - alpha;
|
|
29125
|
+
roots[0] = Math.cbrt(alpha) + Math.cbrt(beta);
|
|
29126
|
+
if (disc > 0) rootn = 1;
|
|
29127
|
+
else {
|
|
29128
|
+
roots[1] = roots[2] = -0.5 * roots[0];
|
|
29129
|
+
rootn = 3;
|
|
29130
|
+
}
|
|
29167
29131
|
}
|
|
29168
|
-
|
|
29169
|
-
|
|
29170
|
-
|
|
29171
|
-
|
|
29172
|
-
|
|
29173
|
-
|
|
29132
|
+
for (let i = 0; i < rootn; i++) roots[i] -= bOver3a;
|
|
29133
|
+
return rootn;
|
|
29134
|
+
}
|
|
29135
|
+
function solve2(coeff, roots) {
|
|
29136
|
+
const a = coeff[2], b = coeff[1], c = coeff[0];
|
|
29137
|
+
if (aeq02(a)) return solve1(coeff, roots);
|
|
29138
|
+
const bOver2a = b / (2 * a);
|
|
29139
|
+
const cOverA = c / a;
|
|
29140
|
+
const disc = fma(bOver2a, bOver2a, -cOverA);
|
|
29141
|
+
if (disc < 0) {
|
|
29142
|
+
return 0;
|
|
29143
|
+
} else if (disc > 0) {
|
|
29144
|
+
roots[0] = -bOver2a + Math.sqrt(disc);
|
|
29145
|
+
roots[1] = fma(-2, bOver2a, -roots[0]);
|
|
29146
|
+
return 2;
|
|
29174
29147
|
}
|
|
29175
|
-
|
|
29176
|
-
|
|
29177
|
-
|
|
29178
|
-
|
|
29179
|
-
|
|
29180
|
-
|
|
29181
|
-
|
|
29182
|
-
return
|
|
29148
|
+
roots[0] = -bOver2a;
|
|
29149
|
+
return 1;
|
|
29150
|
+
}
|
|
29151
|
+
function solve1(coeff, roots) {
|
|
29152
|
+
const a = coeff[1], b = coeff[0];
|
|
29153
|
+
if (aeq02(a)) {
|
|
29154
|
+
if (aeq02(b)) return 4;
|
|
29155
|
+
return 0;
|
|
29183
29156
|
}
|
|
29184
|
-
|
|
29185
|
-
|
|
29186
|
-
return Solver.solve3(coeff, roots);
|
|
29157
|
+
roots[0] = -b / a;
|
|
29158
|
+
return 1;
|
|
29187
29159
|
}
|
|
29188
29160
|
|
|
29189
29161
|
// src/pathplan/route.ts
|
|
@@ -29205,16 +29177,19 @@ var RouteHelper = class _RouteHelper {
|
|
|
29205
29177
|
static B3(t) {
|
|
29206
29178
|
return t * t * t;
|
|
29207
29179
|
}
|
|
29180
|
+
/** @see lib/pathplan/route.c:B01 */
|
|
29208
29181
|
static B01(t) {
|
|
29209
29182
|
const u = 1 - t;
|
|
29210
|
-
return u * u * (
|
|
29183
|
+
return u * u * fma(3, t, u);
|
|
29211
29184
|
}
|
|
29185
|
+
/** @see lib/pathplan/route.c:B23 */
|
|
29212
29186
|
static B23(t) {
|
|
29213
29187
|
const u = 1 - t;
|
|
29214
|
-
return t * t * (3
|
|
29188
|
+
return t * t * fma(3, u, t);
|
|
29215
29189
|
}
|
|
29190
|
+
/** @see lib/pathplan/route.c:normv */
|
|
29216
29191
|
static normv(v) {
|
|
29217
|
-
const d = v.x
|
|
29192
|
+
const d = fma(v.x, v.x, v.y * v.y);
|
|
29218
29193
|
if (d > 1e-6) {
|
|
29219
29194
|
const s = Math.sqrt(d);
|
|
29220
29195
|
return { x: v.x / s, y: v.y / s };
|
|
@@ -29230,20 +29205,28 @@ var RouteHelper = class _RouteHelper {
|
|
|
29230
29205
|
static ptScale(p, c) {
|
|
29231
29206
|
return { x: p.x * c, y: p.y * c };
|
|
29232
29207
|
}
|
|
29208
|
+
/** @see lib/pathplan/route.c:dot */
|
|
29233
29209
|
static ptDot(a, b) {
|
|
29234
|
-
return a.x
|
|
29210
|
+
return fma(a.x, b.x, a.y * b.y);
|
|
29235
29211
|
}
|
|
29212
|
+
/** @see lib/pathplan/route.c:dist (libm hypot, no contraction) */
|
|
29236
29213
|
static ptDist(a, b) {
|
|
29237
|
-
return
|
|
29214
|
+
return libmHypot(a.x - b.x, a.y - b.y);
|
|
29238
29215
|
}
|
|
29239
29216
|
static distN(pts) {
|
|
29240
29217
|
let rv = 0;
|
|
29241
29218
|
for (let i = 1; i < pts.length; i++) rv += _RouteHelper.ptDist(pts[i], pts[i - 1]);
|
|
29242
29219
|
return rv;
|
|
29243
29220
|
}
|
|
29221
|
+
/**
|
|
29222
|
+
* The cubic's coefficients come out of catastrophic cancellation when the
|
|
29223
|
+
* spline is tangent to a barrier (tests/2646.dot), so clang's contraction
|
|
29224
|
+
* here decides solve3's root count; mirror it exactly.
|
|
29225
|
+
* @see lib/pathplan/route.c:points2coeff
|
|
29226
|
+
*/
|
|
29244
29227
|
static points2coeff(v0, v1, v2, v3, c) {
|
|
29245
|
-
c[3] =
|
|
29246
|
-
c[2] = 3
|
|
29228
|
+
c[3] = fma(3, v1, v3) - fma(3, v2, v0);
|
|
29229
|
+
c[2] = fma(-6, v1, fma(3, v0, 3 * v2));
|
|
29247
29230
|
c[1] = 3 * (v1 - v0);
|
|
29248
29231
|
c[0] = v0;
|
|
29249
29232
|
}
|
|
@@ -29283,7 +29266,7 @@ var RouteHelper = class _RouteHelper {
|
|
|
29283
29266
|
const tv = xr[i];
|
|
29284
29267
|
if (tv >= 0 && tv <= 1) {
|
|
29285
29268
|
_RouteHelper.points2coeff(sps[0].y, sps[1].y, sps[2].y, sps[3].y, sc);
|
|
29286
|
-
const sv = (
|
|
29269
|
+
const sv = (fma(tv, fma(tv, fma(tv, sc[3], sc[2]), sc[1]), sc[0]) - lc.yc0) / lc.yc1;
|
|
29287
29270
|
if (sv >= 0 && sv <= 1) _RouteHelper.addRoot(tv, acc);
|
|
29288
29271
|
}
|
|
29289
29272
|
}
|
|
@@ -29293,25 +29276,26 @@ var RouteHelper = class _RouteHelper {
|
|
|
29293
29276
|
const sc = [0, 0, 0, 0], xr = [0, 0, 0];
|
|
29294
29277
|
const rat = lc.yc1 / lc.xc1;
|
|
29295
29278
|
_RouteHelper.points2coeff(
|
|
29296
|
-
sps[0].
|
|
29297
|
-
sps[1].
|
|
29298
|
-
sps[2].
|
|
29299
|
-
sps[3].
|
|
29279
|
+
fms(rat, sps[0].x, sps[0].y),
|
|
29280
|
+
fms(rat, sps[1].x, sps[1].y),
|
|
29281
|
+
fms(rat, sps[2].x, sps[2].y),
|
|
29282
|
+
fms(rat, sps[3].x, sps[3].y),
|
|
29300
29283
|
sc
|
|
29301
29284
|
);
|
|
29302
|
-
sc[0] += rat
|
|
29285
|
+
sc[0] += fma(rat, lc.xc0, -lc.yc0);
|
|
29303
29286
|
const xn = solve3(sc, xr);
|
|
29304
29287
|
if (xn === 4) return 4;
|
|
29305
29288
|
for (let i = 0; i < xn; i++) {
|
|
29306
29289
|
const tv = xr[i];
|
|
29307
29290
|
if (tv >= 0 && tv <= 1) {
|
|
29308
29291
|
_RouteHelper.points2coeff(sps[0].x, sps[1].x, sps[2].x, sps[3].x, sc);
|
|
29309
|
-
const sv = (
|
|
29292
|
+
const sv = (fma(tv, fma(tv, fma(tv, sc[3], sc[2]), sc[1]), sc[0]) - lc.xc0) / lc.xc1;
|
|
29310
29293
|
if (sv >= 0 && sv <= 1) _RouteHelper.addRoot(tv, acc);
|
|
29311
29294
|
}
|
|
29312
29295
|
}
|
|
29313
29296
|
return acc.n;
|
|
29314
29297
|
}
|
|
29298
|
+
/** @see lib/pathplan/route.c:splineintersectsline */
|
|
29315
29299
|
static splineIntersectsLine(sps, lps, roots) {
|
|
29316
29300
|
const lc = {
|
|
29317
29301
|
xc0: lps[0].x,
|
|
@@ -29362,8 +29346,9 @@ var RouteHelper = class _RouteHelper {
|
|
|
29362
29346
|
x0 += _RouteHelper.ptDot(tnas[i].a[0], tmp);
|
|
29363
29347
|
x1 += _RouteHelper.ptDot(tnas[i].a[1], tmp);
|
|
29364
29348
|
}
|
|
29365
|
-
const det01 = c00
|
|
29366
|
-
const
|
|
29349
|
+
const det01 = fma(c00, c11, -(c01 * c01));
|
|
29350
|
+
const det0X = fma(c00, x1, -(c01 * x0));
|
|
29351
|
+
const detX1 = fma(x0, c11, -(x1 * c01));
|
|
29367
29352
|
if (Math.abs(det01) >= 1e-6) {
|
|
29368
29353
|
scale0 = detX1 / det01;
|
|
29369
29354
|
scale3 = det0X / det01;
|
|
@@ -29387,6 +29372,27 @@ var RouteHelper = class _RouteHelper {
|
|
|
29387
29372
|
}
|
|
29388
29373
|
return tnas;
|
|
29389
29374
|
}
|
|
29375
|
+
/**
|
|
29376
|
+
* The max-deviation split of `reallyroutespline` (route.c:130-143): the
|
|
29377
|
+
* interior polyline point farthest from the fitted bezier.
|
|
29378
|
+
*
|
|
29379
|
+
* Faithful contract. On a geometrically symmetric channel two interior
|
|
29380
|
+
* deviations tie to within an ulp, so the split point (and the whole
|
|
29381
|
+
* spline) is decided by C's exact arithmetic, which this mirrors bit for
|
|
29382
|
+
* bit against the native arm64 oracle:
|
|
29383
|
+
* - `dist` is libm `hypot` (route.c:448) -> `libmHypot` via `ptDist`;
|
|
29384
|
+
* - the test is C's strict `(d = dist(p, inps[i])) > maxd` (route.c:139),
|
|
29385
|
+
* so an exact tie keeps the first index;
|
|
29386
|
+
* - clang's default `-ffp-contract=on` fuses the bezier eval at
|
|
29387
|
+
* route.c:137-138 as `fma(B3,p2, fma(B2,cp2, fma(B0,p1, B1*cp1)))`; the
|
|
29388
|
+
* B0..B3 weights and cp1/cp2 (route.c:130-131) are not fused. Fusing the
|
|
29389
|
+
* other product first is NOT equivalent (flips pt-issue-23-w9 and 32).
|
|
29390
|
+
* C is therefore not translation-equivariant on such ties (the winner
|
|
29391
|
+
* depends on absolute-coordinate rounding), and neither is this port.
|
|
29392
|
+
* This supersedes the former tolerant tie-break (accepted divergence A3).
|
|
29393
|
+
* Contraction map: .agent-notes/pathplan-fma-contraction-map.md.
|
|
29394
|
+
* @see lib/pathplan/route.c:reallyroutespline
|
|
29395
|
+
*/
|
|
29390
29396
|
static findMaxDev(inps, tnas, ends) {
|
|
29391
29397
|
const { p0, v0, p1, v1 } = ends;
|
|
29392
29398
|
const cp1 = _RouteHelper.ptAdd(p0, _RouteHelper.ptScale(v0, 1 / 3));
|
|
@@ -29394,10 +29400,12 @@ var RouteHelper = class _RouteHelper {
|
|
|
29394
29400
|
let maxi = -1, maxd = -1;
|
|
29395
29401
|
for (let i = 1; i < inps.length - 1; i++) {
|
|
29396
29402
|
const t = tnas[i].t;
|
|
29397
|
-
const
|
|
29398
|
-
const
|
|
29403
|
+
const b0 = _RouteHelper.B0(t), b1 = _RouteHelper.B1(t);
|
|
29404
|
+
const b2 = _RouteHelper.B2(t), b3 = _RouteHelper.B3(t);
|
|
29405
|
+
const px = fma(b3, p1.x, fma(b2, cp2.x, fma(b0, p0.x, b1 * cp1.x)));
|
|
29406
|
+
const py = fma(b3, p1.y, fma(b2, cp2.y, fma(b0, p0.y, b1 * cp1.y)));
|
|
29399
29407
|
const d = _RouteHelper.ptDist({ x: px, y: py }, inps[i]);
|
|
29400
|
-
if (d > maxd
|
|
29408
|
+
if (d > maxd) {
|
|
29401
29409
|
maxd = d;
|
|
29402
29410
|
maxi = i;
|
|
29403
29411
|
}
|
|
@@ -33548,8 +33556,9 @@ function normalizeCopiedFlatSpline(orig, auxe) {
|
|
|
33548
33556
|
if (orig.info.spl === void 0) return;
|
|
33549
33557
|
if (swapEndsP(auxe) !== swapEndsP(orig)) swapEdgeSpline(orig);
|
|
33550
33558
|
}
|
|
33551
|
-
function makeFlatAdjEdges(g, edges, cnt,
|
|
33559
|
+
function makeFlatAdjEdges(g, edges, cnt, et) {
|
|
33552
33560
|
const aux = buildFlatAux(g, edges, cnt);
|
|
33561
|
+
aux.auxg.info.flags = aux.auxg.info.flags & ~15 | et & 15;
|
|
33553
33562
|
dotInitNodeEdge(aux.auxg);
|
|
33554
33563
|
dotRank(aux.auxg);
|
|
33555
33564
|
if (dotMincross(aux.auxg) !== 0) return 1;
|
|
@@ -33660,88 +33669,6 @@ function assembleFlatPath(P, tend, hend, mid) {
|
|
|
33660
33669
|
for (let i = hend.boxn - 1; i >= 0; i--) addBox(P, hend.boxes[i]);
|
|
33661
33670
|
}
|
|
33662
33671
|
|
|
33663
|
-
// src/layout/dot/splines-flat-multi.ts
|
|
33664
|
-
function portEq2(a, b) {
|
|
33665
|
-
if (!a.defined && !b.defined) return true;
|
|
33666
|
-
if (!a.defined || !b.defined) return false;
|
|
33667
|
-
return a.p.x === b.p.x && a.p.y === b.p.y;
|
|
33668
|
-
}
|
|
33669
|
-
function flatPortKey(e, lo) {
|
|
33670
|
-
return e.tail === lo ? { loP: e.info.tail_port, hiP: e.info.head_port } : { loP: e.info.head_port, hiP: e.info.tail_port };
|
|
33671
|
-
}
|
|
33672
|
-
function isNonAdjGroupable(x, g) {
|
|
33673
|
-
return x.info.spl === void 0 && x.tail.info.rank !== void 0 && x.tail.info.rank === x.head.info.rank && !isFlatAdjacent(g, x);
|
|
33674
|
-
}
|
|
33675
|
-
function samePortsAs(x, lo, key) {
|
|
33676
|
-
const k = flatPortKey(x, lo);
|
|
33677
|
-
return portEq2(k.loP, key.loP) && portEq2(k.hiP, key.hiP);
|
|
33678
|
-
}
|
|
33679
|
-
function collectNonAdjacentFlatGroup(e, g) {
|
|
33680
|
-
const u = e.tail, v = e.head;
|
|
33681
|
-
const lo = (u.info.order ?? 0) <= (v.info.order ?? 0) ? u : v;
|
|
33682
|
-
const key = flatPortKey(e, lo);
|
|
33683
|
-
const sharesPair = (x) => x.tail === u && x.head === v || x.tail === v && x.head === u;
|
|
33684
|
-
const group = g.edges.filter(
|
|
33685
|
-
(x) => sharesPair(x) && isNonAdjGroupable(x, g) && samePortsAs(x, lo, key) && x.info.label === e.info.label
|
|
33686
|
-
);
|
|
33687
|
-
group.sort((a, b) => Number(b.tail === lo) - Number(a.tail === lo) || a.seq - b.seq);
|
|
33688
|
-
return group;
|
|
33689
|
-
}
|
|
33690
|
-
function copyPathEnd(end) {
|
|
33691
|
-
return {
|
|
33692
|
-
...end,
|
|
33693
|
-
boxes: end.boxes.map((b) => ({ ll: { ...b.ll }, ur: { ...b.ur } }))
|
|
33694
|
-
};
|
|
33695
|
-
}
|
|
33696
|
-
function routeGroupEdge(e, i, c) {
|
|
33697
|
-
c.P.nbox = 0;
|
|
33698
|
-
const endStepX = (i + 1) * c.stepx;
|
|
33699
|
-
const endStepY = (i + 1) * c.stepy;
|
|
33700
|
-
const mid = c.bottom ? bottomBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy) : topBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy);
|
|
33701
|
-
assembleFlatPath(c.P, copyPathEnd(c.tend), copyPathEnd(c.hend), mid);
|
|
33702
|
-
const pts = routeSplines(c.P);
|
|
33703
|
-
if (pts === null || pts.length === 0) return false;
|
|
33704
|
-
if (e.tail !== c.leftNode) pts.reverse();
|
|
33705
|
-
clipAndInstall(e, e.head, pts, pts.length, { ...buildDotSinfo(), ignoreSwap: true });
|
|
33706
|
-
return true;
|
|
33707
|
-
}
|
|
33708
|
-
function routeFlatEdgeGroupFaithful(g, edges, cnt) {
|
|
33709
|
-
const lead = edges[0];
|
|
33710
|
-
if (g.info.rank === void 0 || lead.tail.info.rank === void 0 || lead.head.info.rank !== lead.tail.info.rank) return false;
|
|
33711
|
-
const tailIsLeft = (lead.tail.info.order ?? 0) <= (lead.head.info.order ?? 0);
|
|
33712
|
-
const leftNode = tailIsLeft ? lead.tail : lead.head;
|
|
33713
|
-
const rightNode = tailIsLeft ? lead.head : lead.tail;
|
|
33714
|
-
const sample = tailIsLeft ? lead : {
|
|
33715
|
-
...lead,
|
|
33716
|
-
tail: leftNode,
|
|
33717
|
-
head: rightNode,
|
|
33718
|
-
info: { ...lead.info, tail_port: lead.info.head_port, head_port: lead.info.tail_port }
|
|
33719
|
-
};
|
|
33720
|
-
const { bottom, side } = flatSide(sample);
|
|
33721
|
-
const ctx = flatBboxCtx(g);
|
|
33722
|
-
const ranksep = graphRanksep(g);
|
|
33723
|
-
const P = freshFlatPath();
|
|
33724
|
-
const tend = makeFlatEndBox({ ctx, P, e: sample, n: leftNode, side, ranksep, isBegin: true });
|
|
33725
|
-
const hend = makeFlatEndBox({ ctx, P, e: sample, n: rightNode, side, ranksep, isBegin: false });
|
|
33726
|
-
const stepx = (g.info.nodesep ?? 18) / (cnt + 1);
|
|
33727
|
-
const stepy = flatVspace(g, leftNode, !bottom) / (cnt + 1);
|
|
33728
|
-
const rc = {
|
|
33729
|
-
P,
|
|
33730
|
-
tend,
|
|
33731
|
-
hend,
|
|
33732
|
-
tlast: tend.boxes[tend.boxn - 1],
|
|
33733
|
-
hlast: hend.boxes[hend.boxn - 1],
|
|
33734
|
-
bottom,
|
|
33735
|
-
stepx,
|
|
33736
|
-
stepy,
|
|
33737
|
-
leftNode
|
|
33738
|
-
};
|
|
33739
|
-
for (let i = 0; i < cnt; i++) {
|
|
33740
|
-
if (!routeGroupEdge(edges[i], i, rc)) return false;
|
|
33741
|
-
}
|
|
33742
|
-
return true;
|
|
33743
|
-
}
|
|
33744
|
-
|
|
33745
33672
|
// src/layout/dot/splines-flat-labeled.ts
|
|
33746
33673
|
var LBL_SPACE = 6;
|
|
33747
33674
|
function findLabelNode(e) {
|
|
@@ -33996,6 +33923,93 @@ function makeAdjFlatNoPortEdge(g, e) {
|
|
|
33996
33923
|
return true;
|
|
33997
33924
|
}
|
|
33998
33925
|
|
|
33926
|
+
// src/layout/dot/splines-flat-multi.ts
|
|
33927
|
+
function portEq2(a, b) {
|
|
33928
|
+
if (!a.defined && !b.defined) return true;
|
|
33929
|
+
if (!a.defined || !b.defined) return false;
|
|
33930
|
+
return a.p.x === b.p.x && a.p.y === b.p.y;
|
|
33931
|
+
}
|
|
33932
|
+
function flatPortKey(e, lo) {
|
|
33933
|
+
return e.tail === lo ? { loP: e.info.tail_port, hiP: e.info.head_port } : { loP: e.info.head_port, hiP: e.info.tail_port };
|
|
33934
|
+
}
|
|
33935
|
+
function isNonAdjGroupable(x, g) {
|
|
33936
|
+
return x.info.spl === void 0 && x.tail.info.rank !== void 0 && x.tail.info.rank === x.head.info.rank && !isFlatAdjacent(g, x);
|
|
33937
|
+
}
|
|
33938
|
+
function samePortsAs(x, lo, key) {
|
|
33939
|
+
const k = flatPortKey(x, lo);
|
|
33940
|
+
return portEq2(k.loP, key.loP) && portEq2(k.hiP, key.hiP);
|
|
33941
|
+
}
|
|
33942
|
+
function collectNonAdjacentFlatGroup(e, g) {
|
|
33943
|
+
const u = e.tail, v = e.head;
|
|
33944
|
+
const lo = (u.info.order ?? 0) <= (v.info.order ?? 0) ? u : v;
|
|
33945
|
+
const key = flatPortKey(e, lo);
|
|
33946
|
+
const sharesPair = (x) => x.tail === u && x.head === v || x.tail === v && x.head === u;
|
|
33947
|
+
const group = g.edges.filter(
|
|
33948
|
+
(x) => sharesPair(x) && isNonAdjGroupable(x, g) && samePortsAs(x, lo, key) && x.info.label === e.info.label
|
|
33949
|
+
);
|
|
33950
|
+
group.sort((a, b) => Number(b.tail === lo) - Number(a.tail === lo) || a.seq - b.seq);
|
|
33951
|
+
return group;
|
|
33952
|
+
}
|
|
33953
|
+
function copyPathEnd(end) {
|
|
33954
|
+
return {
|
|
33955
|
+
...end,
|
|
33956
|
+
boxes: end.boxes.map((b) => ({ ll: { ...b.ll }, ur: { ...b.ur } }))
|
|
33957
|
+
};
|
|
33958
|
+
}
|
|
33959
|
+
function routeGroupEdge(e, i, c) {
|
|
33960
|
+
c.P.nbox = 0;
|
|
33961
|
+
const endStepX = (i + 1) * c.stepx;
|
|
33962
|
+
const endStepY = (i + 1) * c.stepy;
|
|
33963
|
+
const mid = c.bottom ? bottomBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy) : topBoxes(c.tlast, c.hlast, endStepX, endStepY, c.stepy);
|
|
33964
|
+
assembleFlatPath(c.P, copyPathEnd(c.tend), copyPathEnd(c.hend), mid);
|
|
33965
|
+
const pts = c.et === EDGETYPE_SPLINE ? routeSplines(c.P) : routePolylines(c.P);
|
|
33966
|
+
if (pts === null || pts.length === 0) return false;
|
|
33967
|
+
if (e.tail !== c.leftNode) pts.reverse();
|
|
33968
|
+
clipAndInstall(e, e.head, pts, pts.length, { ...buildDotSinfo(), ignoreSwap: true });
|
|
33969
|
+
return true;
|
|
33970
|
+
}
|
|
33971
|
+
function routeFlatEdgeGroupFaithful(g, edges, cnt, et) {
|
|
33972
|
+
const lead = edges[0];
|
|
33973
|
+
if (g.info.rank === void 0 || lead.tail.info.rank === void 0 || lead.head.info.rank !== lead.tail.info.rank) return false;
|
|
33974
|
+
if (et === EDGETYPE_LINE) {
|
|
33975
|
+
makeSimpleFlat(edges, et);
|
|
33976
|
+
return true;
|
|
33977
|
+
}
|
|
33978
|
+
const tailIsLeft = (lead.tail.info.order ?? 0) <= (lead.head.info.order ?? 0);
|
|
33979
|
+
const leftNode = tailIsLeft ? lead.tail : lead.head;
|
|
33980
|
+
const rightNode = tailIsLeft ? lead.head : lead.tail;
|
|
33981
|
+
const sample = tailIsLeft ? lead : {
|
|
33982
|
+
...lead,
|
|
33983
|
+
tail: leftNode,
|
|
33984
|
+
head: rightNode,
|
|
33985
|
+
info: { ...lead.info, tail_port: lead.info.head_port, head_port: lead.info.tail_port }
|
|
33986
|
+
};
|
|
33987
|
+
const { bottom, side } = flatSide(sample);
|
|
33988
|
+
const ctx = flatBboxCtx(g);
|
|
33989
|
+
const ranksep = graphRanksep(g);
|
|
33990
|
+
const P = freshFlatPath();
|
|
33991
|
+
const tend = makeFlatEndBox({ ctx, P, e: sample, n: leftNode, side, ranksep, isBegin: true });
|
|
33992
|
+
const hend = makeFlatEndBox({ ctx, P, e: sample, n: rightNode, side, ranksep, isBegin: false });
|
|
33993
|
+
const stepx = (g.info.nodesep ?? 18) / (cnt + 1);
|
|
33994
|
+
const stepy = flatVspace(g, leftNode, !bottom) / (cnt + 1);
|
|
33995
|
+
const rc = {
|
|
33996
|
+
P,
|
|
33997
|
+
tend,
|
|
33998
|
+
hend,
|
|
33999
|
+
tlast: tend.boxes[tend.boxn - 1],
|
|
34000
|
+
hlast: hend.boxes[hend.boxn - 1],
|
|
34001
|
+
bottom,
|
|
34002
|
+
et,
|
|
34003
|
+
stepx,
|
|
34004
|
+
stepy,
|
|
34005
|
+
leftNode
|
|
34006
|
+
};
|
|
34007
|
+
for (let i = 0; i < cnt; i++) {
|
|
34008
|
+
if (!routeGroupEdge(edges[i], i, rc)) return false;
|
|
34009
|
+
}
|
|
34010
|
+
return true;
|
|
34011
|
+
}
|
|
34012
|
+
|
|
33999
34013
|
// src/layout/dot/edge-route-boxes.ts
|
|
34000
34014
|
var FUDGE2 = 2;
|
|
34001
34015
|
function makeTailBox(nb, startPy) {
|
|
@@ -34295,7 +34309,10 @@ function isAdjacentPortFlat(e, g) {
|
|
|
34295
34309
|
return e.tail.info.rank !== void 0 && e.tail.info.rank === e.head.info.rank && isFlatAdjacent(g, e) && hasDefinedPort(e);
|
|
34296
34310
|
}
|
|
34297
34311
|
function isGroupableFlat(x, g) {
|
|
34298
|
-
return x.info.spl === void 0 &&
|
|
34312
|
+
return x.info.spl === void 0 && x.tail.info.rank !== void 0 && x.tail.info.rank === x.head.info.rank && isFlatAdjacent(g, x);
|
|
34313
|
+
}
|
|
34314
|
+
function joinsPortedFlatGroup(e, g) {
|
|
34315
|
+
return isAdjFlatCandidate(e) && isGroupableFlat(e, g) && collectAdjacentFlatGroup(e, g).some(hasDefinedPort);
|
|
34299
34316
|
}
|
|
34300
34317
|
function collectAdjacentFlatGroup(e, g) {
|
|
34301
34318
|
const u = e.tail, v = e.head;
|
|
@@ -34310,11 +34327,11 @@ function routeFaithfulSidePort(e, g) {
|
|
|
34310
34327
|
const sameRank = e.tail.info.rank !== void 0 && e.tail.info.rank === e.head.info.rank;
|
|
34311
34328
|
if (sameRank && isFlatAdjacent(g, e)) {
|
|
34312
34329
|
const group = collectAdjacentFlatGroup(e, g);
|
|
34313
|
-
return makeFlatAdjEdges(g, group, group.length,
|
|
34330
|
+
return makeFlatAdjEdges(g, group, group.length, edgeType(g)) === 0 && e.info.spl !== void 0;
|
|
34314
34331
|
}
|
|
34315
34332
|
if (sameRank) {
|
|
34316
34333
|
const group = collectNonAdjacentFlatGroup(e, g);
|
|
34317
|
-
return routeFlatEdgeGroupFaithful(g, group, group.length) && e.info.spl !== void 0;
|
|
34334
|
+
return routeFlatEdgeGroupFaithful(g, group, group.length, edgeType(g)) && e.info.spl !== void 0;
|
|
34318
34335
|
}
|
|
34319
34336
|
const pts = routeRegularEdgeFaithful(g, e);
|
|
34320
34337
|
if (pts === null) return false;
|
|
@@ -34335,11 +34352,12 @@ function isLostFlatAdjRecordEdge(g, e) {
|
|
|
34335
34352
|
function routeFlatEdge(e, g) {
|
|
34336
34353
|
if (isLostFlatAdjRecordEdge(g, e)) return true;
|
|
34337
34354
|
if (makeFlatLabeledEdge(g, e)) return true;
|
|
34355
|
+
if (joinsPortedFlatGroup(e, g) && routeFaithfulSidePort(e, g)) return true;
|
|
34338
34356
|
if (makeAdjFlatNoPortEdge(g, e)) return true;
|
|
34339
34357
|
if ((hasSidePort(e) || isAdjacentPortFlat(e, g)) && routeFaithfulSidePort(e, g)) return true;
|
|
34340
34358
|
if (e.tail.info.rank !== void 0 && e.tail.info.rank === e.head.info.rank && e.info.label === void 0 && !isFlatAdjacent(g, e)) {
|
|
34341
34359
|
const group = collectNonAdjacentFlatGroup(e, g);
|
|
34342
|
-
if (group.length > 0 && routeFlatEdgeGroupFaithful(g, group, group.length) && e.info.spl !== void 0) return true;
|
|
34360
|
+
if (group.length > 0 && routeFlatEdgeGroupFaithful(g, group, group.length, edgeType(g)) && e.info.spl !== void 0) return true;
|
|
34343
34361
|
}
|
|
34344
34362
|
return false;
|
|
34345
34363
|
}
|
|
@@ -36636,7 +36654,6 @@ function buildEdges(g, nodeArr, orthoNodes) {
|
|
|
36636
36654
|
const oes = outIndex.get(n);
|
|
36637
36655
|
if (oes === void 0) continue;
|
|
36638
36656
|
for (const e of oes) {
|
|
36639
|
-
if (e.tail === e.head) continue;
|
|
36640
36657
|
if (concentrate) {
|
|
36641
36658
|
const ti = e.tail.id;
|
|
36642
36659
|
const hi = e.head.id;
|
|
@@ -48189,11 +48206,11 @@ function addClusters(g) {
|
|
|
48189
48206
|
g.info.clust = clusters;
|
|
48190
48207
|
g.info.n_cluster = clusters.length;
|
|
48191
48208
|
}
|
|
48192
|
-
function layoutComponents(g, comps,
|
|
48209
|
+
function layoutComponents(g, comps, solve4, pinned) {
|
|
48193
48210
|
for (const gc of comps) {
|
|
48194
48211
|
setEdgeTypeFromAttr(gc, EDGETYPE_LINE);
|
|
48195
|
-
solveModel2(gc,
|
|
48196
|
-
maybeRemoveOverlap(gc,
|
|
48212
|
+
solveModel2(gc, solve4.mode, solve4.model);
|
|
48213
|
+
maybeRemoveOverlap(gc, solve4.am);
|
|
48197
48214
|
splineEdgesShifted(gc);
|
|
48198
48215
|
}
|
|
48199
48216
|
const pinfo = {
|