@willcgage/module-schematic 0.34.0 → 0.36.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 +41 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -2
- package/dist/index.d.ts +76 -2
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -117,6 +117,13 @@ interface SchematicTurnout {
|
|
|
117
117
|
* the same way) instead of leaving as a straight diagonal. Physical-render
|
|
118
118
|
* only; the operations view stays topological. */
|
|
119
119
|
curved?: boolean | null;
|
|
120
|
+
/** Rotate the turnout 180° — the points face the other way along the track.
|
|
121
|
+
* HAND is which turnout you own; how it's INSTALLED is a separate choice, and
|
|
122
|
+
* the drawn orientation can't always be inferred from where the diverging
|
|
123
|
+
* track happens to run. A siding at the far end of a module is the case that
|
|
124
|
+
* forces it: the body has nowhere to go but back toward the module, so the
|
|
125
|
+
* derived facing comes out backwards. */
|
|
126
|
+
flipped?: boolean | null;
|
|
120
127
|
}
|
|
121
128
|
interface SchematicSignal {
|
|
122
129
|
id: string;
|
|
@@ -428,6 +435,68 @@ declare function sectionSpans(doc: {
|
|
|
428
435
|
fromPos: number;
|
|
429
436
|
toPos: number;
|
|
430
437
|
}[];
|
|
438
|
+
/** A position expressed against the board it sits on, rather than as inches
|
|
439
|
+
* from endplate A (#109). */
|
|
440
|
+
interface SectionRelativePos {
|
|
441
|
+
sectionId: string;
|
|
442
|
+
/** Inches from that section's own west end. */
|
|
443
|
+
offsetInches: number;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Section spans that ALWAYS cover the whole module. The owner's insight is
|
|
447
|
+
* what makes #109 tractable: every module has at least one section, even if
|
|
448
|
+
* that one section IS the whole module. So a module with no authored sections
|
|
449
|
+
* gets a single implicit span 0→length, every position falls inside exactly
|
|
450
|
+
* one span, and absolute ↔ relative becomes a total, lossless mapping with no
|
|
451
|
+
* un-convertible module and no orphan positions.
|
|
452
|
+
*
|
|
453
|
+
* The last span is also stretched to the module length when the sections come
|
|
454
|
+
* up short, so a position past the end still lands somewhere real.
|
|
455
|
+
*/
|
|
456
|
+
declare function sectionSpansOrWhole(doc: {
|
|
457
|
+
sections?: SchematicSection[] | null;
|
|
458
|
+
} | null | undefined, lengthInches: number): {
|
|
459
|
+
id: string;
|
|
460
|
+
name?: string;
|
|
461
|
+
fromPos: number;
|
|
462
|
+
toPos: number;
|
|
463
|
+
}[];
|
|
464
|
+
/** The id a module with no authored sections uses for its single implicit one. */
|
|
465
|
+
declare const WHOLE_MODULE_SECTION_ID = "module";
|
|
466
|
+
/**
|
|
467
|
+
* Absolute inches → the board it sits on plus an offset along it (#109).
|
|
468
|
+
* Total: given spans from `sectionSpansOrWhole`, every position resolves.
|
|
469
|
+
*
|
|
470
|
+
* A position exactly ON a joint is assigned to the section that STARTS there,
|
|
471
|
+
* at offset 0 — a joint is the west end of the next board, and that keeps the
|
|
472
|
+
* mapping single-valued. The module's own east end is the exception: nothing
|
|
473
|
+
* starts there, so it belongs to the last board.
|
|
474
|
+
*/
|
|
475
|
+
declare function toSectionRelative(pos: number, spans: {
|
|
476
|
+
id: string;
|
|
477
|
+
fromPos: number;
|
|
478
|
+
toPos: number;
|
|
479
|
+
}[]): SectionRelativePos | null;
|
|
480
|
+
/** …and back. Null when the section is gone — which is the caller's cue that
|
|
481
|
+
* the thing it positioned has lost its board (#96 phase 3). */
|
|
482
|
+
declare function fromSectionRelative(rel: SectionRelativePos, spans: {
|
|
483
|
+
id: string;
|
|
484
|
+
fromPos: number;
|
|
485
|
+
toPos: number;
|
|
486
|
+
}[]): number | null;
|
|
487
|
+
/** Re-derive an absolute position after the sections have moved: read it
|
|
488
|
+
* against the OLD spans, write it against the NEW ones. This is the whole
|
|
489
|
+
* point of #109 — reorder or resize a board and everything on it comes along
|
|
490
|
+
* instead of silently pointing at a different board. */
|
|
491
|
+
declare function remapPos(pos: number, before: {
|
|
492
|
+
id: string;
|
|
493
|
+
fromPos: number;
|
|
494
|
+
toPos: number;
|
|
495
|
+
}[], after: {
|
|
496
|
+
id: string;
|
|
497
|
+
fromPos: number;
|
|
498
|
+
toPos: number;
|
|
499
|
+
}[]): number | null;
|
|
431
500
|
/** The joints implied by the sections — the interior boundaries, in inches from
|
|
432
501
|
* endplate A. Replaces the authored `sectionBreaks` for a sectioned module. */
|
|
433
502
|
declare function sectionBreaksFromSections(doc: {
|
|
@@ -600,6 +669,8 @@ interface EditorTurnout {
|
|
|
600
669
|
kind: TurnoutKind;
|
|
601
670
|
/** Frog number ("size") — #4, #6, #8, etc. Governs the diverging angle. */
|
|
602
671
|
size?: number;
|
|
672
|
+
/** Rotate the turnout 180° — the points face the other way (#turnout-flip). */
|
|
673
|
+
flipped?: boolean;
|
|
603
674
|
/** A curved turnout — the diverging route bows into an arc rather than a
|
|
604
675
|
* straight diagonal. Physical-render only (the operations view is topological). */
|
|
605
676
|
curved?: boolean;
|
|
@@ -912,7 +983,10 @@ interface ModuleFeatures {
|
|
|
912
983
|
* right-hand throws to the opposite side. `kind` is the source of truth for the
|
|
913
984
|
* drawn side (#bug1) — the stored lane's sign is reconciled to match it.
|
|
914
985
|
*/
|
|
915
|
-
declare function divergeSideForHand(kind: TurnoutKind | undefined, stubDir: number
|
|
986
|
+
declare function divergeSideForHand(kind: TurnoutKind | undefined, stubDir: number,
|
|
987
|
+
/** The turnout is installed the other way round — the points face the far
|
|
988
|
+
* direction, which swaps the side the diverging route leaves on. */
|
|
989
|
+
flipped?: boolean | null): -1 | 0 | 1;
|
|
916
990
|
/**
|
|
917
991
|
* Resolve a schematic doc into positioned drawables. `pos` (inches) becomes a
|
|
918
992
|
* fraction of the module length; endplate A = 0, B = length; turnouts sit at
|
|
@@ -988,4 +1062,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
988
1062
|
heading: number;
|
|
989
1063
|
}>;
|
|
990
1064
|
|
|
991
|
-
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, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, 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 SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, trackPath };
|
|
1065
|
+
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, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, 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 SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SectionRelativePos, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, fromSectionRelative, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, remapPos, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackPath };
|
package/dist/index.d.ts
CHANGED
|
@@ -117,6 +117,13 @@ interface SchematicTurnout {
|
|
|
117
117
|
* the same way) instead of leaving as a straight diagonal. Physical-render
|
|
118
118
|
* only; the operations view stays topological. */
|
|
119
119
|
curved?: boolean | null;
|
|
120
|
+
/** Rotate the turnout 180° — the points face the other way along the track.
|
|
121
|
+
* HAND is which turnout you own; how it's INSTALLED is a separate choice, and
|
|
122
|
+
* the drawn orientation can't always be inferred from where the diverging
|
|
123
|
+
* track happens to run. A siding at the far end of a module is the case that
|
|
124
|
+
* forces it: the body has nowhere to go but back toward the module, so the
|
|
125
|
+
* derived facing comes out backwards. */
|
|
126
|
+
flipped?: boolean | null;
|
|
120
127
|
}
|
|
121
128
|
interface SchematicSignal {
|
|
122
129
|
id: string;
|
|
@@ -428,6 +435,68 @@ declare function sectionSpans(doc: {
|
|
|
428
435
|
fromPos: number;
|
|
429
436
|
toPos: number;
|
|
430
437
|
}[];
|
|
438
|
+
/** A position expressed against the board it sits on, rather than as inches
|
|
439
|
+
* from endplate A (#109). */
|
|
440
|
+
interface SectionRelativePos {
|
|
441
|
+
sectionId: string;
|
|
442
|
+
/** Inches from that section's own west end. */
|
|
443
|
+
offsetInches: number;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Section spans that ALWAYS cover the whole module. The owner's insight is
|
|
447
|
+
* what makes #109 tractable: every module has at least one section, even if
|
|
448
|
+
* that one section IS the whole module. So a module with no authored sections
|
|
449
|
+
* gets a single implicit span 0→length, every position falls inside exactly
|
|
450
|
+
* one span, and absolute ↔ relative becomes a total, lossless mapping with no
|
|
451
|
+
* un-convertible module and no orphan positions.
|
|
452
|
+
*
|
|
453
|
+
* The last span is also stretched to the module length when the sections come
|
|
454
|
+
* up short, so a position past the end still lands somewhere real.
|
|
455
|
+
*/
|
|
456
|
+
declare function sectionSpansOrWhole(doc: {
|
|
457
|
+
sections?: SchematicSection[] | null;
|
|
458
|
+
} | null | undefined, lengthInches: number): {
|
|
459
|
+
id: string;
|
|
460
|
+
name?: string;
|
|
461
|
+
fromPos: number;
|
|
462
|
+
toPos: number;
|
|
463
|
+
}[];
|
|
464
|
+
/** The id a module with no authored sections uses for its single implicit one. */
|
|
465
|
+
declare const WHOLE_MODULE_SECTION_ID = "module";
|
|
466
|
+
/**
|
|
467
|
+
* Absolute inches → the board it sits on plus an offset along it (#109).
|
|
468
|
+
* Total: given spans from `sectionSpansOrWhole`, every position resolves.
|
|
469
|
+
*
|
|
470
|
+
* A position exactly ON a joint is assigned to the section that STARTS there,
|
|
471
|
+
* at offset 0 — a joint is the west end of the next board, and that keeps the
|
|
472
|
+
* mapping single-valued. The module's own east end is the exception: nothing
|
|
473
|
+
* starts there, so it belongs to the last board.
|
|
474
|
+
*/
|
|
475
|
+
declare function toSectionRelative(pos: number, spans: {
|
|
476
|
+
id: string;
|
|
477
|
+
fromPos: number;
|
|
478
|
+
toPos: number;
|
|
479
|
+
}[]): SectionRelativePos | null;
|
|
480
|
+
/** …and back. Null when the section is gone — which is the caller's cue that
|
|
481
|
+
* the thing it positioned has lost its board (#96 phase 3). */
|
|
482
|
+
declare function fromSectionRelative(rel: SectionRelativePos, spans: {
|
|
483
|
+
id: string;
|
|
484
|
+
fromPos: number;
|
|
485
|
+
toPos: number;
|
|
486
|
+
}[]): number | null;
|
|
487
|
+
/** Re-derive an absolute position after the sections have moved: read it
|
|
488
|
+
* against the OLD spans, write it against the NEW ones. This is the whole
|
|
489
|
+
* point of #109 — reorder or resize a board and everything on it comes along
|
|
490
|
+
* instead of silently pointing at a different board. */
|
|
491
|
+
declare function remapPos(pos: number, before: {
|
|
492
|
+
id: string;
|
|
493
|
+
fromPos: number;
|
|
494
|
+
toPos: number;
|
|
495
|
+
}[], after: {
|
|
496
|
+
id: string;
|
|
497
|
+
fromPos: number;
|
|
498
|
+
toPos: number;
|
|
499
|
+
}[]): number | null;
|
|
431
500
|
/** The joints implied by the sections — the interior boundaries, in inches from
|
|
432
501
|
* endplate A. Replaces the authored `sectionBreaks` for a sectioned module. */
|
|
433
502
|
declare function sectionBreaksFromSections(doc: {
|
|
@@ -600,6 +669,8 @@ interface EditorTurnout {
|
|
|
600
669
|
kind: TurnoutKind;
|
|
601
670
|
/** Frog number ("size") — #4, #6, #8, etc. Governs the diverging angle. */
|
|
602
671
|
size?: number;
|
|
672
|
+
/** Rotate the turnout 180° — the points face the other way (#turnout-flip). */
|
|
673
|
+
flipped?: boolean;
|
|
603
674
|
/** A curved turnout — the diverging route bows into an arc rather than a
|
|
604
675
|
* straight diagonal. Physical-render only (the operations view is topological). */
|
|
605
676
|
curved?: boolean;
|
|
@@ -912,7 +983,10 @@ interface ModuleFeatures {
|
|
|
912
983
|
* right-hand throws to the opposite side. `kind` is the source of truth for the
|
|
913
984
|
* drawn side (#bug1) — the stored lane's sign is reconciled to match it.
|
|
914
985
|
*/
|
|
915
|
-
declare function divergeSideForHand(kind: TurnoutKind | undefined, stubDir: number
|
|
986
|
+
declare function divergeSideForHand(kind: TurnoutKind | undefined, stubDir: number,
|
|
987
|
+
/** The turnout is installed the other way round — the points face the far
|
|
988
|
+
* direction, which swaps the side the diverging route leaves on. */
|
|
989
|
+
flipped?: boolean | null): -1 | 0 | 1;
|
|
916
990
|
/**
|
|
917
991
|
* Resolve a schematic doc into positioned drawables. `pos` (inches) becomes a
|
|
918
992
|
* fraction of the module length; endplate A = 0, B = length; turnouts sit at
|
|
@@ -988,4 +1062,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
988
1062
|
heading: number;
|
|
989
1063
|
}>;
|
|
990
1064
|
|
|
991
|
-
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, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, 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 SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, trackPath };
|
|
1065
|
+
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, type EndplateWidthIssue, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type GeometryType, type IndustryLabelMode, type IndustrySpot, 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 SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionFootprint, type SectionRelativePos, type SignalFacing, type SignalSide, type TrackConfig, type TrackRole, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, fromSectionRelative, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, remapPos, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackPath };
|
package/dist/index.js
CHANGED
|
@@ -205,6 +205,35 @@ function sectionSpans(doc) {
|
|
|
205
205
|
}
|
|
206
206
|
return out;
|
|
207
207
|
}
|
|
208
|
+
function sectionSpansOrWhole(doc, lengthInches) {
|
|
209
|
+
const L = lengthInches > 0 ? lengthInches : 0;
|
|
210
|
+
const spans = sectionSpans(doc);
|
|
211
|
+
if (!spans.length) return [{ id: WHOLE_MODULE_SECTION_ID, fromPos: 0, toPos: L }];
|
|
212
|
+
const out = spans.map((sp) => ({ ...sp }));
|
|
213
|
+
const last = out[out.length - 1];
|
|
214
|
+
if (L > last.toPos) last.toPos = L;
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
var WHOLE_MODULE_SECTION_ID = "module";
|
|
218
|
+
function toSectionRelative(pos, spans) {
|
|
219
|
+
if (!spans.length) return null;
|
|
220
|
+
const p = Math.max(spans[0].fromPos, Math.min(spans[spans.length - 1].toPos, pos));
|
|
221
|
+
for (const sp of spans) {
|
|
222
|
+
if (p >= sp.fromPos && p < sp.toPos)
|
|
223
|
+
return { sectionId: sp.id, offsetInches: round3(p - sp.fromPos) };
|
|
224
|
+
}
|
|
225
|
+
const last = spans[spans.length - 1];
|
|
226
|
+
return { sectionId: last.id, offsetInches: round3(last.toPos - last.fromPos) };
|
|
227
|
+
}
|
|
228
|
+
function fromSectionRelative(rel, spans) {
|
|
229
|
+
const sp = spans.find((x) => x.id === rel.sectionId);
|
|
230
|
+
if (!sp) return null;
|
|
231
|
+
return round3(sp.fromPos + Math.max(0, Math.min(sp.toPos - sp.fromPos, rel.offsetInches)));
|
|
232
|
+
}
|
|
233
|
+
function remapPos(pos, before, after) {
|
|
234
|
+
const rel = toSectionRelative(pos, before);
|
|
235
|
+
return rel ? fromSectionRelative(rel, after) : null;
|
|
236
|
+
}
|
|
208
237
|
function sectionBreaksFromSections(doc) {
|
|
209
238
|
const spans = sectionSpans(doc);
|
|
210
239
|
return spans.slice(0, -1).map((sp) => sp.toPos);
|
|
@@ -481,6 +510,7 @@ function checkEndplateWidth(input) {
|
|
|
481
510
|
return issues;
|
|
482
511
|
}
|
|
483
512
|
var round2 = (n) => Math.round(n * 100) / 100;
|
|
513
|
+
var round3 = (n) => Math.round(n * 1e3) / 1e3;
|
|
484
514
|
function endplateWidthFor(widths, id) {
|
|
485
515
|
const w = widths?.[id];
|
|
486
516
|
return typeof w === "number" && w > 0 ? w : FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
@@ -714,7 +744,8 @@ function stateToDoc(state, recordNumber) {
|
|
|
714
744
|
kind: t.kind,
|
|
715
745
|
name: t.name || void 0,
|
|
716
746
|
...t.size ? { size: t.size } : {},
|
|
717
|
-
...t.curved ? { curved: true } : {}
|
|
747
|
+
...t.curved ? { curved: true } : {},
|
|
748
|
+
...t.flipped ? { flipped: true } : {}
|
|
718
749
|
})),
|
|
719
750
|
...state.crossings.length > 0 ? {
|
|
720
751
|
crossings: state.crossings.map((x) => ({
|
|
@@ -885,7 +916,8 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
885
916
|
divergeTrack: t.divergeTrack,
|
|
886
917
|
kind: t.kind ?? "right",
|
|
887
918
|
...t.size ? { size: t.size } : {},
|
|
888
|
-
...t.curved ? { curved: true } : {}
|
|
919
|
+
...t.curved ? { curved: true } : {},
|
|
920
|
+
...t.flipped ? { flipped: true } : {}
|
|
889
921
|
})),
|
|
890
922
|
controlPoints: readControlPoints(d, sc),
|
|
891
923
|
industries: (d.industries ?? []).map((ind) => ({
|
|
@@ -1018,9 +1050,9 @@ function buildCrossover(state) {
|
|
|
1018
1050
|
];
|
|
1019
1051
|
return { track, turnouts };
|
|
1020
1052
|
}
|
|
1021
|
-
function divergeSideForHand(kind, stubDir) {
|
|
1053
|
+
function divergeSideForHand(kind, stubDir, flipped) {
|
|
1022
1054
|
if (kind !== "left" && kind !== "right") return 0;
|
|
1023
|
-
const s = stubDir >= 0 ? 1 : -1;
|
|
1055
|
+
const s = (stubDir >= 0 ? 1 : -1) * (flipped ? -1 : 1);
|
|
1024
1056
|
return kind === "left" ? s : -s;
|
|
1025
1057
|
}
|
|
1026
1058
|
function moduleFeatures(doc) {
|
|
@@ -1381,6 +1413,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
1381
1413
|
return out;
|
|
1382
1414
|
}
|
|
1383
1415
|
|
|
1384
|
-
export { FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, trackPath };
|
|
1416
|
+
export { FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, fromSectionRelative, geometryTurnDegrees, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, poseNeedsManual, poseOverridesFromDoc, remapPos, sampleBenchworkOutline, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackPath };
|
|
1385
1417
|
//# sourceMappingURL=index.js.map
|
|
1386
1418
|
//# sourceMappingURL=index.js.map
|