@willcgage/module-schematic 0.18.0 → 0.19.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
@@ -78,6 +78,11 @@ interface SchematicTrack {
78
78
  * endplate A (past the throat = in the loop), lane is the ladder/arc index —
79
79
  * one record drives both the unrolled fan and a geometric render. */
80
80
  inLoop?: boolean;
81
+ /** Authored 2-D path for this track (module-local inches, open path with
82
+ * arcs) — the PHYSICAL shape a bent/rotated spur draws. Absent = derive from
83
+ * the main centre-line + lane, as before. Physical view only; the operations
84
+ * view stays positional (#2d-track). */
85
+ path?: BenchworkPoint[] | null;
81
86
  }
82
87
  interface SchematicTurnout {
83
88
  id: string;
@@ -195,6 +200,10 @@ interface ModuleSchematicDoc {
195
200
  outline?: BenchworkPoint[];
196
201
  /** @deprecated pre-grouping flat signals; read for back-compat. */
197
202
  signals?: SchematicSignal[];
203
+ /** Authored mainline centre-line (module-local inches, open path with arcs).
204
+ * Present = the owner drew the real shape; absent = derive from geometry.
205
+ * Physical view only — the operations view stays derived (#2d-track). */
206
+ mainPath?: BenchworkPoint[] | null;
198
207
  }
199
208
  /** A benchwork-outline vertex, module-local inches. The edge from this vertex
200
209
  * to the NEXT one is a straight line, unless `bulge` is set — then it's a
@@ -222,6 +231,19 @@ declare function sampleBenchworkOutline(pts: BenchworkPoint[], segsPerArc?: numb
222
231
  x: number;
223
232
  y: number;
224
233
  }[];
234
+ /**
235
+ * Expand an OPEN track path (whose edges may be arcs) into a dense polyline —
236
+ * the open-ended sibling of sampleBenchworkOutline (which closes the ring).
237
+ * Used for authored track centre-lines (a drawn mainline or spur). The final
238
+ * vertex is always emitted so the path reaches its end.
239
+ */
240
+ declare function samplePath(pts: BenchworkPoint[], segsPerArc?: number): {
241
+ x: number;
242
+ y: number;
243
+ }[];
244
+ /** Normalise an authored track path from a doc, or null if it isn't a real path
245
+ * (needs ≥ 2 valid points). Keeps per-vertex bulge. */
246
+ declare function trackPath(path: BenchworkPoint[] | null | undefined): BenchworkPoint[] | null;
225
247
  interface ModuleFootprintInput {
226
248
  /** Mainline length (falls back to footprint length), inches. */
227
249
  lengthInches: number;
@@ -232,6 +254,10 @@ interface ModuleFootprintInput {
232
254
  endplateWidths?: Record<string, number>;
233
255
  /** Authored benchwork outline (module-local inches), or absent for the band. */
234
256
  outline?: BenchworkPoint[] | null;
257
+ /** Authored mainline centre-line (module-local inches, open path with arcs).
258
+ * When present it wins over the geometry-derived centre-line — the owner drew
259
+ * the real shape (#2d-track, physical view only). */
260
+ mainPath?: BenchworkPoint[] | null;
235
261
  }
236
262
  interface OutlineFace {
237
263
  /** The endplate face's two corners + midpoint (the track point). */
@@ -249,7 +275,9 @@ interface ModuleFootprint {
249
275
  /** Authored outline (arc-sampled closed ring) or null → render the band. */
250
276
  outline: BenchworkPoint[] | null;
251
277
  }
252
- /** Module-local main track centre-line (A→B), sampling arcs for curves/corners. */
278
+ /** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
279
+ * An authored `mainPath` wins — the owner drew the real shape; otherwise the
280
+ * centre-line is derived from the geometry fields (length + type/degrees/offset). */
253
281
  declare function moduleCenterline(input: ModuleFootprintInput): BenchworkPoint[];
254
282
  /** Benchwork band: the centre-line offset ±half-width, tapering widthA→widthB. */
255
283
  declare function benchworkBand(center: BenchworkPoint[], widthA?: number, widthB?: number): BenchworkPoint[];
@@ -295,6 +323,9 @@ interface EditorTrack {
295
323
  trackName: string;
296
324
  /** Inside the balloon of a loop module (#165). */
297
325
  inLoop?: boolean;
326
+ /** Authored 2-D path (module-local inches) — a bent/rotated spur's real
327
+ * shape. Absent = derive from the main + lane (#2d-track). */
328
+ path?: BenchworkPoint[];
298
329
  }
299
330
  /** A module_tracks row as loaded for the editor. */
300
331
  interface ModuleTrackRow {
@@ -393,6 +424,9 @@ interface EditorState {
393
424
  controlPoints: EditorControlPoint[];
394
425
  /** Rail-served industries — car-spot spans on a track (#industries). */
395
426
  industries: EditorIndustry[];
427
+ /** Authored mainline centre-line (module-local inches) — empty = derive from
428
+ * geometry. The owner-drawn real shape (#2d-track, physical view only). */
429
+ mainPath: BenchworkPoint[];
396
430
  }
397
431
  /** Build the empty editor state for a module of the given length. */
398
432
  declare function emptyEditorState(lengthInches: number): EditorState;
@@ -671,4 +705,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
671
705
  heading: number;
672
706
  }>;
673
707
 
674
- export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
708
+ export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, stateToDoc, trackPath };
package/dist/index.d.ts CHANGED
@@ -78,6 +78,11 @@ interface SchematicTrack {
78
78
  * endplate A (past the throat = in the loop), lane is the ladder/arc index —
79
79
  * one record drives both the unrolled fan and a geometric render. */
80
80
  inLoop?: boolean;
81
+ /** Authored 2-D path for this track (module-local inches, open path with
82
+ * arcs) — the PHYSICAL shape a bent/rotated spur draws. Absent = derive from
83
+ * the main centre-line + lane, as before. Physical view only; the operations
84
+ * view stays positional (#2d-track). */
85
+ path?: BenchworkPoint[] | null;
81
86
  }
82
87
  interface SchematicTurnout {
83
88
  id: string;
@@ -195,6 +200,10 @@ interface ModuleSchematicDoc {
195
200
  outline?: BenchworkPoint[];
196
201
  /** @deprecated pre-grouping flat signals; read for back-compat. */
197
202
  signals?: SchematicSignal[];
203
+ /** Authored mainline centre-line (module-local inches, open path with arcs).
204
+ * Present = the owner drew the real shape; absent = derive from geometry.
205
+ * Physical view only — the operations view stays derived (#2d-track). */
206
+ mainPath?: BenchworkPoint[] | null;
198
207
  }
199
208
  /** A benchwork-outline vertex, module-local inches. The edge from this vertex
200
209
  * to the NEXT one is a straight line, unless `bulge` is set — then it's a
@@ -222,6 +231,19 @@ declare function sampleBenchworkOutline(pts: BenchworkPoint[], segsPerArc?: numb
222
231
  x: number;
223
232
  y: number;
224
233
  }[];
234
+ /**
235
+ * Expand an OPEN track path (whose edges may be arcs) into a dense polyline —
236
+ * the open-ended sibling of sampleBenchworkOutline (which closes the ring).
237
+ * Used for authored track centre-lines (a drawn mainline or spur). The final
238
+ * vertex is always emitted so the path reaches its end.
239
+ */
240
+ declare function samplePath(pts: BenchworkPoint[], segsPerArc?: number): {
241
+ x: number;
242
+ y: number;
243
+ }[];
244
+ /** Normalise an authored track path from a doc, or null if it isn't a real path
245
+ * (needs ≥ 2 valid points). Keeps per-vertex bulge. */
246
+ declare function trackPath(path: BenchworkPoint[] | null | undefined): BenchworkPoint[] | null;
225
247
  interface ModuleFootprintInput {
226
248
  /** Mainline length (falls back to footprint length), inches. */
227
249
  lengthInches: number;
@@ -232,6 +254,10 @@ interface ModuleFootprintInput {
232
254
  endplateWidths?: Record<string, number>;
233
255
  /** Authored benchwork outline (module-local inches), or absent for the band. */
234
256
  outline?: BenchworkPoint[] | null;
257
+ /** Authored mainline centre-line (module-local inches, open path with arcs).
258
+ * When present it wins over the geometry-derived centre-line — the owner drew
259
+ * the real shape (#2d-track, physical view only). */
260
+ mainPath?: BenchworkPoint[] | null;
235
261
  }
236
262
  interface OutlineFace {
237
263
  /** The endplate face's two corners + midpoint (the track point). */
@@ -249,7 +275,9 @@ interface ModuleFootprint {
249
275
  /** Authored outline (arc-sampled closed ring) or null → render the band. */
250
276
  outline: BenchworkPoint[] | null;
251
277
  }
252
- /** Module-local main track centre-line (A→B), sampling arcs for curves/corners. */
278
+ /** Module-local main track centre-line (A→B), sampling arcs for curves/corners.
279
+ * An authored `mainPath` wins — the owner drew the real shape; otherwise the
280
+ * centre-line is derived from the geometry fields (length + type/degrees/offset). */
253
281
  declare function moduleCenterline(input: ModuleFootprintInput): BenchworkPoint[];
254
282
  /** Benchwork band: the centre-line offset ±half-width, tapering widthA→widthB. */
255
283
  declare function benchworkBand(center: BenchworkPoint[], widthA?: number, widthB?: number): BenchworkPoint[];
@@ -295,6 +323,9 @@ interface EditorTrack {
295
323
  trackName: string;
296
324
  /** Inside the balloon of a loop module (#165). */
297
325
  inLoop?: boolean;
326
+ /** Authored 2-D path (module-local inches) — a bent/rotated spur's real
327
+ * shape. Absent = derive from the main + lane (#2d-track). */
328
+ path?: BenchworkPoint[];
298
329
  }
299
330
  /** A module_tracks row as loaded for the editor. */
300
331
  interface ModuleTrackRow {
@@ -393,6 +424,9 @@ interface EditorState {
393
424
  controlPoints: EditorControlPoint[];
394
425
  /** Rail-served industries — car-spot spans on a track (#industries). */
395
426
  industries: EditorIndustry[];
427
+ /** Authored mainline centre-line (module-local inches) — empty = derive from
428
+ * geometry. The owner-drawn real shape (#2d-track, physical view only). */
429
+ mainPath: BenchworkPoint[];
396
430
  }
397
431
  /** Build the empty editor state for a module of the given length. */
398
432
  declare function emptyEditorState(lengthInches: number): EditorState;
@@ -671,4 +705,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
671
705
  heading: number;
672
706
  }>;
673
707
 
674
- export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
708
+ export { type BenchworkPoint, type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, type IndustryLabelMode, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OutlineFace, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, stateToDoc, trackPath };
package/dist/index.js CHANGED
@@ -43,6 +43,45 @@ function sampleBenchworkOutline(pts, segsPerArc = 20) {
43
43
  }
44
44
  return out;
45
45
  }
46
+ function samplePath(pts, segsPerArc = 20) {
47
+ const n = pts.length;
48
+ if (n < 2) return pts.map((p) => ({ x: p.x, y: p.y }));
49
+ const out = [];
50
+ for (let i = 0; i < n - 1; i++) {
51
+ const p0 = pts[i];
52
+ const p1 = pts[i + 1];
53
+ out.push({ x: p0.x, y: p0.y });
54
+ const bulge = p0.bulge ?? 0;
55
+ if (!bulge) continue;
56
+ const dx = p1.x - p0.x;
57
+ const dy = p1.y - p0.y;
58
+ const c = Math.hypot(dx, dy);
59
+ if (c < 1e-6) continue;
60
+ const nx = -dy / c;
61
+ const ny = dx / c;
62
+ const mid = { x: (p0.x + p1.x) / 2 + nx * bulge, y: (p0.y + p1.y) / 2 + ny * bulge };
63
+ const circ = circleThrough(p0, mid, p1);
64
+ if (!circ) continue;
65
+ const a0 = Math.atan2(p0.y - circ.cy, p0.x - circ.cx);
66
+ const am = Math.atan2(mid.y - circ.cy, mid.x - circ.cx);
67
+ const a1 = Math.atan2(p1.y - circ.cy, p1.x - circ.cx);
68
+ const sweep = arcSweep(a0, a1, am);
69
+ for (let s = 1; s < segsPerArc; s++) {
70
+ const a = a0 + sweep * s / segsPerArc;
71
+ out.push({ x: circ.cx + circ.r * Math.cos(a), y: circ.cy + circ.r * Math.sin(a) });
72
+ }
73
+ }
74
+ out.push({ x: pts[n - 1].x, y: pts[n - 1].y });
75
+ return out;
76
+ }
77
+ function trackPath(path) {
78
+ const pts = (path ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
79
+ x: p.x,
80
+ y: p.y,
81
+ ...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
82
+ }));
83
+ return pts.length >= 2 ? pts : null;
84
+ }
46
85
  function circleThrough(a, b, c) {
47
86
  const d = 2 * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
48
87
  if (Math.abs(d) < 1e-9) return null;
@@ -65,6 +104,8 @@ function arcSweep(a0, a1, am) {
65
104
  }
66
105
  var DEG_FP = Math.PI / 180;
67
106
  function moduleCenterline(input) {
107
+ const drawn = trackPath(input.mainPath);
108
+ if (drawn) return samplePath(drawn);
68
109
  const L = input.lengthInches > 0 ? input.lengthInches : 24;
69
110
  const gt = input.geometryType;
70
111
  if (gt === "dead_end") return [{ x: 0, y: 0 }];
@@ -174,7 +215,8 @@ function emptyEditorState(lengthInches) {
174
215
  endplateWidths: {},
175
216
  outline: [],
176
217
  controlPoints: [],
177
- industries: []
218
+ industries: [],
219
+ mainPath: []
178
220
  };
179
221
  }
180
222
  function isTransitionTurnout(t) {
@@ -311,7 +353,8 @@ function stateToDoc(state, recordNumber) {
311
353
  moduleTrackId: t.moduleTrackId,
312
354
  trackName: t.trackName || void 0,
313
355
  capacityFeet: Math.round(inchesToScaleFeet(Math.abs(t.toPos - t.fromPos))),
314
- ...state.loop && t.inLoop ? { inLoop: true } : {}
356
+ ...state.loop && t.inLoop ? { inLoop: true } : {},
357
+ ...t.path && t.path.length >= 2 ? { path: t.path } : {}
315
358
  }))
316
359
  ],
317
360
  turnouts: state.turnouts.map((t) => ({
@@ -361,7 +404,9 @@ function stateToDoc(state, recordNumber) {
361
404
  } : {},
362
405
  // Benchwork footprint outline (module-local inches); only when it's a real
363
406
  // ring (≥ 3 vertices).
364
- ...state.outline.length >= 3 ? { outline: state.outline } : {}
407
+ ...state.outline.length >= 3 ? { outline: state.outline } : {},
408
+ // Authored mainline path (module-local inches); only when it's a real path.
409
+ ...state.mainPath.length >= 2 ? { mainPath: state.mainPath } : {}
365
410
  };
366
411
  }
367
412
  function docToState(doc, fallbackLength, moduleTracks = []) {
@@ -391,7 +436,9 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
391
436
  toPos: t.toPos != null ? sc(t.toPos) : len,
392
437
  moduleTrackId,
393
438
  trackName: t.trackName ?? nameOf(moduleTrackId),
394
- ...t.inLoop ? { inLoop: true } : {}
439
+ ...t.inLoop ? { inLoop: true } : {},
440
+ // Authored path kept as-drawn (a physical shape, not rescaled with length).
441
+ ...trackPath(t.path) ? { path: trackPath(t.path) } : {}
395
442
  });
396
443
  }
397
444
  }
@@ -440,6 +487,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
440
487
  y: p.y,
441
488
  ...Number.isFinite(p.bulge) && p.bulge ? { bulge: p.bulge } : {}
442
489
  }));
490
+ const mainPath = trackPath(d.mainPath) ?? [];
443
491
  return {
444
492
  lengthInches: len,
445
493
  loop,
@@ -456,6 +504,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
456
504
  poseOverrides,
457
505
  endplateWidths,
458
506
  outline,
507
+ mainPath,
459
508
  crossings: (d.crossings ?? []).map((x) => ({
460
509
  id: x.id,
461
510
  name: x.name ?? "",
@@ -942,6 +991,6 @@ function poseOverridesFromDoc(doc) {
942
991
  return out;
943
992
  }
944
993
 
945
- export { FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, scaleFeetToInches, stateToDoc };
994
+ export { FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, stateToDoc, trackPath };
946
995
  //# sourceMappingURL=index.js.map
947
996
  //# sourceMappingURL=index.js.map