@willcgage/module-schematic 0.13.3 → 0.14.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 +59 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +57 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -43,7 +43,23 @@ interface SchematicEndplate {
|
|
|
43
43
|
y: number;
|
|
44
44
|
heading: number;
|
|
45
45
|
};
|
|
46
|
+
/** Free-moN endplate FACE width across the track, inches — the physical size
|
|
47
|
+
* of the standard interface at this end. Free-moN spec: 12″ minimum, 24″
|
|
48
|
+
* recommended. Absent = the recommended default (modules may differ end to
|
|
49
|
+
* end, e.g. a transition). */
|
|
50
|
+
widthInches?: number | null;
|
|
46
51
|
}
|
|
52
|
+
/** Free-moN endplate face width, inches — the connection interface size. */
|
|
53
|
+
declare const FREEMO_ENDPLATE_WIDTH_MIN_INCHES = 12;
|
|
54
|
+
declare const FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = 24;
|
|
55
|
+
/**
|
|
56
|
+
* The authored face width for an endplate, or the recommended default when a
|
|
57
|
+
* module hasn't authored one. The single source of truth both apps read so a
|
|
58
|
+
* module's endplate size is drawn the same in the Repository and the layout.
|
|
59
|
+
*/
|
|
60
|
+
declare function endplateWidthInches(ep: {
|
|
61
|
+
widthInches?: number | null;
|
|
62
|
+
} | null | undefined): number;
|
|
47
63
|
interface SchematicTrack {
|
|
48
64
|
id: string;
|
|
49
65
|
role: TrackRole;
|
|
@@ -244,6 +260,9 @@ interface EditorState {
|
|
|
244
260
|
y: number;
|
|
245
261
|
heading: number;
|
|
246
262
|
}>;
|
|
263
|
+
/** Authored endplate face widths by endplate id, inches (Free-moN 12″ min,
|
|
264
|
+
* 24″ recommended). Absent id = the recommended default. */
|
|
265
|
+
endplateWidths: Record<string, number>;
|
|
247
266
|
controlPoints: EditorControlPoint[];
|
|
248
267
|
}
|
|
249
268
|
/** Build the empty editor state for a module of the given length. */
|
|
@@ -504,4 +523,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
504
523
|
heading: number;
|
|
505
524
|
}>;
|
|
506
525
|
|
|
507
|
-
export { type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
|
526
|
+
export { type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,23 @@ interface SchematicEndplate {
|
|
|
43
43
|
y: number;
|
|
44
44
|
heading: number;
|
|
45
45
|
};
|
|
46
|
+
/** Free-moN endplate FACE width across the track, inches — the physical size
|
|
47
|
+
* of the standard interface at this end. Free-moN spec: 12″ minimum, 24″
|
|
48
|
+
* recommended. Absent = the recommended default (modules may differ end to
|
|
49
|
+
* end, e.g. a transition). */
|
|
50
|
+
widthInches?: number | null;
|
|
46
51
|
}
|
|
52
|
+
/** Free-moN endplate face width, inches — the connection interface size. */
|
|
53
|
+
declare const FREEMO_ENDPLATE_WIDTH_MIN_INCHES = 12;
|
|
54
|
+
declare const FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = 24;
|
|
55
|
+
/**
|
|
56
|
+
* The authored face width for an endplate, or the recommended default when a
|
|
57
|
+
* module hasn't authored one. The single source of truth both apps read so a
|
|
58
|
+
* module's endplate size is drawn the same in the Repository and the layout.
|
|
59
|
+
*/
|
|
60
|
+
declare function endplateWidthInches(ep: {
|
|
61
|
+
widthInches?: number | null;
|
|
62
|
+
} | null | undefined): number;
|
|
47
63
|
interface SchematicTrack {
|
|
48
64
|
id: string;
|
|
49
65
|
role: TrackRole;
|
|
@@ -244,6 +260,9 @@ interface EditorState {
|
|
|
244
260
|
y: number;
|
|
245
261
|
heading: number;
|
|
246
262
|
}>;
|
|
263
|
+
/** Authored endplate face widths by endplate id, inches (Free-moN 12″ min,
|
|
264
|
+
* 24″ recommended). Absent id = the recommended default. */
|
|
265
|
+
endplateWidths: Record<string, number>;
|
|
247
266
|
controlPoints: EditorControlPoint[];
|
|
248
267
|
}
|
|
249
268
|
/** Build the empty editor state for a module of the given length. */
|
|
@@ -504,4 +523,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
504
523
|
heading: number;
|
|
505
524
|
}>;
|
|
506
525
|
|
|
507
|
-
export { type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
|
526
|
+
export { type BranchConnector, type DrawCrossing, type DrawCrossover, type DrawSignal, type DrawTrack, type DrawTurnout, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, type GeometryType, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleFeatures, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_SCALE_RATIO, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
var FREEMO_ENDPLATE_WIDTH_MIN_INCHES = 12;
|
|
3
|
+
var FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = 24;
|
|
4
|
+
function endplateWidthInches(ep) {
|
|
5
|
+
const w = ep?.widthInches;
|
|
6
|
+
return typeof w === "number" && w > 0 ? w : FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
7
|
+
}
|
|
2
8
|
function isLoopDoc(doc) {
|
|
3
9
|
return doc.loop === true || doc.endplates.length === 1;
|
|
4
10
|
}
|
|
@@ -30,6 +36,7 @@ function emptyEditorState(lengthInches) {
|
|
|
30
36
|
crossings: [],
|
|
31
37
|
branches: [],
|
|
32
38
|
poseOverrides: {},
|
|
39
|
+
endplateWidths: {},
|
|
33
40
|
controlPoints: []
|
|
34
41
|
};
|
|
35
42
|
}
|
|
@@ -91,6 +98,12 @@ function withPoses(endplates, overrides) {
|
|
|
91
98
|
(e) => overrides[e.id] ? { ...e, pose: overrides[e.id] } : e
|
|
92
99
|
);
|
|
93
100
|
}
|
|
101
|
+
function withWidths(endplates, widths) {
|
|
102
|
+
return endplates.map((e) => {
|
|
103
|
+
const w = widths[e.id];
|
|
104
|
+
return typeof w === "number" && w > 0 ? { ...e, widthInches: w } : e;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
94
107
|
function stateToDoc(state, recordNumber) {
|
|
95
108
|
return {
|
|
96
109
|
version: 1,
|
|
@@ -98,42 +111,45 @@ function stateToDoc(state, recordNumber) {
|
|
|
98
111
|
lengthInches: state.lengthInches,
|
|
99
112
|
...state.loop ? { loop: true } : {},
|
|
100
113
|
...state.loop && state.loopReturn === "main2" ? { loopReturn: "main2" } : {},
|
|
101
|
-
endplates:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
) : [
|
|
112
|
-
{ id: "A", label: "West", tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: state.configA }] },
|
|
113
|
-
// Non-loop modules always have a real B ("none" never applies).
|
|
114
|
-
{
|
|
115
|
-
id: "B",
|
|
116
|
-
label: "East",
|
|
117
|
-
tracks: [
|
|
118
|
-
{
|
|
119
|
-
trackId: MAIN_TRACK_ID,
|
|
120
|
-
lane: 0,
|
|
121
|
-
config: state.configB === "none" ? "single" : state.configB
|
|
122
|
-
}
|
|
114
|
+
endplates: withWidths(
|
|
115
|
+
withPoses(
|
|
116
|
+
[
|
|
117
|
+
...state.loop ? (
|
|
118
|
+
// Balloon loop: A is the entry. A standard endplate B on the balloon
|
|
119
|
+
// makes it an INTERCHANGE (second route connects at the loop, e.g.
|
|
120
|
+
// Seaford); configB "none" makes it a pure turnback.
|
|
121
|
+
[
|
|
122
|
+
{ id: "A", label: "Entry", tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: state.configA }] },
|
|
123
|
+
...state.configB !== "none" ? [{ id: "B", label: "Interchange", tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: state.configB }] }] : []
|
|
123
124
|
]
|
|
124
|
-
|
|
125
|
+
) : [
|
|
126
|
+
{ id: "A", label: "West", tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: state.configA }] },
|
|
127
|
+
// Non-loop modules always have a real B ("none" never applies).
|
|
128
|
+
{
|
|
129
|
+
id: "B",
|
|
130
|
+
label: "East",
|
|
131
|
+
tracks: [
|
|
132
|
+
{
|
|
133
|
+
trackId: MAIN_TRACK_ID,
|
|
134
|
+
lane: 0,
|
|
135
|
+
config: state.configB === "none" ? "single" : state.configB
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
// Branch endplates C, D, … — junction connections at pos, off one side
|
|
141
|
+
// (#170). A set can carry several (e.g. a second railroad through).
|
|
142
|
+
...state.branches.map((b, i) => ({
|
|
143
|
+
id: String.fromCharCode(67 + i),
|
|
144
|
+
// C, D, E…
|
|
145
|
+
label: b.label || `Branch ${i + 1}`,
|
|
146
|
+
tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: b.config }],
|
|
147
|
+
at: { pos: b.pos, side: b.side }
|
|
148
|
+
}))
|
|
125
149
|
],
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
id: String.fromCharCode(67 + i),
|
|
130
|
-
// C, D, E…
|
|
131
|
-
label: b.label || `Branch ${i + 1}`,
|
|
132
|
-
tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: b.config }],
|
|
133
|
-
at: { pos: b.pos, side: b.side }
|
|
134
|
-
}))
|
|
135
|
-
],
|
|
136
|
-
state.poseOverrides
|
|
150
|
+
state.poseOverrides
|
|
151
|
+
),
|
|
152
|
+
state.endplateWidths
|
|
137
153
|
),
|
|
138
154
|
tracks: [
|
|
139
155
|
state.loop ? (
|
|
@@ -259,6 +275,11 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
259
275
|
(e) => e.id !== "A" && e.id !== "B" && e.at
|
|
260
276
|
);
|
|
261
277
|
const poseOverrides = poseOverridesFromDoc(d);
|
|
278
|
+
const endplateWidths = {};
|
|
279
|
+
for (const e of d.endplates ?? []) {
|
|
280
|
+
if (typeof e.widthInches === "number" && e.widthInches > 0)
|
|
281
|
+
endplateWidths[e.id] = e.widthInches;
|
|
282
|
+
}
|
|
262
283
|
return {
|
|
263
284
|
lengthInches: len,
|
|
264
285
|
loop,
|
|
@@ -273,6 +294,7 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
273
294
|
config: ep.tracks?.[0]?.config === "double" ? "double" : "single"
|
|
274
295
|
})),
|
|
275
296
|
poseOverrides,
|
|
297
|
+
endplateWidths,
|
|
276
298
|
crossings: (d.crossings ?? []).map((x) => ({
|
|
277
299
|
id: x.id,
|
|
278
300
|
name: x.name ?? "",
|
|
@@ -730,6 +752,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
730
752
|
return out;
|
|
731
753
|
}
|
|
732
754
|
|
|
733
|
-
export { MAIN2_TRACK_ID, MAIN_TRACK_ID, N_SCALE_RATIO, asModuleSchematic, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
|
755
|
+
export { FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_SCALE_RATIO, asModuleSchematic, buildCrossover, buildPassingSiding, buildTransition, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleFeatures, nextId, poseNeedsManual, poseOverridesFromDoc, scaleFeetToInches, stateToDoc };
|
|
734
756
|
//# sourceMappingURL=index.js.map
|
|
735
757
|
//# sourceMappingURL=index.js.map
|