@willcgage/module-schematic 0.106.0 → 0.108.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
@@ -1712,6 +1712,16 @@ interface TrackPart {
1712
1712
  * and `minimumLength` a floor, and nothing may infer where an owner's actual
1713
1713
  * turnout ends from either of them. */
1714
1714
  buildable?: boolean;
1715
+ /**
1716
+ * This part stands in for one nobody has identified — its shape is
1717
+ * interpolated, not read off anything.
1718
+ *
1719
+ * ⛔ A provisional part must never be adopted automatically, offered beside
1720
+ * real products as an equal, or allowed to look measured. It exists so an
1721
+ * owner who cannot answer "which turnout is this?" is not blocked, and so that
1722
+ * what they could not answer stays visible afterwards.
1723
+ */
1724
+ provisional?: boolean;
1715
1725
  /** The shortest the part can be built. Buildable parts only. */
1716
1726
  minimumLength?: PartDimension;
1717
1727
  /** How many identical pieces built on this fixture make ONE finished part.
@@ -2002,6 +2012,47 @@ declare const DEFAULT_FLEX_PART_ID = "atlas-c55-n-flex";
2002
2012
  * rest of this library exists to avoid; a named product can be added with its
2003
2013
  * own measurement, and will draw at it.
2004
2014
  */
2015
+ /** Frog numbers a placeholder is offered for. #6 is the standard's floor for a
2016
+ * main line; #4 and #5 are ordinary in yards. Outside the measured 5–10 range
2017
+ * the interpolators extrapolate, which is acceptable in a part that already
2018
+ * says it is a stand-in. */
2019
+ declare const GENERIC_TURNOUT_FROG_NUMBERS: readonly [4, 5, 6, 7, 8, 10];
2020
+ /**
2021
+ * A turnout nobody has identified — "it's a #6, I don't know whose".
2022
+ *
2023
+ * ⭐⭐ **IT IS THE TURNOUT'S WORKING GEOMETRY AND NOTHING ELSE**: points → frog
2024
+ * → end, with **no moulded approach track in front of the points**. That is not
2025
+ * a shortcut, it is the only honest shape available. `pointsOffset` is the one
2026
+ * dimension a frog number cannot yield — the measured Atlas parts read 1.75″,
2027
+ * 0.625″ and 0.5625″ for #5, #7 and #10, which is a moulding decision and not
2028
+ * geometry, so there is nothing to interpolate along. Zero is therefore not a
2029
+ * guess about the owner's part; it says we are modelling the turnout and not
2030
+ * some product's tie strip. It is also what a hand-laid turnout actually is.
2031
+ *
2032
+ * ⭐ **The lead and the length past the frog ARE derivable**, by interpolating
2033
+ * the measured parts ({@link leadInchesForSize}, {@link pastFrogInchesForSize})
2034
+ * — the same interpolation the 1-D model has always drawn an unidentified `#N`
2035
+ * with. Nothing new is invented here; what changes is that it is now labelled.
2036
+ *
2037
+ * ⚠️ **EVERY DIMENSION IS `derived`.** Two things follow, both wanted:
2038
+ * {@link partGeometry} reports `source: "derived"`, so any surface can say the
2039
+ * shape is provisional; and {@link partExtent} returns **null**, so the drawing
2040
+ * declines to claim where this turnout's body ends rather than laundering an
2041
+ * interpolation into a boundary an owner would read as measured.
2042
+ *
2043
+ * ⛔ **NEVER ADOPTED AUTOMATICALLY.** A placeholder is something an owner
2044
+ * chooses when they cannot answer; resolving a bare `#6` to one behind their
2045
+ * back would be exactly the invention ADR 0001 forbids. See
2046
+ * {@link moduleConversionReport}, which excludes provisional parts from both
2047
+ * automatic resolution and its candidate list.
2048
+ */
2049
+ declare function genericTurnoutPart(frogNumber: number, library?: TrackPart[]): TrackPart;
2050
+ /** The placeholders, one per {@link GENERIC_TURNOUT_FROG_NUMBERS}. */
2051
+ declare const GENERIC_TURNOUTS: TrackPart[];
2052
+ /** Parts that stand in for one nobody has identified — offered only where an
2053
+ * owner is being asked what something is, and never mixed in with real products
2054
+ * as though they were equivalent. */
2055
+ declare function provisionalParts(library?: TrackPart[]): TrackPart[];
2005
2056
  declare const GENERIC_END_OF_TRACK: TrackPart[];
2006
2057
  declare const BUILT_IN_TRACK_PARTS: TrackPart[];
2007
2058
  /** Every flex product a track can be laid with. */
@@ -3439,4 +3490,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
3439
3490
  heading: number;
3440
3491
  }>;
3441
3492
 
3442
- export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, type ConversionAnswers, type ConversionBlocker, DEFAULT_FLEX_PART_ID, type DimensionSource, type DocToGraphResult, 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 EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleConversionReport, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OrphanTrack, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type RunInsertion, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutIdentity, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverAssembly, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToGraph, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleConversionReport, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
3493
+ export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, type ConversionAnswers, type ConversionBlocker, DEFAULT_FLEX_PART_ID, type DimensionSource, type DocToGraphResult, 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 EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, GENERIC_TURNOUTS, GENERIC_TURNOUT_FROG_NUMBERS, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleConversionReport, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OrphanTrack, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type RunInsertion, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutIdentity, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverAssembly, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToGraph, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, genericTurnoutPart, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleConversionReport, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, provisionalParts, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
package/dist/index.d.ts CHANGED
@@ -1712,6 +1712,16 @@ interface TrackPart {
1712
1712
  * and `minimumLength` a floor, and nothing may infer where an owner's actual
1713
1713
  * turnout ends from either of them. */
1714
1714
  buildable?: boolean;
1715
+ /**
1716
+ * This part stands in for one nobody has identified — its shape is
1717
+ * interpolated, not read off anything.
1718
+ *
1719
+ * ⛔ A provisional part must never be adopted automatically, offered beside
1720
+ * real products as an equal, or allowed to look measured. It exists so an
1721
+ * owner who cannot answer "which turnout is this?" is not blocked, and so that
1722
+ * what they could not answer stays visible afterwards.
1723
+ */
1724
+ provisional?: boolean;
1715
1725
  /** The shortest the part can be built. Buildable parts only. */
1716
1726
  minimumLength?: PartDimension;
1717
1727
  /** How many identical pieces built on this fixture make ONE finished part.
@@ -2002,6 +2012,47 @@ declare const DEFAULT_FLEX_PART_ID = "atlas-c55-n-flex";
2002
2012
  * rest of this library exists to avoid; a named product can be added with its
2003
2013
  * own measurement, and will draw at it.
2004
2014
  */
2015
+ /** Frog numbers a placeholder is offered for. #6 is the standard's floor for a
2016
+ * main line; #4 and #5 are ordinary in yards. Outside the measured 5–10 range
2017
+ * the interpolators extrapolate, which is acceptable in a part that already
2018
+ * says it is a stand-in. */
2019
+ declare const GENERIC_TURNOUT_FROG_NUMBERS: readonly [4, 5, 6, 7, 8, 10];
2020
+ /**
2021
+ * A turnout nobody has identified — "it's a #6, I don't know whose".
2022
+ *
2023
+ * ⭐⭐ **IT IS THE TURNOUT'S WORKING GEOMETRY AND NOTHING ELSE**: points → frog
2024
+ * → end, with **no moulded approach track in front of the points**. That is not
2025
+ * a shortcut, it is the only honest shape available. `pointsOffset` is the one
2026
+ * dimension a frog number cannot yield — the measured Atlas parts read 1.75″,
2027
+ * 0.625″ and 0.5625″ for #5, #7 and #10, which is a moulding decision and not
2028
+ * geometry, so there is nothing to interpolate along. Zero is therefore not a
2029
+ * guess about the owner's part; it says we are modelling the turnout and not
2030
+ * some product's tie strip. It is also what a hand-laid turnout actually is.
2031
+ *
2032
+ * ⭐ **The lead and the length past the frog ARE derivable**, by interpolating
2033
+ * the measured parts ({@link leadInchesForSize}, {@link pastFrogInchesForSize})
2034
+ * — the same interpolation the 1-D model has always drawn an unidentified `#N`
2035
+ * with. Nothing new is invented here; what changes is that it is now labelled.
2036
+ *
2037
+ * ⚠️ **EVERY DIMENSION IS `derived`.** Two things follow, both wanted:
2038
+ * {@link partGeometry} reports `source: "derived"`, so any surface can say the
2039
+ * shape is provisional; and {@link partExtent} returns **null**, so the drawing
2040
+ * declines to claim where this turnout's body ends rather than laundering an
2041
+ * interpolation into a boundary an owner would read as measured.
2042
+ *
2043
+ * ⛔ **NEVER ADOPTED AUTOMATICALLY.** A placeholder is something an owner
2044
+ * chooses when they cannot answer; resolving a bare `#6` to one behind their
2045
+ * back would be exactly the invention ADR 0001 forbids. See
2046
+ * {@link moduleConversionReport}, which excludes provisional parts from both
2047
+ * automatic resolution and its candidate list.
2048
+ */
2049
+ declare function genericTurnoutPart(frogNumber: number, library?: TrackPart[]): TrackPart;
2050
+ /** The placeholders, one per {@link GENERIC_TURNOUT_FROG_NUMBERS}. */
2051
+ declare const GENERIC_TURNOUTS: TrackPart[];
2052
+ /** Parts that stand in for one nobody has identified — offered only where an
2053
+ * owner is being asked what something is, and never mixed in with real products
2054
+ * as though they were equivalent. */
2055
+ declare function provisionalParts(library?: TrackPart[]): TrackPart[];
2005
2056
  declare const GENERIC_END_OF_TRACK: TrackPart[];
2006
2057
  declare const BUILT_IN_TRACK_PARTS: TrackPart[];
2007
2058
  /** Every flex product a track can be laid with. */
@@ -3439,4 +3490,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
3439
3490
  heading: number;
3440
3491
  }>;
3441
3492
 
3442
- export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, type ConversionAnswers, type ConversionBlocker, DEFAULT_FLEX_PART_ID, type DimensionSource, type DocToGraphResult, 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 EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleConversionReport, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OrphanTrack, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type RunInsertion, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutIdentity, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverAssembly, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToGraph, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleConversionReport, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
3493
+ export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, type BenchworkPoint, type BranchConnector, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, type ConversionAnswers, type ConversionBlocker, DEFAULT_FLEX_PART_ID, type DimensionSource, type DocToGraphResult, 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 EndplateEdge, type EndplateEdgePose, type EndplatePose, type EndplateTrackIssue, type EndplateWidthIssue, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, type FlexPiece, type FlexPieceEnd, type FrogCasting, GENERIC_END_OF_TRACK, GENERIC_TURNOUTS, GENERIC_TURNOUT_FROG_NUMBERS, type GeometryType, type GraphAnchor, type GraphConflict, type GraphConnection, type GraphDocInput, type GraphDocResult, type GraphRoute, type GraphTurnout, type GraphWalk, type ImportedPart, type IndustryLabelMode, type IndustrySpot, JOINT_SNAP_INCHES, type LanePinch, MAIN2_TRACK_ID, MAIN_TRACK_ID, type ModuleConversionReport, type ModuleFeatures, type ModuleFootprint, type ModuleFootprintInput, type ModuleGeometryInput, type ModuleSchematicDoc, type ModuleTrackRow, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, type OccupiedSpan, type OrphanTrack, type OutlineFace, PINCH_EASE_INCHES, type PartAngle, type PartDimension, type PartEnd, type PartExtent, type PartGeometry, type PartJoint, type PartJointRole, type PartSegment, type PieceSnap, type PlacedJoint, RAIL_GAUGE_INCHES, type ResolvedAnchor, type ReturnLoopGeometry, type ReturnLoopShape, type RouteSpan, type RunInsertion, type SchematicBlock, type SchematicControlPoint, type SchematicCrossing, type SchematicEndplate, type SchematicEndplateTrack, type SchematicIndustry, type SchematicSection, type SchematicSignal, type SchematicTrack, type SchematicTurnout, type SectionAdjacency, type SectionEnd, type SectionEndAssessment, type SectionFootprint, type SectionJointAssessment, type SectionRelativePos, type SignalFacing, type SignalSide, type SpanOverhang, type StoredTrackPart, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, type TrackConfig, type TrackGraph, type TrackPart, type TrackPiece, type TrackRole, type TurnoutClosure, type TurnoutIdentity, type TurnoutKind, type UsableCapacity, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverAssembly, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToGraph, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, genericTurnoutPart, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleConversionReport, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, provisionalParts, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
package/dist/index.js CHANGED
@@ -1701,6 +1701,33 @@ var FAST_TRACKS_N_ME55_CROSSOVERS = [
1701
1701
  };
1702
1702
  });
1703
1703
  var DEFAULT_FLEX_PART_ID = "atlas-c55-n-flex";
1704
+ var GENERIC_TURNOUT_FROG_NUMBERS = [4, 5, 6, 7, 8, 10];
1705
+ function genericTurnoutPart(frogNumber, library = ATLAS_CODE55_N) {
1706
+ const derived = "derived";
1707
+ const lead = leadInchesForSize(frogNumber, library);
1708
+ const past = pastFrogInchesForSize(frogNumber, library);
1709
+ const why = `Interpolated across the measured parts by frog number \u2014 a stand-in, not a reading. No points offset: it is not a function of the frog number (the measured #5, #7 and #10 read 1.75\u2033, 0.625\u2033 and 0.5625\u2033), so this part begins AT the points, as a hand-laid turnout does.`;
1710
+ return {
1711
+ id: `generic-turnout-${frogNumber}`,
1712
+ manufacturer: "Generic",
1713
+ line: "N scale",
1714
+ scale: "N",
1715
+ name: `#${frogNumber} Turnout (make unknown)`,
1716
+ kind: "turnout",
1717
+ frogNumber,
1718
+ provisional: true,
1719
+ pointsOffset: { inches: 0, source: derived, note: why },
1720
+ lead: { inches: lead, source: derived, note: why },
1721
+ frogOffset: { inches: lead, source: derived, note: why },
1722
+ overallLength: { inches: lead + past, source: derived, note: why }
1723
+ };
1724
+ }
1725
+ var GENERIC_TURNOUTS = GENERIC_TURNOUT_FROG_NUMBERS.map(
1726
+ (n) => genericTurnoutPart(n)
1727
+ );
1728
+ function provisionalParts(library = BUILT_IN_TRACK_PARTS) {
1729
+ return library.filter((p) => p.provisional);
1730
+ }
1704
1731
  var GENERIC_END_OF_TRACK = [
1705
1732
  {
1706
1733
  id: "generic-bumper",
@@ -1716,7 +1743,11 @@ var BUILT_IN_TRACK_PARTS = [
1716
1743
  ...FAST_TRACKS_N_ME55,
1717
1744
  ...FAST_TRACKS_N_ME55_CROSSOVERS,
1718
1745
  ...FLEX_TRACK_PARTS,
1719
- ...GENERIC_END_OF_TRACK
1746
+ ...GENERIC_END_OF_TRACK,
1747
+ // ⚠️ LAST, AND PROVISIONAL. These are stand-ins, not products; every path that
1748
+ // resolves a turnout automatically filters them out, and every picker that
1749
+ // offers them must say what they are.
1750
+ ...GENERIC_TURNOUTS
1720
1751
  ];
1721
1752
  function flexParts(library = BUILT_IN_TRACK_PARTS) {
1722
1753
  return library.filter((p) => p.kind === "flex");
@@ -1844,7 +1875,9 @@ function partExtentForSize(size, library = BUILT_IN_TRACK_PARTS) {
1844
1875
  return part && part.frogNumber === size ? partExtent(part) : null;
1845
1876
  }
1846
1877
  function turnoutPartForSize(size, library = BUILT_IN_TRACK_PARTS) {
1847
- const turnouts = library.filter((p) => p.kind === "turnout" && p.frogNumber != null);
1878
+ const turnouts = library.filter(
1879
+ (p) => p.kind === "turnout" && p.frogNumber != null && !p.provisional
1880
+ );
1848
1881
  if (!turnouts.length) return null;
1849
1882
  const dist = (p) => Math.abs(p.frogNumber - size);
1850
1883
  return turnouts.reduce((best, p) => {
@@ -1857,12 +1890,12 @@ function turnoutPartForSize(size, library = BUILT_IN_TRACK_PARTS) {
1857
1890
  }
1858
1891
  function measuredLeadPoints(library) {
1859
1892
  return library.filter(
1860
- (p) => p.kind === "turnout" && p.frogNumber != null && p.lead?.source === "measured"
1893
+ (p) => p.kind === "turnout" && p.frogNumber != null && p.lead?.source === "measured" && !p.provisional
1861
1894
  ).map((p) => ({ n: p.frogNumber, lead: p.lead.inches })).sort((a, b) => a.n - b.n);
1862
1895
  }
1863
1896
  function leadInchesForSize(size, library = BUILT_IN_TRACK_PARTS) {
1864
1897
  const exact = library.find(
1865
- (p) => p.kind === "turnout" && p.frogNumber === size && p.lead != null
1898
+ (p) => p.kind === "turnout" && p.frogNumber === size && p.lead != null && !p.provisional
1866
1899
  );
1867
1900
  if (exact) return exact.lead.inches;
1868
1901
  const pts = measuredLeadPoints(library);
@@ -3163,7 +3196,9 @@ function deriveGraphDoc(doc, library = BUILT_IN_TRACK_PARTS) {
3163
3196
  return { doc: out.doc, warnings: out.warnings };
3164
3197
  }
3165
3198
  function placeableTurnoutParts(library, kind) {
3166
- return library.filter((p) => kind.includes(p.kind) && partGeometryGap(p) == null);
3199
+ return library.filter(
3200
+ (p) => kind.includes(p.kind) && !p.provisional && partGeometryGap(p) == null
3201
+ );
3167
3202
  }
3168
3203
  function moduleConversionReport(doc, library = BUILT_IN_TRACK_PARTS) {
3169
3204
  if (doc.graph?.pieces?.length) {
@@ -3244,6 +3279,15 @@ function moduleConversionReport(doc, library = BUILT_IN_TRACK_PARTS) {
3244
3279
  candidates
3245
3280
  };
3246
3281
  });
3282
+ const mainIds = new Set((doc.tracks ?? []).filter((t) => t.role === "main").map((t) => t.id));
3283
+ for (const t of doc.turnouts ?? []) {
3284
+ if (!mainIds.has(t.divergeTrack)) continue;
3285
+ blockers.push({
3286
+ kind: "turnout-opens-a-main",
3287
+ ref: t.id,
3288
+ why: `${t.name || t.id} opens ${t.divergeTrack}, which is a main \u2014 a main that begins at a turnout cannot be laid as pieces yet, and converting anyway would drop both it and the turnout`
3289
+ });
3290
+ }
3247
3291
  for (const c of doc.crossings ?? [])
3248
3292
  blockers.push({
3249
3293
  kind: "crossing",
@@ -4258,6 +4302,6 @@ function poseOverridesFromDoc(doc) {
4258
4302
  return out;
4259
4303
  }
4260
4304
 
4261
- export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, GENERIC_END_OF_TRACK, JOINT_SNAP_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, PINCH_EASE_INCHES, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverAssembly, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToGraph, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleConversionReport, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
4305
+ export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, BUMPER_DRAWN_INCHES, CLEARANCE_SPACING_INCHES, CODE55_RAIL_HEIGHT_INCHES, DEFAULT_FLEX_PART_ID, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, FAST_TRACKS_N_ME55, FAST_TRACKS_N_ME55_CROSSOVERS, FLEX_TRACK_PARTS, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_MAIN_MIN_RADIUS_INCHES, FREEMO_REVERSE_CURVE_STRAIGHT_INCHES, FREEMO_TRACK_SPACING_INCHES, GENERIC_END_OF_TRACK, GENERIC_TURNOUTS, GENERIC_TURNOUT_FROG_NUMBERS, JOINT_SNAP_INCHES, MAIN2_TRACK_ID, MAIN_TRACK_ID, N_CAR_LENGTH_INCHES, N_SCALE_RATIO, PINCH_EASE_INCHES, RAIL_GAUGE_INCHES, TIE_HALF_LENGTH_INCHES, TRACK_PART_KINDS, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, assessSectionEnd, assessSectionJoint, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTrackGraph, buildTransition, carCapacity, checkEndplateWidth, clearancePointPastFrogInches, crossoverAssembly, crossoverPinches, deriveEndplatePoses, deriveGraphDoc, divergeSideForHand, docToGraph, docToState, emptyEditorState, endplateCentreOffsetInches, endplateEdgePose, endplateFaceSegments, endplateLead, endplateTrackOffsetInches, endplateWidthInches, fitFlexBetween, flexPartFor, flexParts, flexPieces, flexRunEnd, flexUsage, frogCasting, frogNumberFromName, fromSectionRelative, genericTurnoutPart, geometryTurnDegrees, graphToDoc, hasNoFarEndplate, importedPartToTrackPart, inchesToScaleFeet, insertIntoRun, isLoopDoc, isTransitionTurnout, laneOffsetAt, leadInchesForSize, maxFlexPieceInches, mergeImportedParts, mergeStoredParts, moduleCenterline, moduleConversionReport, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partExtent, partExtentForSize, partGeometry, partGeometryGap, partOutlineAtFrog, partsPlaceable, pastFrogInchesForSize, pathLengthInches, pieceHand, piecePartNumber, pieceRoutePaths, placedJoints, poseNeedsManual, poseOverridesFromDoc, provisionalParts, remapPos, resizeFlexPiece, resolveGraphAnchor, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionalArcInches, sectionedCenterline, sectionedEndPose, sliceCenterline, snapPiece, spanOverhang, stateToDoc, storedPartToTrackPart, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutFacing, turnoutOccupiedSpan, turnoutPartForSize, usableCapacity, walkTrackGraph };
4262
4306
  //# sourceMappingURL=index.js.map
4263
4307
  //# sourceMappingURL=index.js.map