@willcgage/module-schematic 0.109.0 → 0.111.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 +70 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +70 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3149,8 +3149,12 @@ function graphToDoc(pieces, input) {
|
|
|
3149
3149
|
for (const t of tracks) {
|
|
3150
3150
|
if (t.role === "main") continue;
|
|
3151
3151
|
const ends = turnouts.filter((sw) => sw.divergeTrack === t.id);
|
|
3152
|
-
if (ends.length >= 2 && new Set(ends.map((sw) => sw.onTrack)).size >= 2)
|
|
3153
|
-
|
|
3152
|
+
if (!(ends.length >= 2 && new Set(ends.map((sw) => sw.onTrack)).size >= 2)) continue;
|
|
3153
|
+
t.role = "crossover";
|
|
3154
|
+
const at = ends.map((sw) => sw.pos);
|
|
3155
|
+
t.fromPos = round(Math.min(...at));
|
|
3156
|
+
t.toPos = round(Math.max(...at));
|
|
3157
|
+
t.lane = main2Lane || 1;
|
|
3154
3158
|
}
|
|
3155
3159
|
const place = (a, what) => {
|
|
3156
3160
|
if (!a) return null;
|
|
@@ -3417,7 +3421,12 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3417
3421
|
const ends = [branch?.fromPos, branch?.toPos].filter(
|
|
3418
3422
|
(n) => typeof n === "number" && Number.isFinite(n)
|
|
3419
3423
|
);
|
|
3420
|
-
const divergeFarPos =
|
|
3424
|
+
const divergeFarPos = (
|
|
3425
|
+
// ⭐ A crossover half diverges TOWARD its partner. Its diverging track is a
|
|
3426
|
+
// MAIN, whose ends are the whole module, so the ordinary rule has nothing
|
|
3427
|
+
// useful to sign and would point it away from the turnout it feeds.
|
|
3428
|
+
divergeFarOverride.get(t.id) ?? (ends.length ? ends.reduce((a, b) => Math.abs(b - t.pos) > Math.abs(a - t.pos) ? b : a) : void 0)
|
|
3429
|
+
);
|
|
3421
3430
|
const facing = turnoutFacing({
|
|
3422
3431
|
pos: t.pos,
|
|
3423
3432
|
divergeFarPos,
|
|
@@ -3534,6 +3543,7 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3534
3543
|
fromPos: a.x0,
|
|
3535
3544
|
toPos: a.x0 + a.geom.lengthInches
|
|
3536
3545
|
}));
|
|
3546
|
+
const mainIdsAll = new Set(mains.map((m) => m.id));
|
|
3537
3547
|
const attachment = /* @__PURE__ */ new Map();
|
|
3538
3548
|
for (const t of turnouts) {
|
|
3539
3549
|
const m = mains.find((x) => x.id === t.divergeTrack && x.id !== main.id);
|
|
@@ -3542,11 +3552,34 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3542
3552
|
const to = m.toPos ?? mainLen;
|
|
3543
3553
|
if (from > 0 && Math.abs(t.pos - from) < 0.01) attachment.set(m.id, { sw: t, at: "from" });
|
|
3544
3554
|
else if (Math.abs(t.pos - to) < 0.01) attachment.set(m.id, { sw: t, at: "to" });
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3555
|
+
}
|
|
3556
|
+
const mainToMainPairs = [];
|
|
3557
|
+
{
|
|
3558
|
+
const isMain = (id) => mainIdsAll.has(id);
|
|
3559
|
+
const used = /* @__PURE__ */ new Set();
|
|
3560
|
+
for (const t of turnouts) {
|
|
3561
|
+
if (used.has(t.id) || !isMain(t.onTrack) || !isMain(t.divergeTrack)) continue;
|
|
3562
|
+
if (t.onTrack === t.divergeTrack) continue;
|
|
3563
|
+
const partner = turnouts.filter(
|
|
3564
|
+
(u) => !used.has(u.id) && u.id !== t.id && u.onTrack === t.divergeTrack && u.divergeTrack === t.onTrack
|
|
3565
|
+
).sort((x, y) => Math.abs(x.pos - t.pos) - Math.abs(y.pos - t.pos))[0];
|
|
3566
|
+
if (!partner) continue;
|
|
3567
|
+
used.add(t.id);
|
|
3568
|
+
used.add(partner.id);
|
|
3569
|
+
mainToMainPairs.push({
|
|
3570
|
+
a: t,
|
|
3571
|
+
b: partner,
|
|
3572
|
+
pairKey: [t.onTrack, t.divergeTrack].sort().join("\u2194")
|
|
3549
3573
|
});
|
|
3574
|
+
}
|
|
3575
|
+
}
|
|
3576
|
+
const crossingsBetween = /* @__PURE__ */ new Map();
|
|
3577
|
+
for (const p of mainToMainPairs)
|
|
3578
|
+
crossingsBetween.set(p.pairKey, (crossingsBetween.get(p.pairKey) ?? 0) + 1);
|
|
3579
|
+
const divergeFarOverride = /* @__PURE__ */ new Map();
|
|
3580
|
+
for (const { a, b } of mainToMainPairs) {
|
|
3581
|
+
divergeFarOverride.set(a.id, b.pos);
|
|
3582
|
+
divergeFarOverride.set(b.id, a.pos);
|
|
3550
3583
|
}
|
|
3551
3584
|
for (const m of mains) {
|
|
3552
3585
|
if (attachment.get(m.id)?.at === "from") continue;
|
|
@@ -3601,6 +3634,36 @@ function docToGraph(doc, answers = {}, library = BUILT_IN_TRACK_PARTS) {
|
|
|
3601
3634
|
done.add(m.id);
|
|
3602
3635
|
}
|
|
3603
3636
|
for (const id of assemblyTracks) done.add(id);
|
|
3637
|
+
for (const [i, pair] of mainToMainPairs.entries()) {
|
|
3638
|
+
const la = laidTurnouts.get(pair.a.id);
|
|
3639
|
+
const lb = laidTurnouts.get(pair.b.id);
|
|
3640
|
+
if (!la || !lb) continue;
|
|
3641
|
+
const ja = jointAt(la.piece, la.divergeId);
|
|
3642
|
+
const jb = jointAt(lb.piece, lb.divergeId);
|
|
3643
|
+
if (!ja || !jb) continue;
|
|
3644
|
+
const dx = jb.x - ja.x;
|
|
3645
|
+
const dy = jb.y - ja.y;
|
|
3646
|
+
const len = Math.hypot(dx, dy);
|
|
3647
|
+
if (!(len > 1e-6)) {
|
|
3648
|
+
notLaid.push({
|
|
3649
|
+
id: pair.a.divergeTrack,
|
|
3650
|
+
why: `${pair.a.name || pair.a.id} and ${pair.b.name || pair.b.id} meet at the same point, so there is no track between them to lay`
|
|
3651
|
+
});
|
|
3652
|
+
continue;
|
|
3653
|
+
}
|
|
3654
|
+
pieces.push({
|
|
3655
|
+
id: `xc-${i}`,
|
|
3656
|
+
partId: flexId,
|
|
3657
|
+
x: ja.x,
|
|
3658
|
+
y: ja.y,
|
|
3659
|
+
rotationDeg: Math.atan2(dy, dx) * 180 / Math.PI,
|
|
3660
|
+
lengthInches: r3(len)
|
|
3661
|
+
});
|
|
3662
|
+
if ((crossingsBetween.get(pair.pairKey) ?? 1) > 1)
|
|
3663
|
+
warnings.push(
|
|
3664
|
+
`${pair.a.name || pair.a.id} and ${pair.b.name || pair.b.id} are two of four turnouts crossing between the same pair of mains \u2014 a double crossover. They are laid as separate turnouts with a ${len.toFixed(1)}\u2033 piece of track between them, which is what the document describes. If it is really a one-piece double crossover, name the product on a connector track and it will be laid as the single assembly it is.`
|
|
3665
|
+
);
|
|
3666
|
+
}
|
|
3604
3667
|
let progressed = true;
|
|
3605
3668
|
while (progressed) {
|
|
3606
3669
|
progressed = false;
|