@willcgage/module-schematic 0.44.0 → 0.46.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.d.cts CHANGED
@@ -1067,6 +1067,11 @@ interface ModuleGeometryInput {
1067
1067
  * so endplate B lands at the end of the CHAINED boards rather than where a
1068
1068
  * single module-level geometry would have put it (#108). */
1069
1069
  sections?: SchematicSection[] | null;
1070
+ /** A balloon / return loop: the main runs out and turns back on itself, so the
1071
+ * module has ONE endplate (A). No far endplate B is derived — the chain closes
1072
+ * back near the throat, and a B there would just be a spurious plate on the
1073
+ * loop. An interchange endplate on the balloon is placed separately (#loop). */
1074
+ loop?: boolean;
1070
1075
  }
1071
1076
  /** Signed turn a module applies to the through track (CCW/left positive). */
1072
1077
  declare function geometryTurnDegrees(geometryType?: string | null, geometryDegrees?: number | null): number;
package/dist/index.d.ts CHANGED
@@ -1067,6 +1067,11 @@ interface ModuleGeometryInput {
1067
1067
  * so endplate B lands at the end of the CHAINED boards rather than where a
1068
1068
  * single module-level geometry would have put it (#108). */
1069
1069
  sections?: SchematicSection[] | null;
1070
+ /** A balloon / return loop: the main runs out and turns back on itself, so the
1071
+ * module has ONE endplate (A). No far endplate B is derived — the chain closes
1072
+ * back near the throat, and a B there would just be a spurious plate on the
1073
+ * loop. An interchange endplate on the balloon is placed separately (#loop). */
1074
+ loop?: boolean;
1070
1075
  }
1071
1076
  /** Signed turn a module applies to the through track (CCW/left positive). */
1072
1077
  declare function geometryTurnDegrees(geometryType?: string | null, geometryDegrees?: number | null): number;
package/dist/index.js CHANGED
@@ -1242,12 +1242,15 @@ function moduleFeatures(doc) {
1242
1242
  }));
1243
1243
  const branchConnectors = doc.endplates.filter(
1244
1244
  (e) => e.id !== "A" && e.id !== "B" && e.at && !!e.trackId && (doc.tracks ?? []).some((t) => t.id === e.trackId)
1245
- ).map((e) => ({
1246
- id: e.id,
1247
- label: e.label ?? e.id,
1248
- posFrac: clampFrac(e.at.pos),
1249
- side: e.at.side === "down" ? "down" : "up"
1250
- }));
1245
+ ).map((e) => {
1246
+ const sw = (doc.turnouts ?? []).find((t) => t.divergeTrack === e.trackId);
1247
+ return {
1248
+ id: e.id,
1249
+ label: e.label ?? e.id,
1250
+ posFrac: clampFrac(sw ? sw.pos : e.at.pos),
1251
+ side: e.at.side === "down" ? "down" : "up"
1252
+ };
1253
+ });
1251
1254
  const industries = (doc.industries ?? []).flatMap((ind) => {
1252
1255
  const spots = [
1253
1256
  { track: ind.track, fromPos: ind.fromPos, toPos: ind.toPos, side: ind.side },
@@ -1351,7 +1354,7 @@ function deriveEndplatePoses(geo) {
1351
1354
  trackOffsets: offsetsFor(cfg(0), half)
1352
1355
  })
1353
1356
  );
1354
- const noB = geo.geometryType === "dead_end";
1357
+ const noB = geo.geometryType === "dead_end" || geo.loop === true;
1355
1358
  const end = sectionedEndPose({ sections: geo.sections });
1356
1359
  if (!noB && end) {
1357
1360
  poses.push(