@willcgage/module-schematic 0.73.0 → 0.75.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 +87 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -1
- package/dist/index.d.ts +75 -1
- package/dist/index.js +85 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -131,6 +131,10 @@ interface SchematicTrack {
|
|
|
131
131
|
* product's maximum piece length. Present = these are the ONLY joints, so an
|
|
132
132
|
* owner's deliberate cut survives a change elsewhere on the module. */
|
|
133
133
|
flexCuts?: number[] | null;
|
|
134
|
+
/** The owner's MEASURED usable length, real inches (#20) — for what the
|
|
135
|
+
* drawing can't know: a bumper post short of the drawn end, a structure
|
|
136
|
+
* fouling the track. Absent = derive it from the clearance points (#19). */
|
|
137
|
+
measuredUsableInches?: number | null;
|
|
134
138
|
}
|
|
135
139
|
interface SchematicTurnout {
|
|
136
140
|
id: string;
|
|
@@ -771,6 +775,74 @@ declare function scaleFeetToInches(feet: number, ratio?: number): number;
|
|
|
771
775
|
* ~3.0″; ~3.3″ over the couplers — the real spacing a cut of cars takes. The
|
|
772
776
|
* single constant every repo reads so a track's car count matches everywhere. */
|
|
773
777
|
declare const N_CAR_LENGTH_INCHES = 3.3;
|
|
778
|
+
/**
|
|
779
|
+
* How far the two routes must separate before a car on one clears equipment on
|
|
780
|
+
* the other — the CLEARANCE POINT's defining distance (#19).
|
|
781
|
+
*
|
|
782
|
+
* ⭐ Deliberately the **Free-moN track spacing**, not a second number. §2.0 uses
|
|
783
|
+
* 1.125″ as the distance at which two parallel tracks coexist, so "a car here
|
|
784
|
+
* clears a car there" is the same statement the standard already makes. It's
|
|
785
|
+
* 15 scale feet centre to centre, inside the prototype's usual 13–15 ft range.
|
|
786
|
+
*
|
|
787
|
+
* The alternative — a separate prototype constant — would leave the app holding
|
|
788
|
+
* two spacings that disagree about what "clear" means.
|
|
789
|
+
*/
|
|
790
|
+
declare const CLEARANCE_SPACING_INCHES = 1.125;
|
|
791
|
+
/**
|
|
792
|
+
* How far past the FROG a turnout's diverging route reaches the clearance point
|
|
793
|
+
* (#19) — the point from which usable capacity is measured.
|
|
794
|
+
*
|
|
795
|
+
* Not a measurement and not a guess: it's solved from the closure the drawing
|
|
796
|
+
* already uses, by asking where `offsetAt` first reaches
|
|
797
|
+
* {@link CLEARANCE_SPACING_INCHES}. So it follows the part's real lead, and a
|
|
798
|
+
* better-measured part moves it automatically.
|
|
799
|
+
*
|
|
800
|
+
* Returns the distance PAST THE FROG because `pos` means the frog (#132) — add
|
|
801
|
+
* it to the turnout's position, in the direction the turnout faces.
|
|
802
|
+
*/
|
|
803
|
+
declare function clearancePointPastFrogInches(size: number, library?: TrackPart[], clearanceInches?: number): number;
|
|
804
|
+
/** A track's usable capacity, measured to the clearance-point standard (#19). */
|
|
805
|
+
interface UsableCapacity {
|
|
806
|
+
/** The stretch a car can actually stand on, inches along the run. */
|
|
807
|
+
fromPos: number;
|
|
808
|
+
toPos: number;
|
|
809
|
+
/** Its length — what capacity is computed from. */
|
|
810
|
+
usableInches: number;
|
|
811
|
+
/** The run's full drawn length, for comparison. */
|
|
812
|
+
drawnInches: number;
|
|
813
|
+
/** How much each end gives up to its governing turnout's clearance point. */
|
|
814
|
+
givenUpInches: number;
|
|
815
|
+
/** Cars that fit in the usable length. */
|
|
816
|
+
cars: number;
|
|
817
|
+
/** Usable length as scale feet. */
|
|
818
|
+
scaleFeet: number;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* A track's USABLE capacity — measured from the governing turnout's clearance
|
|
822
|
+
* point, not from the rail ends (#19/#20).
|
|
823
|
+
*
|
|
824
|
+
* A spur runs clearance point → end of track; a siding, clearance point →
|
|
825
|
+
* clearance point. The difference is not small: FMN-0040's 70″ passing siding
|
|
826
|
+
* has two #7s on it, and loses 5.4″ at each end — 21 cars drawn, 17 usable.
|
|
827
|
+
*
|
|
828
|
+
* `measuredUsableInches` is the owner's override for what the drawing can't
|
|
829
|
+
* know — a bumper post short of the drawn end, a structure fouling the track.
|
|
830
|
+
* Given, it wins outright and the clearance points aren't applied to it: they
|
|
831
|
+
* measured the usable length itself.
|
|
832
|
+
*/
|
|
833
|
+
declare function usableCapacity(input: {
|
|
834
|
+
fromPos: number;
|
|
835
|
+
toPos: number;
|
|
836
|
+
/** Turnouts that DIVERGE ONTO this track — the ones that govern its ends. */
|
|
837
|
+
governing?: {
|
|
838
|
+
pos: number;
|
|
839
|
+
size?: number | null;
|
|
840
|
+
}[] | null;
|
|
841
|
+
/** The owner's measured usable length, inches. Wins when present. */
|
|
842
|
+
measuredUsableInches?: number | null;
|
|
843
|
+
library?: TrackPart[];
|
|
844
|
+
carLengthInches?: number;
|
|
845
|
+
}): UsableCapacity;
|
|
774
846
|
/** How much of a car-spot span has no rail under it (#194). */
|
|
775
847
|
interface SpanOverhang {
|
|
776
848
|
/** Inches the span runs past the track's near end (0 = it starts on track). */
|
|
@@ -822,6 +894,8 @@ interface EditorTrack {
|
|
|
822
894
|
/** Authored 2-D path (module-local inches) — a bent/rotated spur's real
|
|
823
895
|
* shape. Absent = derive from the main + lane (#2d-track). */
|
|
824
896
|
path?: BenchworkPoint[];
|
|
897
|
+
/** Measured usable length, real inches (#20). Absent = derived (#19). */
|
|
898
|
+
measuredUsableInches?: number;
|
|
825
899
|
}
|
|
826
900
|
/** A module_tracks row as loaded for the editor. */
|
|
827
901
|
interface ModuleTrackRow {
|
|
@@ -2051,4 +2125,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
2051
2125
|
heading: number;
|
|
2052
2126
|
}>;
|
|
2053
2127
|
|
|
2054
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, type GeometryType, type ImportedPart, 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 OccupiedSpan, type OutlineFace, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, 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 SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize };
|
|
2128
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, type GeometryType, type ImportedPart, 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 OccupiedSpan, type OutlineFace, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, 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 SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity };
|
package/dist/index.d.ts
CHANGED
|
@@ -131,6 +131,10 @@ interface SchematicTrack {
|
|
|
131
131
|
* product's maximum piece length. Present = these are the ONLY joints, so an
|
|
132
132
|
* owner's deliberate cut survives a change elsewhere on the module. */
|
|
133
133
|
flexCuts?: number[] | null;
|
|
134
|
+
/** The owner's MEASURED usable length, real inches (#20) — for what the
|
|
135
|
+
* drawing can't know: a bumper post short of the drawn end, a structure
|
|
136
|
+
* fouling the track. Absent = derive it from the clearance points (#19). */
|
|
137
|
+
measuredUsableInches?: number | null;
|
|
134
138
|
}
|
|
135
139
|
interface SchematicTurnout {
|
|
136
140
|
id: string;
|
|
@@ -771,6 +775,74 @@ declare function scaleFeetToInches(feet: number, ratio?: number): number;
|
|
|
771
775
|
* ~3.0″; ~3.3″ over the couplers — the real spacing a cut of cars takes. The
|
|
772
776
|
* single constant every repo reads so a track's car count matches everywhere. */
|
|
773
777
|
declare const N_CAR_LENGTH_INCHES = 3.3;
|
|
778
|
+
/**
|
|
779
|
+
* How far the two routes must separate before a car on one clears equipment on
|
|
780
|
+
* the other — the CLEARANCE POINT's defining distance (#19).
|
|
781
|
+
*
|
|
782
|
+
* ⭐ Deliberately the **Free-moN track spacing**, not a second number. §2.0 uses
|
|
783
|
+
* 1.125″ as the distance at which two parallel tracks coexist, so "a car here
|
|
784
|
+
* clears a car there" is the same statement the standard already makes. It's
|
|
785
|
+
* 15 scale feet centre to centre, inside the prototype's usual 13–15 ft range.
|
|
786
|
+
*
|
|
787
|
+
* The alternative — a separate prototype constant — would leave the app holding
|
|
788
|
+
* two spacings that disagree about what "clear" means.
|
|
789
|
+
*/
|
|
790
|
+
declare const CLEARANCE_SPACING_INCHES = 1.125;
|
|
791
|
+
/**
|
|
792
|
+
* How far past the FROG a turnout's diverging route reaches the clearance point
|
|
793
|
+
* (#19) — the point from which usable capacity is measured.
|
|
794
|
+
*
|
|
795
|
+
* Not a measurement and not a guess: it's solved from the closure the drawing
|
|
796
|
+
* already uses, by asking where `offsetAt` first reaches
|
|
797
|
+
* {@link CLEARANCE_SPACING_INCHES}. So it follows the part's real lead, and a
|
|
798
|
+
* better-measured part moves it automatically.
|
|
799
|
+
*
|
|
800
|
+
* Returns the distance PAST THE FROG because `pos` means the frog (#132) — add
|
|
801
|
+
* it to the turnout's position, in the direction the turnout faces.
|
|
802
|
+
*/
|
|
803
|
+
declare function clearancePointPastFrogInches(size: number, library?: TrackPart[], clearanceInches?: number): number;
|
|
804
|
+
/** A track's usable capacity, measured to the clearance-point standard (#19). */
|
|
805
|
+
interface UsableCapacity {
|
|
806
|
+
/** The stretch a car can actually stand on, inches along the run. */
|
|
807
|
+
fromPos: number;
|
|
808
|
+
toPos: number;
|
|
809
|
+
/** Its length — what capacity is computed from. */
|
|
810
|
+
usableInches: number;
|
|
811
|
+
/** The run's full drawn length, for comparison. */
|
|
812
|
+
drawnInches: number;
|
|
813
|
+
/** How much each end gives up to its governing turnout's clearance point. */
|
|
814
|
+
givenUpInches: number;
|
|
815
|
+
/** Cars that fit in the usable length. */
|
|
816
|
+
cars: number;
|
|
817
|
+
/** Usable length as scale feet. */
|
|
818
|
+
scaleFeet: number;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* A track's USABLE capacity — measured from the governing turnout's clearance
|
|
822
|
+
* point, not from the rail ends (#19/#20).
|
|
823
|
+
*
|
|
824
|
+
* A spur runs clearance point → end of track; a siding, clearance point →
|
|
825
|
+
* clearance point. The difference is not small: FMN-0040's 70″ passing siding
|
|
826
|
+
* has two #7s on it, and loses 5.4″ at each end — 21 cars drawn, 17 usable.
|
|
827
|
+
*
|
|
828
|
+
* `measuredUsableInches` is the owner's override for what the drawing can't
|
|
829
|
+
* know — a bumper post short of the drawn end, a structure fouling the track.
|
|
830
|
+
* Given, it wins outright and the clearance points aren't applied to it: they
|
|
831
|
+
* measured the usable length itself.
|
|
832
|
+
*/
|
|
833
|
+
declare function usableCapacity(input: {
|
|
834
|
+
fromPos: number;
|
|
835
|
+
toPos: number;
|
|
836
|
+
/** Turnouts that DIVERGE ONTO this track — the ones that govern its ends. */
|
|
837
|
+
governing?: {
|
|
838
|
+
pos: number;
|
|
839
|
+
size?: number | null;
|
|
840
|
+
}[] | null;
|
|
841
|
+
/** The owner's measured usable length, inches. Wins when present. */
|
|
842
|
+
measuredUsableInches?: number | null;
|
|
843
|
+
library?: TrackPart[];
|
|
844
|
+
carLengthInches?: number;
|
|
845
|
+
}): UsableCapacity;
|
|
774
846
|
/** How much of a car-spot span has no rail under it (#194). */
|
|
775
847
|
interface SpanOverhang {
|
|
776
848
|
/** Inches the span runs past the track's near end (0 = it starts on track). */
|
|
@@ -822,6 +894,8 @@ interface EditorTrack {
|
|
|
822
894
|
/** Authored 2-D path (module-local inches) — a bent/rotated spur's real
|
|
823
895
|
* shape. Absent = derive from the main + lane (#2d-track). */
|
|
824
896
|
path?: BenchworkPoint[];
|
|
897
|
+
/** Measured usable length, real inches (#20). Absent = derived (#19). */
|
|
898
|
+
measuredUsableInches?: number;
|
|
825
899
|
}
|
|
826
900
|
/** A module_tracks row as loaded for the editor. */
|
|
827
901
|
interface ModuleTrackRow {
|
|
@@ -2051,4 +2125,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
2051
2125
|
heading: number;
|
|
2052
2126
|
}>;
|
|
2053
2127
|
|
|
2054
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, type GeometryType, type ImportedPart, 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 OccupiedSpan, type OutlineFace, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, 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 SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize };
|
|
2128
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, type DimensionSource, type DrawCrossing, type DrawCrossover, type DrawIndustry, type DrawSignal, type DrawTrack, type DrawTurnout, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, type EditorBranch, type EditorControlPoint, type EditorCpSignal, type EditorCrossing, type EditorIndustry, type EditorState, type EditorTrack, type EditorTurnout, type EndplateBConfig, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, type GeometryType, type ImportedPart, 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 OccupiedSpan, type OutlineFace, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartSegment, RAIL_GAUGE_INCHES, type ReturnLoopGeometry, type ReturnLoopShape, 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 SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackPart, type TrackRole, type TurnoutClosure, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity };
|
package/dist/index.js
CHANGED
|
@@ -575,6 +575,56 @@ function scaleFeetToInches(feet, ratio = N_SCALE_RATIO) {
|
|
|
575
575
|
return feet * 12 / ratio;
|
|
576
576
|
}
|
|
577
577
|
var N_CAR_LENGTH_INCHES = 3.3;
|
|
578
|
+
var CLEARANCE_SPACING_INCHES = FREEMO_TRACK_SPACING_INCHES;
|
|
579
|
+
function clearancePointPastFrogInches(size, library = BUILT_IN_TRACK_PARTS, clearanceInches = CLEARANCE_SPACING_INCHES) {
|
|
580
|
+
const N = size > 0 ? size : 6;
|
|
581
|
+
const lead = leadInchesForSize(N, library);
|
|
582
|
+
const cl = turnoutClosure(N, { leadInches: lead });
|
|
583
|
+
let lo = 0;
|
|
584
|
+
let hi = Math.max(4 * lead, 4 * clearanceInches * N);
|
|
585
|
+
if (cl.offsetAt(hi) < clearanceInches) return hi - lead;
|
|
586
|
+
for (let i = 0; i < 60; i++) {
|
|
587
|
+
const mid = (lo + hi) / 2;
|
|
588
|
+
if (cl.offsetAt(mid) < clearanceInches) lo = mid;
|
|
589
|
+
else hi = mid;
|
|
590
|
+
}
|
|
591
|
+
return Math.max(0, hi - lead);
|
|
592
|
+
}
|
|
593
|
+
function usableCapacity(input) {
|
|
594
|
+
const lo = Math.min(input.fromPos, input.toPos);
|
|
595
|
+
const hi = Math.max(input.fromPos, input.toPos);
|
|
596
|
+
const drawn = hi - lo;
|
|
597
|
+
const carLen = input.carLengthInches ?? N_CAR_LENGTH_INCHES;
|
|
598
|
+
if (typeof input.measuredUsableInches === "number" && input.measuredUsableInches >= 0) {
|
|
599
|
+
const m = input.measuredUsableInches;
|
|
600
|
+
return {
|
|
601
|
+
fromPos: lo,
|
|
602
|
+
toPos: lo + m,
|
|
603
|
+
usableInches: m,
|
|
604
|
+
drawnInches: drawn,
|
|
605
|
+
givenUpInches: Math.max(0, drawn - m),
|
|
606
|
+
cars: carCapacity(0, m, carLen),
|
|
607
|
+
scaleFeet: Math.round(inchesToScaleFeet(m))
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
let a = lo;
|
|
611
|
+
let b = hi;
|
|
612
|
+
for (const sw of input.governing ?? []) {
|
|
613
|
+
const c = clearancePointPastFrogInches(sw.size ?? 6, input.library);
|
|
614
|
+
if (Math.abs(sw.pos - lo) <= Math.abs(sw.pos - hi)) a = Math.max(a, lo + c);
|
|
615
|
+
else b = Math.min(b, hi - c);
|
|
616
|
+
}
|
|
617
|
+
const usable = Math.max(0, b - a);
|
|
618
|
+
return {
|
|
619
|
+
fromPos: a,
|
|
620
|
+
toPos: Math.max(a, b),
|
|
621
|
+
usableInches: usable,
|
|
622
|
+
drawnInches: drawn,
|
|
623
|
+
givenUpInches: Math.max(0, drawn - usable),
|
|
624
|
+
cars: carCapacity(0, usable, carLen),
|
|
625
|
+
scaleFeet: Math.round(inchesToScaleFeet(usable))
|
|
626
|
+
};
|
|
627
|
+
}
|
|
578
628
|
function spanOverhang(input) {
|
|
579
629
|
const lo = Math.min(input.fromPos, input.toPos);
|
|
580
630
|
const hi = Math.max(input.fromPos, input.toPos);
|
|
@@ -825,7 +875,17 @@ function stateToDoc(state, recordNumber) {
|
|
|
825
875
|
toPos: t.toPos,
|
|
826
876
|
moduleTrackId: t.moduleTrackId,
|
|
827
877
|
trackName: t.trackName || void 0,
|
|
828
|
-
|
|
878
|
+
// ⚠️ USABLE capacity, measured from the governing turnouts' CLEARANCE
|
|
879
|
+
// POINTS (#19) — not the drawn rail-to-rail length, which counts track
|
|
880
|
+
// a car can't stand on without fouling the route it diverged from.
|
|
881
|
+
// FMN-0040's 70″ siding is 21 cars drawn and 17 usable.
|
|
882
|
+
capacityFeet: usableCapacity({
|
|
883
|
+
fromPos: t.fromPos,
|
|
884
|
+
toPos: t.toPos,
|
|
885
|
+
governing: state.turnouts.filter((sw) => sw.divergeTrack === t.id),
|
|
886
|
+
measuredUsableInches: t.measuredUsableInches
|
|
887
|
+
}).scaleFeet,
|
|
888
|
+
...typeof t.measuredUsableInches === "number" && t.measuredUsableInches >= 0 ? { measuredUsableInches: t.measuredUsableInches } : {},
|
|
829
889
|
...state.loop && t.inLoop ? { inLoop: true } : {},
|
|
830
890
|
...t.path && t.path.length >= 2 ? { path: t.path } : {}
|
|
831
891
|
}))
|
|
@@ -924,7 +984,10 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
924
984
|
trackName: t.trackName ?? nameOf(moduleTrackId),
|
|
925
985
|
...t.inLoop ? { inLoop: true } : {},
|
|
926
986
|
// Authored path kept as-drawn (a physical shape, not rescaled with length).
|
|
927
|
-
...trackPath(t.path) ? { path: trackPath(t.path) } : {}
|
|
987
|
+
...trackPath(t.path) ? { path: trackPath(t.path) } : {},
|
|
988
|
+
// A MEASURED length is a real-world fact about the physical track, so it
|
|
989
|
+
// rescales with the module exactly as its positions do (#20).
|
|
990
|
+
...typeof t.measuredUsableInches === "number" && Number.isFinite(t.measuredUsableInches) ? { measuredUsableInches: sc(t.measuredUsableInches) } : {}
|
|
928
991
|
});
|
|
929
992
|
}
|
|
930
993
|
}
|
|
@@ -1299,6 +1362,25 @@ var ATLAS_CODE55_N = [
|
|
|
1299
1362
|
note: "scaled from the measured #7 by frog number \u2014 not measured"
|
|
1300
1363
|
}
|
|
1301
1364
|
},
|
|
1365
|
+
{
|
|
1366
|
+
// Will Gage, 2026-07-26: "2057 is 3.5, 2056 is 2.5" — the two Atlas Code 55
|
|
1367
|
+
// wyes are different FROG NUMBERS, not a left/right pair of one part. The
|
|
1368
|
+
// 2056 half of that confirms the entry above; this is the one we didn't have.
|
|
1369
|
+
//
|
|
1370
|
+
// No lead. The #2.5's is `derived` from a per-frog rule its own note records
|
|
1371
|
+
// as refuted, so it rests on nothing — repeating that for a second part
|
|
1372
|
+
// would be exactly how a number nobody checked becomes two. Without one,
|
|
1373
|
+
// `leadInchesForSize` interpolates across the MEASURED parts at the wye's
|
|
1374
|
+
// effective frog (3.5 × 2 = 7), which lands on the measured #7.
|
|
1375
|
+
id: "atlas-c55-n-wye-35",
|
|
1376
|
+
manufacturer: "Atlas",
|
|
1377
|
+
line: "Code 55",
|
|
1378
|
+
scale: "N",
|
|
1379
|
+
name: "#3.5 Wye",
|
|
1380
|
+
kind: "wye",
|
|
1381
|
+
partNumbers: { single: "2057" },
|
|
1382
|
+
frogNumber: 3.5
|
|
1383
|
+
},
|
|
1302
1384
|
{
|
|
1303
1385
|
id: "atlas-c55-n-curved-21-15",
|
|
1304
1386
|
manufacturer: "Atlas",
|
|
@@ -2341,6 +2423,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
2341
2423
|
return out;
|
|
2342
2424
|
}
|
|
2343
2425
|
|
|
2344
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FLEX_TRACK_PARTS, 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, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize };
|
|
2426
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FLEX_TRACK_PARTS, 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, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateCentreOffsetInches, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, flexPartFor, flexParts, flexPieces, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partOutlineAtFrog, pastFrogInchesForSize, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity };
|
|
2345
2427
|
//# sourceMappingURL=index.js.map
|
|
2346
2428
|
//# sourceMappingURL=index.js.map
|