@willcgage/module-schematic 0.92.0 → 0.93.0
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.cjs +71 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +70 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,8 @@ var FREEMO_ENDPLATE_WIDTH_MIN_INCHES = 12;
|
|
|
5
5
|
var FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = 24;
|
|
6
6
|
var FREEMO_TRACK_SPACING_INCHES = 1.125;
|
|
7
7
|
var FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES = 4;
|
|
8
|
+
var FREEMO_MAIN_MIN_RADIUS_INCHES = 22;
|
|
9
|
+
var FREEMO_REVERSE_CURVE_STRAIGHT_INCHES = 6;
|
|
8
10
|
var PINCH_EASE_INCHES = 3;
|
|
9
11
|
function laneOffsetAt(lane, pos, pinches, spacingInches = FREEMO_TRACK_SPACING_INCHES) {
|
|
10
12
|
const base = (lane ?? 0) * spacingInches;
|
|
@@ -2441,6 +2443,7 @@ function snapPiece(moving, others, library = BUILT_IN_TRACK_PARTS, withinInches
|
|
|
2441
2443
|
};
|
|
2442
2444
|
}
|
|
2443
2445
|
var danglingDivergeWarning = (id) => `the route diverging at ${id} is not connected to anything`;
|
|
2446
|
+
var unreachedWarning = (id) => `${id} is not reachable from the endplate \u2014 nothing connects it`;
|
|
2444
2447
|
function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS) {
|
|
2445
2448
|
const byKey = new Map(graph.joints.map((j) => [j.key, j]));
|
|
2446
2449
|
const pieceById = new Map(pieces.map((p) => [p.id, p]));
|
|
@@ -2578,11 +2581,14 @@ function walkTrackGraph(graph, pieces, startAt, library = BUILT_IN_TRACK_PARTS)
|
|
|
2578
2581
|
if (sw && !sw.divergeRoute) sw.divergeRoute = r.id;
|
|
2579
2582
|
}
|
|
2580
2583
|
const reached = new Set(routes.flatMap((r) => r.pieces));
|
|
2584
|
+
const unreached = [];
|
|
2581
2585
|
for (const p of pieces)
|
|
2582
|
-
if (!reached.has(p.id) && !graph.unplaceable.some((u) => u.piece === p.id))
|
|
2583
|
-
warnings.push(
|
|
2586
|
+
if (!reached.has(p.id) && !graph.unplaceable.some((u) => u.piece === p.id)) {
|
|
2587
|
+
warnings.push(unreachedWarning(p.id));
|
|
2588
|
+
unreached.push(p.id);
|
|
2589
|
+
}
|
|
2584
2590
|
for (const c of graph.conflicts) warnings.push(c.reason);
|
|
2585
|
-
return { routes, turnouts, warnings, danglingDiverges };
|
|
2591
|
+
return { routes, turnouts, warnings, danglingDiverges, unreached };
|
|
2586
2592
|
}
|
|
2587
2593
|
function resolveGraphAnchor(anchor, walk, pieces, library = BUILT_IN_TRACK_PARTS) {
|
|
2588
2594
|
const piece = pieces.find((p) => p.id === anchor.piece);
|
|
@@ -2611,14 +2617,29 @@ function graphToDoc(pieces, input) {
|
|
|
2611
2617
|
const epA = endplates[0];
|
|
2612
2618
|
const epB = endplates[1];
|
|
2613
2619
|
const main = walk.routes.find((r) => r.id === "main");
|
|
2614
|
-
const
|
|
2615
|
-
const
|
|
2620
|
+
const walk2 = input.start2 ? walkTrackGraph(graph, pieces, input.start2, library) : null;
|
|
2621
|
+
const main2 = walk2?.routes.find((r) => r.id === "main") ?? null;
|
|
2622
|
+
const claimed = new Set(walk.routes.flatMap((r) => r.pieces));
|
|
2623
|
+
if (main2 && main2.pieces.some((p) => claimed.has(p))) {
|
|
2624
|
+
warnings.push(
|
|
2625
|
+
"Main 2 starts on track that Main 1 already runs along \u2014 they are one run, not two"
|
|
2626
|
+
);
|
|
2627
|
+
}
|
|
2628
|
+
const twoMains = !!main2 && !main2.pieces.some((p) => claimed.has(p));
|
|
2629
|
+
const main2Lane = twoMains ? (graph.joints.find((j) => j.key === `${input.start2.piece}.${input.start2.joint}`)?.y ?? 1) >= 0 ? 1 : -1 : 0;
|
|
2630
|
+
const lengthInches = round(Math.max(main.toPos, twoMains ? main2.toPos : 0));
|
|
2631
|
+
const branches = [
|
|
2632
|
+
...walk.routes.filter((r) => r.id !== "main" && r.pieces.length),
|
|
2633
|
+
...twoMains ? walk2.routes.filter((r) => r.id !== "main" && r.pieces.length).map((r) => ({ ...r, id: `main2:${r.id}`, bornAt: r.bornAt })) : []
|
|
2634
|
+
];
|
|
2616
2635
|
const trackIdOf = /* @__PURE__ */ new Map([["main", MAIN_TRACK_ID]]);
|
|
2636
|
+
if (twoMains) trackIdOf.set("main2:main", MAIN2_TRACK_ID);
|
|
2617
2637
|
for (const r of branches) trackIdOf.set(r.id, r.pieces[0]);
|
|
2618
2638
|
const laneOf = (r) => {
|
|
2619
2639
|
const side = Math.sign(r.lateral) || 1;
|
|
2620
2640
|
const sameSide = branches.filter((x) => (Math.sign(x.lateral) || 1) === side).sort((a, b) => Math.abs(a.lateral) - Math.abs(b.lateral));
|
|
2621
|
-
|
|
2641
|
+
const taken = side === main2Lane ? 1 : 0;
|
|
2642
|
+
return side * (sameSide.indexOf(r) + 1 + taken);
|
|
2622
2643
|
};
|
|
2623
2644
|
const tracks = [
|
|
2624
2645
|
{
|
|
@@ -2627,7 +2648,20 @@ function graphToDoc(pieces, input) {
|
|
|
2627
2648
|
lane: 0,
|
|
2628
2649
|
from: epA?.id ?? "A",
|
|
2629
2650
|
...epB ? { to: epB.id } : {}
|
|
2630
|
-
}
|
|
2651
|
+
},
|
|
2652
|
+
...twoMains ? [
|
|
2653
|
+
{
|
|
2654
|
+
id: MAIN2_TRACK_ID,
|
|
2655
|
+
role: "main",
|
|
2656
|
+
lane: main2Lane,
|
|
2657
|
+
from: epA?.id ?? "A",
|
|
2658
|
+
...epB ? { to: epB.id } : {},
|
|
2659
|
+
// ⚠️ Its own extent, because a second main need not run the whole
|
|
2660
|
+
// module: on a transition module it starts or stops partway.
|
|
2661
|
+
fromPos: round(Math.min(main2.fromPos, main2.toPos)),
|
|
2662
|
+
toPos: round(Math.max(main2.fromPos, main2.toPos))
|
|
2663
|
+
}
|
|
2664
|
+
] : []
|
|
2631
2665
|
];
|
|
2632
2666
|
for (const r of branches) {
|
|
2633
2667
|
const id = trackIdOf.get(r.id);
|
|
@@ -2645,9 +2679,29 @@ function graphToDoc(pieces, input) {
|
|
|
2645
2679
|
...meta.moduleTrackId != null ? { moduleTrackId: meta.moduleTrackId } : {}
|
|
2646
2680
|
});
|
|
2647
2681
|
}
|
|
2682
|
+
if (walk2) {
|
|
2683
|
+
const seen = /* @__PURE__ */ new Set([
|
|
2684
|
+
...walk.routes.flatMap((r) => r.pieces),
|
|
2685
|
+
...walk2.routes.flatMap((r) => r.pieces)
|
|
2686
|
+
]);
|
|
2687
|
+
const covered = new Set([...walk.unreached, ...walk2.unreached].filter((id) => seen.has(id)));
|
|
2688
|
+
const drop = new Set([...covered].map(unreachedWarning));
|
|
2689
|
+
const d2 = new Set(walk2.danglingDiverges.map(danglingDivergeWarning));
|
|
2690
|
+
for (let i = warnings.length - 1; i >= 0; i--) if (drop.has(warnings[i])) warnings.splice(i, 1);
|
|
2691
|
+
for (const w of walk2.warnings)
|
|
2692
|
+
if (!d2.has(w) && !drop.has(w) && !warnings.includes(w)) warnings.push(w);
|
|
2693
|
+
}
|
|
2648
2694
|
const pieceById = new Map(pieces.map((p) => [p.id, p]));
|
|
2649
2695
|
const turnouts = [];
|
|
2650
|
-
|
|
2696
|
+
const allTurnouts = [
|
|
2697
|
+
...walk.turnouts,
|
|
2698
|
+
...twoMains ? walk2.turnouts.map((t) => ({
|
|
2699
|
+
...t,
|
|
2700
|
+
onRoute: t.onRoute === "main" ? "main2:main" : `main2:${t.onRoute}`,
|
|
2701
|
+
divergeRoute: t.divergeRoute ? `main2:${t.divergeRoute}` : null
|
|
2702
|
+
})) : []
|
|
2703
|
+
];
|
|
2704
|
+
for (const t of allTurnouts) {
|
|
2651
2705
|
const diverge = t.divergeRoute ? trackIdOf.get(t.divergeRoute) : void 0;
|
|
2652
2706
|
if (!diverge) {
|
|
2653
2707
|
warnings.push(
|
|
@@ -2729,7 +2783,13 @@ function deriveGraphDoc(doc, library = BUILT_IN_TRACK_PARTS) {
|
|
|
2729
2783
|
...t.moduleTrackId != null ? { moduleTrackId: t.moduleTrackId } : {}
|
|
2730
2784
|
};
|
|
2731
2785
|
}
|
|
2732
|
-
const out = graphToDoc(g.pieces, {
|
|
2786
|
+
const out = graphToDoc(g.pieces, {
|
|
2787
|
+
startAt: g.startAt,
|
|
2788
|
+
start2: g.start2 ?? null,
|
|
2789
|
+
base: doc,
|
|
2790
|
+
meta,
|
|
2791
|
+
library
|
|
2792
|
+
});
|
|
2733
2793
|
return { doc: out.doc, warnings: out.warnings };
|
|
2734
2794
|
}
|
|
2735
2795
|
function frogCasting(cl, opts = {}) {
|
|
@@ -3378,6 +3438,8 @@ exports.FLEX_TRACK_PARTS = FLEX_TRACK_PARTS;
|
|
|
3378
3438
|
exports.FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES = FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES;
|
|
3379
3439
|
exports.FREEMO_ENDPLATE_WIDTH_MIN_INCHES = FREEMO_ENDPLATE_WIDTH_MIN_INCHES;
|
|
3380
3440
|
exports.FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
3441
|
+
exports.FREEMO_MAIN_MIN_RADIUS_INCHES = FREEMO_MAIN_MIN_RADIUS_INCHES;
|
|
3442
|
+
exports.FREEMO_REVERSE_CURVE_STRAIGHT_INCHES = FREEMO_REVERSE_CURVE_STRAIGHT_INCHES;
|
|
3381
3443
|
exports.FREEMO_TRACK_SPACING_INCHES = FREEMO_TRACK_SPACING_INCHES;
|
|
3382
3444
|
exports.JOINT_SNAP_INCHES = JOINT_SNAP_INCHES;
|
|
3383
3445
|
exports.MAIN2_TRACK_ID = MAIN2_TRACK_ID;
|