@willcgage/module-schematic 0.60.0 → 0.61.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 CHANGED
@@ -117,6 +117,15 @@ function samplePath(pts, segsPerArc = 20) {
117
117
  out.push({ x: pts[n - 1].x, y: pts[n - 1].y });
118
118
  return out;
119
119
  }
120
+ function pathLengthInches(path) {
121
+ const pts = trackPath(path);
122
+ if (!pts) return 0;
123
+ const poly = samplePath(pts);
124
+ let total = 0;
125
+ for (let i = 1; i < poly.length; i++)
126
+ total += Math.hypot(poly[i].x - poly[i - 1].x, poly[i].y - poly[i - 1].y);
127
+ return total;
128
+ }
120
129
  function trackPath(path) {
121
130
  const pts = (path ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
122
131
  x: p.x,
@@ -1682,15 +1691,43 @@ function moduleFeatures(doc) {
1682
1691
  laneA: trackLane.get(x.tracks?.[0] ?? "") ?? 0,
1683
1692
  laneB: trackLane.get(x.tracks?.[1] ?? "") ?? 1
1684
1693
  }));
1694
+ const main2Lane = trackLane.has(MAIN2_TRACK_ID) ? trackLane.get(MAIN2_TRACK_ID) : null;
1695
+ const baseLanes = [
1696
+ 0,
1697
+ main2Lane ?? (doubleMain ? 1 : 0),
1698
+ ...extraTracks.map((t) => t.lane),
1699
+ ...signals.map((s) => s.lane),
1700
+ ...crossings.flatMap((x) => [x.laneA, x.laneB]),
1701
+ ...crossovers.flatMap((x) => [x.fromLane, x.toLane])
1702
+ ];
1703
+ let upLane = Math.max(...baseLanes, 0);
1704
+ let downLane = Math.min(...baseLanes, 0);
1685
1705
  const branchConnectors = doc.endplates.filter(
1686
1706
  (e) => e.id !== "A" && e.id !== "B" && e.at && !!e.trackId && (doc.tracks ?? []).some((t) => t.id === e.trackId)
1687
1707
  ).map((e) => {
1708
+ const trk = (doc.tracks ?? []).find((t) => t.id === e.trackId);
1688
1709
  const sw = (doc.turnouts ?? []).find((t) => t.divergeTrack === e.trackId);
1710
+ const startPos = sw ? sw.pos : e.at.pos;
1711
+ const side = e.at.side === "down" ? "down" : "up";
1712
+ const lane = side === "down" ? --downLane : ++upLane;
1713
+ const runInches = pathLengthInches(trk.path) || Math.abs(e.at.pos - startPos) || FREEMO_ENDPLATE_WIDTH_MIN_INCHES;
1714
+ const toB = e.at.pos >= startPos;
1715
+ const fits = (p) => p >= 0 && p <= len;
1716
+ const ahead = startPos + runInches;
1717
+ const behind = startPos - runInches;
1718
+ const endPos = toB && fits(ahead) ? ahead : !toB && fits(behind) ? behind : fits(toB ? behind : ahead) ? toB ? behind : ahead : ahead;
1689
1719
  return {
1690
1720
  id: e.id,
1691
1721
  label: e.label ?? e.id,
1692
- posFrac: clampFrac(sw ? sw.pos : e.at.pos),
1693
- side: e.at.side === "down" ? "down" : "up"
1722
+ name: trk.trackName ?? "",
1723
+ trackId: trk.id,
1724
+ kind: e.kind === "main" ? "main" : "branch",
1725
+ posFrac: clampFrac(startPos),
1726
+ fromLane: sw ? trackLane.get(sw.onTrack) ?? 0 : 0,
1727
+ side,
1728
+ lane,
1729
+ endFrac: clampFrac(endPos),
1730
+ lengthInches: runInches
1694
1731
  };
1695
1732
  });
1696
1733
  const industries = (doc.industries ?? []).flatMap((ind) => {
@@ -1715,15 +1752,7 @@ function moduleFeatures(doc) {
1715
1752
  };
1716
1753
  });
1717
1754
  });
1718
- const main2Lane = trackLane.has(MAIN2_TRACK_ID) ? trackLane.get(MAIN2_TRACK_ID) : null;
1719
- const allLanes = [
1720
- 0,
1721
- main2Lane ?? (doubleMain ? 1 : 0),
1722
- ...extraTracks.map((t) => t.lane),
1723
- ...signals.map((s) => s.lane),
1724
- ...crossings.flatMap((x) => [x.laneA, x.laneB]),
1725
- ...crossovers.flatMap((x) => [x.fromLane, x.toLane])
1726
- ];
1755
+ const allLanes = [...baseLanes, ...branchConnectors.map((b) => b.lane)];
1727
1756
  const loop = isLoopDoc(doc);
1728
1757
  const main2 = doc.tracks.find((t) => t.id === MAIN2_TRACK_ID);
1729
1758
  const main2Positioned = !!main2 && (main2.fromPos != null || main2.toPos != null) && !loop;
@@ -2065,6 +2094,7 @@ exports.moduleSections = moduleSections;
2065
2094
  exports.nextId = nextId;
2066
2095
  exports.parseXtpLibrary = parseXtpLibrary;
2067
2096
  exports.partOutlineAtFrog = partOutlineAtFrog;
2097
+ exports.pathLengthInches = pathLengthInches;
2068
2098
  exports.poseNeedsManual = poseNeedsManual;
2069
2099
  exports.poseOverridesFromDoc = poseOverridesFromDoc;
2070
2100
  exports.remapPos = remapPos;