diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..631f049
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,147 @@
+# Changelog
+
+Detail behind each commit. Commit messages stay high level; the reasoning, the measurements, and
+the things that turned out to be wrong live here.
+
+Measured figures are 100 solitaire Standard games with the developer bot unless stated otherwise.
+The target is 20 Revenue over 5 Days.
+
+---
+
+## Unreleased
+
+Nothing yet.
+
+---
+
+## Board rendering, three-page site, curve geometry
+
+Drawing the board as track, splitting the site, tooltips, and the curve fix.
+
+### Board rendering
+
+Two renderers in `src/sim/board-svg.ts`, chosen because they fail in opposite places:
+
+- **Office Area** — the district stays a map. Cards on a grid with the rails drawn edge to edge, so
+ a join is rail meeting rail rather than two descriptions that happen to agree. The through rail
+ sits at a constant height on every card, which is the alignment the printed cards use.
+- **The Division** — not a map but a queue of sections with hard capacities, so it is a dispatcher's
+ diagram: one line per track, `1 of 2 free` under each section, `no limit — trains queue` at the
+ Division Points.
+
+Both are **self-contained** — no imports, no module-level helpers — because the playable app imports
+them normally while the replay is a single HTML file with an inline script that cannot import
+anything, and embeds them via `Function.toString()`. One implementation either way; a second copy
+would eventually draw a different board from the same state.
+
+Rails come from the engine's own `connectionsFor`, now exported. A drawn rail cannot claim a
+connection the rules do not have — visible in that **Modifier cards draw no rails at all**.
+
+Capacity, confirmed from the rules and now shown: Division Points unlimited, most Mainline cards 1,
+Double Track and Uncontrolled Siding 2, Offices 1/2/3/4 by tier.
+
+### Three pages
+
+`index.html` is now a splash with two doors. The game moved to `play.html`; `replays.html` is a
+directory.
+
+**A replay is a save**, and a save is `{seed, history}`. The engine is deterministic and runs in the
+browser, so re-submitting the same moves rebuilds the position exactly — **18 KB instead of 3.4 MB**,
+about 190× smaller, small enough to email. A save that would describe an impossible position cannot
+be replayed at all, because every step goes back through `applyIntent`; the viewer stops and says so
+rather than showing a board the rules could not produce.
+
+Static hosting cannot list a directory, so `replays/manifest.json` is generated at build time from
+whatever is in `public/replays/`, with each file validated first.
+
+### Tooltips
+
+Reference detail is read once and printing it costs the space the board and action list need. A
+single delegated tooltip (`src/web/tooltip.ts`) now carries card effects, action reasoning, and
+facility state. Not the native `title`: that waits a second, cannot be styled, and never appears for
+keyboard users.
+
+### Curve geometry — the significant fix
+
+A curve was modelled as a through track **plus** a diverging leg, which is a turnout. Consequences:
+
+- Curves were **topologically identical duplicates of turnouts** — same connections, no distinction
+ beyond the sharp curve's 2-Move cost.
+- Every diverging leg went south, so **no piece anywhere reached north** except an n-s straight,
+ which connects n↔s and nothing else.
+- Therefore a district could only ever be a **vertical column**: no siding, no parallel track, no
+ run-around, no second turnout back to the main.
+
+The printed cards (`docs/tracks.png`, rows 3–4) show a curve as a single arc from edge to edge with
+no through track. A curve is now a **two-port arc**, rotatable to `ne`/`nw`/`se`/`sw`. A sharp curve
+is geometrically identical and costs 2 Moves. Turnouts keep §A.1 unchanged — a two-port arc has no
+third port, so the absent-edge rule cannot apply to it.
+
+Verified through the engine, not the types: a crew leaves the main at a turnout, runs a siding
+parallel, and rejoins at the far end.
+
+### Measurements
+
+| | revenue | freight | sidings built |
+| --- | --- | --- | --- |
+| before | 4.1 | 0.5 | impossible |
+| geometry only | **3.9** | 0.9 | possible, not sought |
+| bot builds sidings | 3.3 | **1.1** | **59/60 games** |
+
+Freight more than doubled and the harness recorded **its first win**, but overall revenue is down
+from geometry-alone and the bad tail worsened (−29 → −59).
+
+Capping turnouts at one or two measured **worse** (revenue 2.5, freight 0.6) — more ways off the main
+means more industries the crew can reach, and that beats a tidy Running Track. The uncapped version
+stands, with that measurement recorded at the code.
+
+**The bot builds sidings but does not exploit them.** It pays about 20 of its 26 track pieces for
+them while its switching logic still sets out dead weight on a spur rather than planning a
+run-around. That is the next piece of work and where the revenue should appear.
+
+---
+
+## Earlier commits
+
+Recorded from memory of the work rather than written at the time; detail thins going back.
+
+### `f00255c` — more fixes and tweaks
+
+Card descriptions on every card in hand and every face-up slot, the three Local Operations options
+explained, the objective and pace in the header, and rotations named in words rather than
+"rotation 2". Build stamp added (version, git SHA, `-dirty` for an uncommitted tree) because nothing
+tracked what was deployed. Extra X22 was **not** a bug — a per-diem train whose card calls for a
+caboose and nothing else — but "loaded caboose" was.
+
+### `d1f689d` — name the caboose, the train and the Running Track hazard
+
+`maneuver.redFlags` was labelled "Red Flags on tray3": the earlier tray-id fix checked the history
+log, and the action list was a surface it missed. An industry on the Running Track does not block
+traffic (§11.2 gives it rails) but a car left standing there is hit by the next arrival (§10).
+
+### `dd300ac` — fix caching, Limits placement, and explain the board better
+
+The first deploy served a fresh `index.html` against a **cached** `main.js`, which threw
+`missing element: target` and never started. Every module import now carries the build tag. The
+Limits fix was half-done: the sign could move, but nothing forbade building past it, so one straight
+at (0,2) produced `limits · Whistle Post · limits · straight · limits`.
+
+### `2eca9de` — playable browser build
+
+The solitaire game as a static site, proven to need no server: full games run with every Node global
+replaced by a throwing stub. Train cards stopped accepting a board placement — seed 555 had offered
+Extra X15 at six squares with six rotations, all identical.
+
+### `160190d` — the bot's reasoning in the replay
+
+Decision panel showing what the bot chose, why, and every option it passed over, with the reasons
+reported by the bot itself rather than re-derived by the viewer.
+
+### `d261ad7` — parking trains, freight deadlock, Whistle Post lock-in
+
+Three faults found by measurement rather than failing tests. Trains parked because `destinationsFor`
+computed reverse as `facing === 'e' ? 'w' : 'e'`, so a crew facing south reversed to east — a port a
+north-south card does not have. Freight ran at a **3% load completion rate** because a load started
+with no spotted car parks on WORK and locks the industry track, blocking the very car that would
+clear it. Office density doubled after 25 of 100 games never drew a Depot and never escaped a
+one-track Whistle Post.
diff --git a/docs/design/board-first-pass.html b/docs/design/board-first-pass.html
new file mode 100644
index 0000000..d7fe2e4
--- /dev/null
+++ b/docs/design/board-first-pass.html
@@ -0,0 +1,65 @@
+
+
Board rendering — first pass
+Approach B (dispatcher’s diagram) for the Division, approach D (grid with real rails) for the Office Area. Every board below is a real bot-driven game, rendered by the same two functions the playable game and the replay both use. Hover any card or train for detail.
+MULTIPLAYER DIVISIONS — capacity is countable
+2 players · seed 79 · Day 1 Stage 11 · 7 sections · 3 train(s) on the Division · revenue [-10, -3]
West DP no limit — trains queue Heavy Grade climbs ▲ W 1 of 1 free ABS Signals Whistle Post TX20 0 of 1 free Hilly 1 of 1 free Depot T5 T1 0 of 2 free Uncontrolled Siding 2 of 2 free East DP no limit — trains queue
+3 players · seed 80 · Day 6 Stage 1 · 9 sections · 2 train(s) on the Division · revenue [0, -14, 4]
West DP no limit — trains queue Plains 1 of 1 free ABS Signals Terminal 4 of 4 free Double Track 2 of 2 free Whistle Post 1 of 1 free Heavy Grade climbs E ▲ T1 (1) 0 of 1 free Station 3 of 3 free Tunnel T10 (2) 0 of 1 free East DP no limit — trains queue
+4 players · seed 81 · Day 2 Stage 9 · 11 sections · 5 train(s) on the Division · revenue [3, -2, -3, -8]
West DP no limit — trains queue Yard T2 (1) 0 of 1 free ABS Signals Terminal 4 of 4 free Double Track 2 of 2 free Whistle Post 1 of 1 free Double Track T6 (1) 1 of 2 free Whistle Post 1 of 1 free Tunnel 1 of 1 free Depot T9 T3 0 of 2 free Double Track T7 (2) 1 of 2 free East DP no limit — trains queue
+5 players · seed 82 · Day 2 Stage 11 · 13 sections · 4 train(s) on the Division · revenue [1, 0, -10, 1, 2]
West DP TX22 no limit — trains queue Hilly TX20 (1) 0 of 1 free Station 3 of 3 free Uncontrolled Siding T12 (2) 1 of 2 free Whistle Post T11 0 of 1 free Plains 1 of 1 free Whistle Post 1 of 1 free Uncontrolled Siding 2 of 2 free Depot 2 of 2 free Heavy Grade climbs E ▲ 1 of 1 free Brakeman · Airbrakes Depot 2 of 2 free Yard 1 of 1 free East DP no limit — trains queue
+OFFICE AREAS — rails drawn, so a join is visible
+seed 430 · solitaire · the opening position — Limits, Whistle Post, Limits · 7 cards · 2 facilities · Office is a Depot
Depot 0,0 Freight House 0,-1 turnout 0,1 Limits 0,2 Rotary Dumps -1,0 Freight House 0,-2 Limits 0,-3 RUNNING TRACK
+seed 430 · solitaire · a few turns in: the Running Track starts to grow · 16 cards · 5 facilities · Office is a Depot
Depot 0,0 Freight House 0,-1 turnout 0,1 Freight House 0,2 Rotary Dumps -1,0 Freight House 0,-2 Refinery 0,-3 curve -1,1 Packing Sheds 0,3 straight -1,2 straight -1,3 Limits 0,4 straight -1,4 Limits 0,-4 straight -1,5 straight -1,6 RUNNING TRACK
+seed 430 · solitaire · mid-game, first industries down · 32 cards · 5 facilities · Office is a Terminal
Terminal 0,0 Freight House 0,-1 turnout 0,1 Freight House 0,2 Rotary Dumps -1,0 Freight House 0,-2 Refinery 0,-3 curve -1,1 Packing Sheds 0,3 straight -1,2 straight -1,3 turnout 0,4 straight -1,4 turnout 0,-4 straight -1,5 straight -1,6 straight -1,7 straight -1,8 Local Small Groceries -1,-1 straight -1,9 curve -1,10 turnout 0,-5 curve -1,-4 turnout 0,5 Truck Dock -1,-2 curve -1,-3 turnout 0,6 turnout 0,-6 curve -1,-5 Limits 0,7 Limits 0,-7 curve -1,-6 RUNNING TRACK
+seed 430 · solitaire · the winning game, fully grown · 37 cards · 7 facilities · Office is a Terminal
Terminal 0,0 Freight House 0,-1 turnout 0,1 Freight House 0,2 Rotary Dumps -1,0 Freight House 0,-2 Refinery 0,-3 curve -1,1 Packing Sheds 0,3 straight -1,2 straight -1,3 turnout 0,4 straight -1,4 turnout 0,-4 straight -1,5 straight -1,6 straight -1,7 straight -1,8 Local Small Groceries -1,-1 straight -1,9 curve -1,10 turnout 0,-5 curve -1,-4 cab emp turnout 0,5 Truck Dock -1,-2 curve -1,-3 turnout 0,6 turnout 0,-6 curve -1,-5 turnout 0,7 curve 0,-7 curve -1,-6 Freight House 0,8 Limits 0,-8 curve 0,9 Mine Tipple 0,10 Limits 0,11 RUNNING TRACK
+seed 202 · solitaire · a long Running Track with industries standing on it · 34 cards · 4 facilities · Office is a Station
Station 0,0 Overpass Freight House 0,-1 emp emp turnout 0,1 Freight House 0,2 emp Power Plant -1,0 emp emp emp curve -1,1 Packing Sheds 0,-2 straight -1,2 turnout 0,-3 straight -1,3 straight -1,4 Ice House -1,-1 straight -1,5 Forklifts -2,0 straight -1,6 straight -1,7 straight -1,8 straight -1,9 turnout 0,3 curve -1,10 turnout 0,4 turnout 0,-4 curve -1,-3 cab curve -1,-2 turnout 0,-5 curve -1,-4 cab turnout 0,5 turnout 0,6 curve 0,-6 Viscosity Breakers -2,1 curve -1,-5 curve 0,7 Limits 0,-7 Limits 0,8 RUNNING TRACK
+seed 111 · solitaire · a district hanging below the Running Track · 25 cards · 2 facilities · Office is a Depot
Depot 0,0 T7 Grocer's Warehouse 0,-1 emp turnout 0,1 turnout 0,2 Refinery -1,0 curve -1,1 straight -1,2 Yard Office T10 straight -1,3 Pipelines -1,-1 straight -1,4 straight -1,5 straight -1,6 straight -1,7 turnout 0,-2 straight -1,8 straight -1,9 curve -1,10 turnout 0,-3 Hotel -2,0 curve -1,-2 loa turnout 0,3 turnout 0,4 Limits 0,-4 curve -1,-3 Limits 0,5 RUNNING TRACK
+seed 80 · 3 players · three-player game, player 1 · 22 cards · 1 facility · Office is a Terminal
Terminal 0,0 turnout 0,-1 turnout 0,1 Power Plant 0,2 curve -1,1 straight -1,2 straight -1,3 straight -1,4 Ice House -1,0 T11 straight -1,5 straight -1,6 straight -1,7 straight -1,8 straight -1,9 Transmission Lines -1,-1 curve -1,10 turnout 0,-2 turnout 0,-3 turnout 0,3 curve -1,-2 cab Limits 0,4 Limits 0,-4 RUNNING TRACK
+seed 81 · 4 players · four-player game, player 1 · 19 cards · 2 facilities · Office is a Terminal
Terminal 0,0 T9 Refinery 0,-1 turnout 0,1 Limits 0,2 Grocer's Warehouse -1,0 curve -1,1 turnout 0,-2 straight -1,2 straight -1,3 Restaurant -1,-1 straight -1,4 straight -1,5 straight -1,6 straight -1,7 straight -1,8 straight -1,9 curve -1,10 Limits 0,-3 curve -1,-2 RUNNING TRACK
\ No newline at end of file
diff --git a/docs/design/board-layout-studies.html b/docs/design/board-layout-studies.html
new file mode 100644
index 0000000..9e4db9a
--- /dev/null
+++ b/docs/design/board-layout-studies.html
@@ -0,0 +1,41 @@
+Station Master — board layout studies Four ways to draw the same position, so that where a train is, which track it is on, and whether two cards actually join can be read at a glance rather than from a sentence. Nothing here is wired to the engine — these are drawings.
First: what the rules actually limit Where Trains allowed What happens if exceeded Division Point (either end) No limit trains simply queue Mainline card (most) 1 a follower needs the Superintendent’s clearance (§8.1) Double Track / Uncontrolled Siding 2+ — “trains may pass”no ruling needed at all Whistle Post 1 A/D tracknext arrival is an automatic collision Depot / Station / Terminal 2 / 3 / 4 same — collision, −5
So capacity is real and worth drawing: it is 1 almost everywhere on the Mainline, 2+ on exactly two card types, fixed by tier at an Office, and unbounded at the Division Points. That maps cleanly onto count the slots .
Office — fixed A/D tracks Division Point — unlimited Mainline card Limits Industry
A. Faithful cards — the tabletop, redrawnThe through rail sits at the same height on every card, so cards butt together and the line runs unbroken — which is exactly how the printed cards work. Every place a marker may stand is a printed square, so capacity is something you count rather than read.
THE DIVISION — west to east West DP unlimited ∞ Heavy Grade 1 train · climbs E YOUR DEPOT 2 A/D tracks Double Track 2 trains may pass East DP unlimited ∞ T3 T7 T12 T4 T5 Rail meets rail across every join. A square = one place a train may stand; ∞ = no limit. Strength: closest to the physical game; a player who has seen the cards needs no explanation. Cost: wide. Five cards already fill the strip, and a real Division has more.
B. Dispatcher’s diagram — count the linesHow a real dispatcher sees a division: one continuous line per running track, section boundaries as thin seams. Capacity is the number of parallel lines, and a train sits on a line.
THE DIVISION — dispatcher's track diagram West DP no limit — trains queue here Heavy Grade 1 track YOUR DEPOT 2 tracks Double Track 2 tracks East DP no limit — trains queue here T3 T9 T7 T12 A/D 2 free T4 T5 Count the lines to know the capacity. A train sits ON a line, so "which track" is never ambiguous. Loses the card-by-card feel, but nothing about connection or occupancy can be misread. Strength: nothing about occupancy or capacity can be misread, and it stays compact at any Division length. Cost: abandons the card metaphor entirely — terrain becomes a label rather than a picture.
C. Swimlanes — one lane per trackThe Running Track is the top lane and never moves. Each further track — A/D tracks, industry sidings — is its own lane beneath. Cards become columns, so a card that owns several tracks is simply taller.
YOUR OFFICE AREA — the Running Track never leaves the top lane RUNNING A/D 1 A/D 2 SIDING Limits straight DEPOT 2 A/D tracks — a 3rd arrival collides Freight House industry siding · 2 spots straight Limits T7 T12 One lane per track, running the full width. "Which track is that train on?" is answered by its row. Tall cards where a card owns several tracks; the Running Track stays a single unbroken line. Strength: “which track is that train on?” is answered by which row it is in, with no ambiguity anywhere. Cost: a tall card next to a short one looks ragged, and the district stops resembling a map.
D. The current grid, with the rails actually drawnThe smallest change: keep today’s grid and layout, but draw real rail edge to edge and real squares for standing room. A join becomes rail meeting rail instead of two descriptions that happen to agree.
YOUR OFFICE AREA — grid, with the rails actually drawn Limits straight DEPOT 2 A/D Freight House Limits turnout Refinery siding full — nothing more can be spotted T12 T7 Nearest to what exists now: same grid, but a join is visible as rail meeting rail. A curve leaving the Running Track is drawn, so a turnout that goes nowhere is obvious at a glance. Strength: preserves the map-like district, and a turnout whose leg goes nowhere becomes obvious. Cost: does least for the Mainline strip, which is where capacity confusion actually bites.
What I would do D for your Office Area, B for the Division strip.
They fail in opposite places. The district is a map you build, and it wants to stay a map — so draw the rails on the grid you already have (D). The Division is not a map; it is a queue of sections with hard capacities, which is precisely what a dispatcher’s diagram is for (B), and it stays readable however long the Division grows.
A is the most faithful and the most charming, and I would keep it in reserve: it is the right answer if this ever becomes a table you look down on rather than a panel you read. C solves the one question the others answer least well — which of several A/D tracks a train occupies — so if that turns out to be the confusion that matters most, C for the Office alone is worth revisiting.
Every drawing above shares one idea worth keeping whichever you pick: a square is a place a train may stand, and an empty square is spare capacity. That single convention makes “how many more trains fit here” answerable without a legend.
\ No newline at end of file
diff --git a/public/replays/seed-202.json b/public/replays/seed-202.json
new file mode 100644
index 0000000..8acb6af
--- /dev/null
+++ b/public/replays/seed-202.json
@@ -0,0 +1,1986 @@
+{
+ "seed": 202,
+ "history": [
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c8"
+ },
+ {
+ "type": "mainline.modify",
+ "cardId": "c106",
+ "node": 1
+ },
+ {
+ "type": "card.play",
+ "cardId": "c94",
+ "placement": {
+ "row": 0,
+ "col": 0
+ },
+ "variant": 0
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": 1
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c56",
+ "placement": {
+ "row": -1,
+ "col": 0
+ },
+ "variant": 1
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": 1
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c38",
+ "placement": {
+ "row": 0,
+ "col": -1
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 1
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 2
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c57",
+ "placement": {
+ "row": 0,
+ "col": -2
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 3
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 4
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c83",
+ "placement": {
+ "row": -1,
+ "col": -1
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 5
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c73",
+ "placement": {
+ "row": -2,
+ "col": 0
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "mainline.modify",
+ "cardId": "c107",
+ "node": 3
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 6
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 7
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c0"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 8
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 9
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c40",
+ "placement": {
+ "row": 0,
+ "col": 2
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c18"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": 10
+ },
+ "variant": 1
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": 3
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray1",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray1",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray1",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray1",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": -3
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c46",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": -3
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c33",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray1",
+ "to": {
+ "row": -1,
+ "col": -3
+ },
+ "reverse": false
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray1",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray1",
+ "to": {
+ "row": -1,
+ "col": 0
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray1",
+ "count": 1
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray1",
+ "count": 1
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray1",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray1",
+ "to": {
+ "row": 0,
+ "col": 0
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 2
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "carIndex": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "carIndex": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 2
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": -1,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c28"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": -2
+ },
+ "variant": 1
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "carType": "coach"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c33"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": -4
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray1",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray1",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray1",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "carType": "coach"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c14"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": -1,
+ "col": -4
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": 4
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c60",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": 5
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c115",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray2",
+ "to": {
+ "row": -1,
+ "col": -4
+ },
+ "reverse": false
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray2",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray2",
+ "to": {
+ "row": 0,
+ "col": -1
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray2",
+ "count": 1
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray2",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray2",
+ "to": {
+ "row": 0,
+ "col": 2
+ },
+ "reverse": false
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray2",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray2",
+ "to": {
+ "row": 0,
+ "col": 0
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.startLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ }
+ },
+ {
+ "type": "laborer.startLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ }
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": -5
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c79",
+ "placement": {
+ "row": -2,
+ "col": 1
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": -1,
+ "col": -5
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c46",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "hopper",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": 6
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c113",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": -6
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c60",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "laborer.startLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ }
+ },
+ {
+ "type": "laborer.startLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ }
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "reefer"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": 7
+ },
+ "variant": 1
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c110",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "from": "menAtWork",
+ "index": 0
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carIndex": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "from": "menAtWork",
+ "index": 1
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "boxcar",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "boxcar",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "boxcar",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "reefer"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "reefer"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "reefer"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "reefer"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c46",
+ "toSlot": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c105",
+ "toSlot": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c60",
+ "toSlot": 0
+ },
+ {
+ "type": "loadUnload.end"
+ }
+ ],
+ "title": "A busy district",
+ "note": "freight worked through a siding, and a collision to inspect"
+}
\ No newline at end of file
diff --git a/public/replays/seed-430.json b/public/replays/seed-430.json
new file mode 100644
index 0000000..fc90272
--- /dev/null
+++ b/public/replays/seed-430.json
@@ -0,0 +1,1808 @@
+{
+ "seed": 430,
+ "history": [
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c25"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": 1
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c81",
+ "placement": {
+ "row": -1,
+ "col": 0
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c38",
+ "placement": {
+ "row": 0,
+ "col": -1
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c39",
+ "placement": {
+ "row": 0,
+ "col": -2
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "carType": "coach"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": 1
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c37",
+ "placement": {
+ "row": 0,
+ "col": 2
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 2
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 3
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c59",
+ "placement": {
+ "row": 0,
+ "col": 3
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 4
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c48",
+ "placement": {
+ "row": 0,
+ "col": -3
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 5
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c14"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 6
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c16"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 7
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 8
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c85",
+ "placement": {
+ "row": -1,
+ "col": -1
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "porter.detrain",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "straight",
+ "hand": "none",
+ "placement": {
+ "row": -1,
+ "col": 9
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": 10
+ },
+ "variant": 1
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c22",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c103",
+ "placement": {
+ "row": 0,
+ "col": 1
+ },
+ "variant": 0
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": -4
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c6"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": -4
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": 4
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c70",
+ "placement": {
+ "row": -1,
+ "col": -2
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c31"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "left",
+ "placement": {
+ "row": -1,
+ "col": -3
+ },
+ "variant": 1
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "carType": "coach"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "left",
+ "placement": {
+ "row": 0,
+ "col": 5
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c109",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": -5
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c97",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": -1,
+ "col": -5
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c101",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "mainline.modify",
+ "cardId": "c108",
+ "node": 1
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": 6
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": -6
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c99",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c34"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": -1,
+ "col": -6
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "carType": "coach"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "turnout",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": 7
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c79",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "porter.detrain",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "porter.board",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "porter.detrain",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": 0,
+ "col": -1
+ },
+ "reverse": false
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray3",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": 0,
+ "col": 0
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "carType": "coach"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.startLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ }
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": -7
+ },
+ "variant": 0
+ },
+ {
+ "type": "card.play",
+ "cardId": "c40",
+ "placement": {
+ "row": 0,
+ "col": 8
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "track.lay",
+ "geometry": "curved",
+ "hand": "right",
+ "placement": {
+ "row": 0,
+ "col": 9
+ },
+ "variant": 1
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c56",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromDepartment",
+ "slot": 0
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c112",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": true
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "boxcar",
+ "loaded": true
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.discard",
+ "cardId": "c117",
+ "toSlot": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c102",
+ "placement": {
+ "row": 0,
+ "col": 1
+ },
+ "variant": 0
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "porter.detrain",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "porter.board",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "porter.detrain",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 1
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": 0,
+ "col": -2
+ },
+ "reverse": false
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray3",
+ "count": 1
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray3",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": 0,
+ "col": 0
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "box": 0
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carIndex": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "carType": "coach"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 2
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.startLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ }
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c44",
+ "placement": {
+ "row": 0,
+ "col": 10
+ },
+ "variant": 1
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "hopper",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray3",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "laborer.startLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ }
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carType": "boxcar"
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "draw"
+ },
+ {
+ "type": "draw.fromHomeOffice"
+ },
+ {
+ "type": "card.play",
+ "cardId": "c17"
+ },
+ {
+ "type": "draw.end"
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "hopper",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "hopper",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "caboose",
+ "loaded": true
+ },
+ {
+ "type": "porter.board",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "porter.detrain",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "porter.board",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "laborer.beginUnload",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "carIndex": 0
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 2
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": -1,
+ "col": -4
+ },
+ "reverse": false
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray3",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": 0,
+ "col": -1
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray3",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": -1,
+ "col": -4
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": 0,
+ "col": -1
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray3",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": -1,
+ "col": -4
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray3",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray3",
+ "to": {
+ "row": 0,
+ "col": 0
+ },
+ "reverse": true
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 1
+ },
+ {
+ "type": "laborer.advanceLoad",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "box": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "porter.board",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "porter.detrain",
+ "at": {
+ "row": 0,
+ "col": 0
+ }
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "switch"
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray2",
+ "to": {
+ "row": -1,
+ "col": -4
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray2",
+ "count": 1
+ },
+ {
+ "type": "switch.dropCars",
+ "trayId": "tray2",
+ "count": 1
+ },
+ {
+ "type": "switch.move",
+ "trayId": "tray2",
+ "to": {
+ "row": 0,
+ "col": 0
+ },
+ "reverse": true
+ },
+ {
+ "type": "switch.end"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": 0
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.clearInbound",
+ "at": {
+ "row": 0,
+ "col": -2
+ },
+ "index": 0
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -3
+ },
+ "carType": "tank"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": -3
+ },
+ "carType": "tank"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 3
+ },
+ "carType": "reefer"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.stockOutbound",
+ "at": {
+ "row": 0,
+ "col": 10
+ },
+ "carType": "hopper"
+ },
+ {
+ "type": "loadUnload.end"
+ },
+ {
+ "type": "localOps.choose",
+ "option": "freightAgent"
+ },
+ {
+ "type": "freightAgent.unjam",
+ "at": {
+ "row": 0,
+ "col": -1
+ },
+ "from": "outbound",
+ "index": 0
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "hopper",
+ "loaded": false
+ },
+ {
+ "type": "newTrain.placeCar",
+ "trayId": "tray2",
+ "carType": "coach",
+ "loaded": false
+ },
+ {
+ "type": "loadUnload.end"
+ }
+ ],
+ "title": "A near miss",
+ "note": "revenue 19 against a target of 20 \u2014 one point short"
+}
\ No newline at end of file
diff --git a/scripts/build-web.ts b/scripts/build-web.ts
index 23d0887..73bee41 100644
--- a/scripts/build-web.ts
+++ b/scripts/build-web.ts
@@ -10,7 +10,7 @@
*/
import { execFileSync } from 'node:child_process';
-import { mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
+import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
@@ -26,6 +26,8 @@ execFileSync(
'tsc',
'--ignoreConfig',
'src/web/main.ts',
+ 'src/web/splash.ts',
+ 'src/web/replays.ts',
'--outDir', dist,
'--rootDir', 'src',
'--target', 'es2022',
@@ -107,10 +109,47 @@ function bustImports(dir: string): number {
const busted = bustImports(dist);
-const page = readFileSync(join(root, 'src/web/index.html'), 'utf8')
- .replaceAll('__BUILD__', stamp)
- .replace(/(
+