@willcgage/module-schematic 0.59.0 → 0.61.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 +69 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -3
- package/dist/index.d.ts +86 -3
- package/dist/index.js +68 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -394,6 +394,13 @@ declare function samplePath(pts: BenchworkPoint[], segsPerArc?: number): {
|
|
|
394
394
|
x: number;
|
|
395
395
|
y: number;
|
|
396
396
|
}[];
|
|
397
|
+
/**
|
|
398
|
+
* Arc length of an authored path, inches — the path's OWN length, independent of
|
|
399
|
+
* where it sits or which way it runs. A branch route to a third endplate (#181)
|
|
400
|
+
* has no meaningful extent along the module axis (a square 90° exit projects to
|
|
401
|
+
* zero), so its own length is the only honest measure of it.
|
|
402
|
+
*/
|
|
403
|
+
declare function pathLengthInches(path: BenchworkPoint[] | null | undefined): number;
|
|
397
404
|
/** Normalise an authored track path from a doc, or null if it isn't a real path
|
|
398
405
|
* (needs ≥ 2 valid points). Keeps per-vertex bulge. */
|
|
399
406
|
declare function trackPath(path: BenchworkPoint[] | null | undefined): BenchworkPoint[] | null;
|
|
@@ -951,13 +958,47 @@ interface DrawCrossover {
|
|
|
951
958
|
toPosFrac: number;
|
|
952
959
|
toLane: number;
|
|
953
960
|
}
|
|
954
|
-
/**
|
|
955
|
-
*
|
|
961
|
+
/**
|
|
962
|
+
* A route leaving the module at a third endplate (#170) — Main 3, whatever the
|
|
963
|
+
* owner labels it (#181). Drawn as an ELBOW: it diverges from its host main at
|
|
964
|
+
* `posFrac`, drops to its own `lane`, then runs to `endFrac` and ends at an
|
|
965
|
+
* endplate face.
|
|
966
|
+
*
|
|
967
|
+
* The run is the branch's OWN arc length laid along the strip, not its
|
|
968
|
+
* projection onto the module axis — a square 90° exit projects to zero, which
|
|
969
|
+
* is exactly the case that made branches invisible here. Straightening the
|
|
970
|
+
* route out at its true length is the same idiom this whole view applies to the
|
|
971
|
+
* main; `posFrac → endFrac` is therefore a real axis, and `lengthInches` maps
|
|
972
|
+
* onto it, so anything positioned along the branch has somewhere to draw.
|
|
973
|
+
*/
|
|
956
974
|
interface BranchConnector {
|
|
975
|
+
/** Endplate id — "C", "D", … */
|
|
957
976
|
id: string;
|
|
977
|
+
/** The endplate's label. MR draws no text (the destination depends on what's
|
|
978
|
+
* physically attached, so FD derives the panel label at runtime) — this is
|
|
979
|
+
* the owner's local name, for tooltips and FD's fallback. */
|
|
958
980
|
label: string;
|
|
981
|
+
/** The route's own name, from the track. */
|
|
982
|
+
name: string;
|
|
983
|
+
/** The branch track's id. */
|
|
984
|
+
trackId: string;
|
|
985
|
+
/** Whether the route IS a main (a diverging/split main) or a secondary
|
|
986
|
+
* branch line. Drives drawn weight, not geometry. */
|
|
987
|
+
kind: "branch" | "main";
|
|
988
|
+
/** Where it leaves its host main. */
|
|
959
989
|
posFrac: number;
|
|
990
|
+
/** The host track's lane — a branch need not leave Main 1. Renderers must
|
|
991
|
+
* start the diverge HERE, not at a hard-coded lane 0. */
|
|
992
|
+
fromLane: number;
|
|
993
|
+
/** Which side of the module it exits. */
|
|
960
994
|
side: "up" | "down";
|
|
995
|
+
/** The branch's own lane, signed by `side` and placed clear of every other
|
|
996
|
+
* lane (so it never collides) — already folded into laneMin/laneMax. */
|
|
997
|
+
lane: number;
|
|
998
|
+
/** Where the run ends, and the endplate face is drawn. */
|
|
999
|
+
endFrac: number;
|
|
1000
|
+
/** The route's own arc length, inches. */
|
|
1001
|
+
lengthInches: number;
|
|
961
1002
|
}
|
|
962
1003
|
/** An industry — draw a car-spot span beside its track's lane, on `side`, with
|
|
963
1004
|
* a name label + an optional car/length readout (#industries). */
|
|
@@ -1383,6 +1424,48 @@ declare function turnoutClosure(size: number, opts?: {
|
|
|
1383
1424
|
* around 25″ on a #7 — clear of the Free-moN 22″ minimum. */
|
|
1384
1425
|
easeInches?: number;
|
|
1385
1426
|
}): TurnoutClosure;
|
|
1427
|
+
/** A frog casting's parts, in TURNOUT-LOCAL inches: `x` = distance past the
|
|
1428
|
+
* points, `y` = lateral offset from the through route. */
|
|
1429
|
+
interface FrogCasting {
|
|
1430
|
+
/** The point rail — the acute V, apex at the crossing, opening toward the
|
|
1431
|
+
* diverging end. Three points: through leg, apex, diverging leg. */
|
|
1432
|
+
point: Array<{
|
|
1433
|
+
x: number;
|
|
1434
|
+
y: number;
|
|
1435
|
+
}>;
|
|
1436
|
+
/** The two wing rails flanking the point, each a short polyline. */
|
|
1437
|
+
wings: Array<Array<{
|
|
1438
|
+
x: number;
|
|
1439
|
+
y: number;
|
|
1440
|
+
}>>;
|
|
1441
|
+
/** The apex — where the two inner rails actually cross. */
|
|
1442
|
+
apex: {
|
|
1443
|
+
x: number;
|
|
1444
|
+
y: number;
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
/**
|
|
1448
|
+
* The frog casting at a turnout's crossing.
|
|
1449
|
+
*
|
|
1450
|
+
* The apex is where the two INNER rails cross, which is HALF a gauge off the
|
|
1451
|
+
* through centre-line (the through inner rail sits at +g/2, the diverging inner
|
|
1452
|
+
* rail at d−g/2, and d = g at the frog). Not one full gauge — that is the
|
|
1453
|
+
* diverging CENTRE-line, and putting the casting there floats it clear of the
|
|
1454
|
+
* rails it is made of.
|
|
1455
|
+
*
|
|
1456
|
+
* ⚠️ **The flangeway is EXAGGERATED and that is deliberate.** True scale in N is
|
|
1457
|
+
* about 0.011″ (prototype 1¾″ ÷ 160) — one pixel in a close-up render and
|
|
1458
|
+
* invisible at module zoom. Drawn to scale the wing rails would sit exactly on
|
|
1459
|
+
* the running rails and add nothing. `flangewayInches` defaults to a readable
|
|
1460
|
+
* fraction of the gauge instead; pass the true figure if you ever need it.
|
|
1461
|
+
*/
|
|
1462
|
+
declare function frogCasting(cl: TurnoutClosure, opts?: {
|
|
1463
|
+
gaugeInches?: number;
|
|
1464
|
+
/** How far the casting runs either side of the apex. */
|
|
1465
|
+
reachInches?: number;
|
|
1466
|
+
/** See the warning above — exaggerated for legibility by default. */
|
|
1467
|
+
flangewayInches?: number;
|
|
1468
|
+
}): FrogCasting;
|
|
1386
1469
|
declare function divergeSideForHand(kind: TurnoutKind | undefined, stubDir: number,
|
|
1387
1470
|
/** The turnout is installed the other way round — the points face the far
|
|
1388
1471
|
* direction, which swaps the side the diverging route leaves on. */
|
|
@@ -1541,4 +1624,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
1541
1624
|
heading: number;
|
|
1542
1625
|
}>;
|
|
1543
1626
|
|
|
1544
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, 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, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, 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 OutlineFace, type PartAngle, type PartDimension, type PartEnd, 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, 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, endplateFaceSegments, endplateLead, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, mergeImportedParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partOutlineAtFrog, poseNeedsManual, poseOverridesFromDoc, remapPos, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutPartForSize };
|
|
1627
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, 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, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, 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 OutlineFace, type PartAngle, type PartDimension, type PartEnd, 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, 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, endplateFaceSegments, endplateLead, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, mergeImportedParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partOutlineAtFrog, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutPartForSize };
|
package/dist/index.d.ts
CHANGED
|
@@ -394,6 +394,13 @@ declare function samplePath(pts: BenchworkPoint[], segsPerArc?: number): {
|
|
|
394
394
|
x: number;
|
|
395
395
|
y: number;
|
|
396
396
|
}[];
|
|
397
|
+
/**
|
|
398
|
+
* Arc length of an authored path, inches — the path's OWN length, independent of
|
|
399
|
+
* where it sits or which way it runs. A branch route to a third endplate (#181)
|
|
400
|
+
* has no meaningful extent along the module axis (a square 90° exit projects to
|
|
401
|
+
* zero), so its own length is the only honest measure of it.
|
|
402
|
+
*/
|
|
403
|
+
declare function pathLengthInches(path: BenchworkPoint[] | null | undefined): number;
|
|
397
404
|
/** Normalise an authored track path from a doc, or null if it isn't a real path
|
|
398
405
|
* (needs ≥ 2 valid points). Keeps per-vertex bulge. */
|
|
399
406
|
declare function trackPath(path: BenchworkPoint[] | null | undefined): BenchworkPoint[] | null;
|
|
@@ -951,13 +958,47 @@ interface DrawCrossover {
|
|
|
951
958
|
toPosFrac: number;
|
|
952
959
|
toLane: number;
|
|
953
960
|
}
|
|
954
|
-
/**
|
|
955
|
-
*
|
|
961
|
+
/**
|
|
962
|
+
* A route leaving the module at a third endplate (#170) — Main 3, whatever the
|
|
963
|
+
* owner labels it (#181). Drawn as an ELBOW: it diverges from its host main at
|
|
964
|
+
* `posFrac`, drops to its own `lane`, then runs to `endFrac` and ends at an
|
|
965
|
+
* endplate face.
|
|
966
|
+
*
|
|
967
|
+
* The run is the branch's OWN arc length laid along the strip, not its
|
|
968
|
+
* projection onto the module axis — a square 90° exit projects to zero, which
|
|
969
|
+
* is exactly the case that made branches invisible here. Straightening the
|
|
970
|
+
* route out at its true length is the same idiom this whole view applies to the
|
|
971
|
+
* main; `posFrac → endFrac` is therefore a real axis, and `lengthInches` maps
|
|
972
|
+
* onto it, so anything positioned along the branch has somewhere to draw.
|
|
973
|
+
*/
|
|
956
974
|
interface BranchConnector {
|
|
975
|
+
/** Endplate id — "C", "D", … */
|
|
957
976
|
id: string;
|
|
977
|
+
/** The endplate's label. MR draws no text (the destination depends on what's
|
|
978
|
+
* physically attached, so FD derives the panel label at runtime) — this is
|
|
979
|
+
* the owner's local name, for tooltips and FD's fallback. */
|
|
958
980
|
label: string;
|
|
981
|
+
/** The route's own name, from the track. */
|
|
982
|
+
name: string;
|
|
983
|
+
/** The branch track's id. */
|
|
984
|
+
trackId: string;
|
|
985
|
+
/** Whether the route IS a main (a diverging/split main) or a secondary
|
|
986
|
+
* branch line. Drives drawn weight, not geometry. */
|
|
987
|
+
kind: "branch" | "main";
|
|
988
|
+
/** Where it leaves its host main. */
|
|
959
989
|
posFrac: number;
|
|
990
|
+
/** The host track's lane — a branch need not leave Main 1. Renderers must
|
|
991
|
+
* start the diverge HERE, not at a hard-coded lane 0. */
|
|
992
|
+
fromLane: number;
|
|
993
|
+
/** Which side of the module it exits. */
|
|
960
994
|
side: "up" | "down";
|
|
995
|
+
/** The branch's own lane, signed by `side` and placed clear of every other
|
|
996
|
+
* lane (so it never collides) — already folded into laneMin/laneMax. */
|
|
997
|
+
lane: number;
|
|
998
|
+
/** Where the run ends, and the endplate face is drawn. */
|
|
999
|
+
endFrac: number;
|
|
1000
|
+
/** The route's own arc length, inches. */
|
|
1001
|
+
lengthInches: number;
|
|
961
1002
|
}
|
|
962
1003
|
/** An industry — draw a car-spot span beside its track's lane, on `side`, with
|
|
963
1004
|
* a name label + an optional car/length readout (#industries). */
|
|
@@ -1383,6 +1424,48 @@ declare function turnoutClosure(size: number, opts?: {
|
|
|
1383
1424
|
* around 25″ on a #7 — clear of the Free-moN 22″ minimum. */
|
|
1384
1425
|
easeInches?: number;
|
|
1385
1426
|
}): TurnoutClosure;
|
|
1427
|
+
/** A frog casting's parts, in TURNOUT-LOCAL inches: `x` = distance past the
|
|
1428
|
+
* points, `y` = lateral offset from the through route. */
|
|
1429
|
+
interface FrogCasting {
|
|
1430
|
+
/** The point rail — the acute V, apex at the crossing, opening toward the
|
|
1431
|
+
* diverging end. Three points: through leg, apex, diverging leg. */
|
|
1432
|
+
point: Array<{
|
|
1433
|
+
x: number;
|
|
1434
|
+
y: number;
|
|
1435
|
+
}>;
|
|
1436
|
+
/** The two wing rails flanking the point, each a short polyline. */
|
|
1437
|
+
wings: Array<Array<{
|
|
1438
|
+
x: number;
|
|
1439
|
+
y: number;
|
|
1440
|
+
}>>;
|
|
1441
|
+
/** The apex — where the two inner rails actually cross. */
|
|
1442
|
+
apex: {
|
|
1443
|
+
x: number;
|
|
1444
|
+
y: number;
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
/**
|
|
1448
|
+
* The frog casting at a turnout's crossing.
|
|
1449
|
+
*
|
|
1450
|
+
* The apex is where the two INNER rails cross, which is HALF a gauge off the
|
|
1451
|
+
* through centre-line (the through inner rail sits at +g/2, the diverging inner
|
|
1452
|
+
* rail at d−g/2, and d = g at the frog). Not one full gauge — that is the
|
|
1453
|
+
* diverging CENTRE-line, and putting the casting there floats it clear of the
|
|
1454
|
+
* rails it is made of.
|
|
1455
|
+
*
|
|
1456
|
+
* ⚠️ **The flangeway is EXAGGERATED and that is deliberate.** True scale in N is
|
|
1457
|
+
* about 0.011″ (prototype 1¾″ ÷ 160) — one pixel in a close-up render and
|
|
1458
|
+
* invisible at module zoom. Drawn to scale the wing rails would sit exactly on
|
|
1459
|
+
* the running rails and add nothing. `flangewayInches` defaults to a readable
|
|
1460
|
+
* fraction of the gauge instead; pass the true figure if you ever need it.
|
|
1461
|
+
*/
|
|
1462
|
+
declare function frogCasting(cl: TurnoutClosure, opts?: {
|
|
1463
|
+
gaugeInches?: number;
|
|
1464
|
+
/** How far the casting runs either side of the apex. */
|
|
1465
|
+
reachInches?: number;
|
|
1466
|
+
/** See the warning above — exaggerated for legibility by default. */
|
|
1467
|
+
flangewayInches?: number;
|
|
1468
|
+
}): FrogCasting;
|
|
1386
1469
|
declare function divergeSideForHand(kind: TurnoutKind | undefined, stubDir: number,
|
|
1387
1470
|
/** The turnout is installed the other way round — the points face the far
|
|
1388
1471
|
* direction, which swaps the side the diverging route leaves on. */
|
|
@@ -1541,4 +1624,4 @@ declare function poseOverridesFromDoc(doc: ModuleSchematicDoc): Record<string, {
|
|
|
1541
1624
|
heading: number;
|
|
1542
1625
|
}>;
|
|
1543
1626
|
|
|
1544
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, 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, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, 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 OutlineFace, type PartAngle, type PartDimension, type PartEnd, 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, 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, endplateFaceSegments, endplateLead, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, mergeImportedParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partOutlineAtFrog, poseNeedsManual, poseOverridesFromDoc, remapPos, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutPartForSize };
|
|
1627
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, type BenchworkPoint, type BranchConnector, CODE55_RAIL_HEIGHT_INCHES, 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, FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES, FREEMO_ENDPLATE_WIDTH_MIN_INCHES, FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES, FREEMO_TRACK_SPACING_INCHES, 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 OutlineFace, type PartAngle, type PartDimension, type PartEnd, 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, 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, endplateFaceSegments, endplateLead, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, mergeImportedParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partOutlineAtFrog, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutPartForSize };
|
package/dist/index.js
CHANGED
|
@@ -115,6 +115,15 @@ function samplePath(pts, segsPerArc = 20) {
|
|
|
115
115
|
out.push({ x: pts[n - 1].x, y: pts[n - 1].y });
|
|
116
116
|
return out;
|
|
117
117
|
}
|
|
118
|
+
function pathLengthInches(path) {
|
|
119
|
+
const pts = trackPath(path);
|
|
120
|
+
if (!pts) return 0;
|
|
121
|
+
const poly = samplePath(pts);
|
|
122
|
+
let total = 0;
|
|
123
|
+
for (let i = 1; i < poly.length; i++)
|
|
124
|
+
total += Math.hypot(poly[i].x - poly[i - 1].x, poly[i].y - poly[i - 1].y);
|
|
125
|
+
return total;
|
|
126
|
+
}
|
|
118
127
|
function trackPath(path) {
|
|
119
128
|
const pts = (path ?? []).filter((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y)).map((p) => ({
|
|
120
129
|
x: p.x,
|
|
@@ -1473,6 +1482,32 @@ function turnoutClosure(size, opts = {}) {
|
|
|
1473
1482
|
}
|
|
1474
1483
|
};
|
|
1475
1484
|
}
|
|
1485
|
+
function frogCasting(cl, opts = {}) {
|
|
1486
|
+
const g = opts.gaugeInches ?? RAIL_GAUGE_INCHES;
|
|
1487
|
+
const w = opts.reachInches ?? g * 1.5;
|
|
1488
|
+
const fw = opts.flangewayInches ?? g * 0.12;
|
|
1489
|
+
const m = cl.frogSlope;
|
|
1490
|
+
const lead = cl.lead;
|
|
1491
|
+
const apex = { x: lead, y: g / 2 };
|
|
1492
|
+
const point = [
|
|
1493
|
+
{ x: lead + w, y: g / 2 },
|
|
1494
|
+
apex,
|
|
1495
|
+
{ x: lead + w, y: g / 2 + m * w }
|
|
1496
|
+
];
|
|
1497
|
+
const wings = [
|
|
1498
|
+
[
|
|
1499
|
+
{ x: lead - w, y: g / 2 - fw },
|
|
1500
|
+
{ x: lead - w * 0.35, y: g / 2 - fw },
|
|
1501
|
+
{ x: lead + w * 0.35, y: g / 2 - fw * 0.5 }
|
|
1502
|
+
],
|
|
1503
|
+
[
|
|
1504
|
+
{ x: lead - w, y: g / 2 + m * -w + fw },
|
|
1505
|
+
{ x: lead - w * 0.35, y: g / 2 + m * -w * 0.35 + fw },
|
|
1506
|
+
{ x: lead + w * 0.35, y: g / 2 + m * w * 0.35 + fw * 0.5 }
|
|
1507
|
+
]
|
|
1508
|
+
];
|
|
1509
|
+
return { point, wings, apex };
|
|
1510
|
+
}
|
|
1476
1511
|
function divergeSideForHand(kind, stubDir, flipped) {
|
|
1477
1512
|
if (kind !== "left" && kind !== "right") return 0;
|
|
1478
1513
|
const s = (stubDir >= 0 ? 1 : -1) * (flipped ? -1 : 1);
|
|
@@ -1539,7 +1574,7 @@ function moduleFeatures(doc) {
|
|
|
1539
1574
|
if (parentLane === 0) {
|
|
1540
1575
|
const [from, to] = ext;
|
|
1541
1576
|
const far = Math.abs(to - sw.pos) >= Math.abs(from - sw.pos) ? to : from;
|
|
1542
|
-
const s = divergeSideForHand(sw.kind, far - sw.pos);
|
|
1577
|
+
const s = divergeSideForHand(sw.kind, far - sw.pos, sw.flipped);
|
|
1543
1578
|
sign = s !== 0 ? s : Math.sign(trk.lane) || 1;
|
|
1544
1579
|
} else {
|
|
1545
1580
|
sign = Math.sign(parentLane) || 1;
|
|
@@ -1654,15 +1689,43 @@ function moduleFeatures(doc) {
|
|
|
1654
1689
|
laneA: trackLane.get(x.tracks?.[0] ?? "") ?? 0,
|
|
1655
1690
|
laneB: trackLane.get(x.tracks?.[1] ?? "") ?? 1
|
|
1656
1691
|
}));
|
|
1692
|
+
const main2Lane = trackLane.has(MAIN2_TRACK_ID) ? trackLane.get(MAIN2_TRACK_ID) : null;
|
|
1693
|
+
const baseLanes = [
|
|
1694
|
+
0,
|
|
1695
|
+
main2Lane ?? (doubleMain ? 1 : 0),
|
|
1696
|
+
...extraTracks.map((t) => t.lane),
|
|
1697
|
+
...signals.map((s) => s.lane),
|
|
1698
|
+
...crossings.flatMap((x) => [x.laneA, x.laneB]),
|
|
1699
|
+
...crossovers.flatMap((x) => [x.fromLane, x.toLane])
|
|
1700
|
+
];
|
|
1701
|
+
let upLane = Math.max(...baseLanes, 0);
|
|
1702
|
+
let downLane = Math.min(...baseLanes, 0);
|
|
1657
1703
|
const branchConnectors = doc.endplates.filter(
|
|
1658
1704
|
(e) => e.id !== "A" && e.id !== "B" && e.at && !!e.trackId && (doc.tracks ?? []).some((t) => t.id === e.trackId)
|
|
1659
1705
|
).map((e) => {
|
|
1706
|
+
const trk = (doc.tracks ?? []).find((t) => t.id === e.trackId);
|
|
1660
1707
|
const sw = (doc.turnouts ?? []).find((t) => t.divergeTrack === e.trackId);
|
|
1708
|
+
const startPos = sw ? sw.pos : e.at.pos;
|
|
1709
|
+
const side = e.at.side === "down" ? "down" : "up";
|
|
1710
|
+
const lane = side === "down" ? --downLane : ++upLane;
|
|
1711
|
+
const runInches = pathLengthInches(trk.path) || Math.abs(e.at.pos - startPos) || FREEMO_ENDPLATE_WIDTH_MIN_INCHES;
|
|
1712
|
+
const toB = e.at.pos >= startPos;
|
|
1713
|
+
const fits = (p) => p >= 0 && p <= len;
|
|
1714
|
+
const ahead = startPos + runInches;
|
|
1715
|
+
const behind = startPos - runInches;
|
|
1716
|
+
const endPos = toB && fits(ahead) ? ahead : !toB && fits(behind) ? behind : fits(toB ? behind : ahead) ? toB ? behind : ahead : ahead;
|
|
1661
1717
|
return {
|
|
1662
1718
|
id: e.id,
|
|
1663
1719
|
label: e.label ?? e.id,
|
|
1664
|
-
|
|
1665
|
-
|
|
1720
|
+
name: trk.trackName ?? "",
|
|
1721
|
+
trackId: trk.id,
|
|
1722
|
+
kind: e.kind === "main" ? "main" : "branch",
|
|
1723
|
+
posFrac: clampFrac(startPos),
|
|
1724
|
+
fromLane: sw ? trackLane.get(sw.onTrack) ?? 0 : 0,
|
|
1725
|
+
side,
|
|
1726
|
+
lane,
|
|
1727
|
+
endFrac: clampFrac(endPos),
|
|
1728
|
+
lengthInches: runInches
|
|
1666
1729
|
};
|
|
1667
1730
|
});
|
|
1668
1731
|
const industries = (doc.industries ?? []).flatMap((ind) => {
|
|
@@ -1687,15 +1750,7 @@ function moduleFeatures(doc) {
|
|
|
1687
1750
|
};
|
|
1688
1751
|
});
|
|
1689
1752
|
});
|
|
1690
|
-
const
|
|
1691
|
-
const allLanes = [
|
|
1692
|
-
0,
|
|
1693
|
-
main2Lane ?? (doubleMain ? 1 : 0),
|
|
1694
|
-
...extraTracks.map((t) => t.lane),
|
|
1695
|
-
...signals.map((s) => s.lane),
|
|
1696
|
-
...crossings.flatMap((x) => [x.laneA, x.laneB]),
|
|
1697
|
-
...crossovers.flatMap((x) => [x.fromLane, x.toLane])
|
|
1698
|
-
];
|
|
1753
|
+
const allLanes = [...baseLanes, ...branchConnectors.map((b) => b.lane)];
|
|
1699
1754
|
const loop = isLoopDoc(doc);
|
|
1700
1755
|
const main2 = doc.tracks.find((t) => t.id === MAIN2_TRACK_ID);
|
|
1701
1756
|
const main2Positioned = !!main2 && (main2.fromPos != null || main2.toPos != null) && !loop;
|
|
@@ -1986,6 +2041,6 @@ function poseOverridesFromDoc(doc) {
|
|
|
1986
2041
|
return out;
|
|
1987
2042
|
}
|
|
1988
2043
|
|
|
1989
|
-
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, CODE55_RAIL_HEIGHT_INCHES, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, 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, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateLead, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, mergeImportedParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partOutlineAtFrog, poseNeedsManual, poseOverridesFromDoc, remapPos, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutPartForSize };
|
|
2044
|
+
export { ATLAS_CODE55_N, BUILT_IN_TRACK_PARTS, CODE55_RAIL_HEIGHT_INCHES, ENDPLATE_FASCIA_CLEAR_INCHES, ENDPLATE_LEAD_INCHES, 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, TURNOUT_LEAD_INCHES_PER_FROG, WHOLE_MODULE_SECTION_ID, asModuleSchematic, benchworkBand, benchworkOutline, buildCrossover, buildPassingSiding, buildTransition, carCapacity, checkEndplateWidth, deriveEndplatePoses, divergeSideForHand, docToState, emptyEditorState, endplateFaceSegments, endplateLead, endplateTrackOffsetFor, endplateTrackOffsetInches, endplateWidthInches, frogCasting, frogNumberFromName, fromSectionRelative, geometryTurnDegrees, importedPartToTrackPart, inchesToScaleFeet, isLoopDoc, isTransitionTurnout, leadInchesForSize, mergeImportedParts, moduleCenterline, moduleFeatures, moduleFootprint, moduleLengthFromSections, moduleSections, nextId, parseXtpLibrary, partOutlineAtFrog, pathLengthInches, poseNeedsManual, poseOverridesFromDoc, remapPos, returnLoop, sampleBenchworkOutline, samplePartSegments, samplePath, scaleFeetToInches, sectionAdjacency, sectionBand, sectionBreaksFromSections, sectionComponents, sectionFootprints, sectionNeighbours, sectionSpans, sectionSpansOrWhole, sectionedCenterline, sectionedEndPose, sliceCenterline, stateToDoc, toSectionRelative, trackMeetsEndplateIssues, trackPart, trackPath, turnoutClosure, turnoutPartForSize };
|
|
1990
2045
|
//# sourceMappingURL=index.js.map
|
|
1991
2046
|
//# sourceMappingURL=index.js.map
|