From 56ef79d14a5e6a77490c9dea5737840e099c853c Mon Sep 17 00:00:00 2001 From: Jacob Babor Date: Fri, 26 Jun 2026 21:24:24 -0500 Subject: [PATCH] Prototype spatial GPS edge weights --- docs/compaction-handoff.md | 46 ++- docs/red4ext-logging-shim.md | 29 +- docs/traffic-system-debrief.md | 40 +- .../src/GeneratedSpatialRoadGrid.hpp | 382 ++++++++++++++++++ red4ext/EdgeWeightGPS/src/Main.cpp | 195 ++++++++- tools/generate_spatial_edge_grid.py | 327 +++++++++++++++ 6 files changed, 982 insertions(+), 37 deletions(-) create mode 100644 red4ext/EdgeWeightGPS/src/GeneratedSpatialRoadGrid.hpp create mode 100644 tools/generate_spatial_edge_grid.py diff --git a/docs/compaction-handoff.md b/docs/compaction-handoff.md index aedf4c5..183e004 100644 --- a/docs/compaction-handoff.md +++ b/docs/compaction-handoff.md @@ -6,8 +6,8 @@ Current date/time context: 2026-06-26, local timezone America/Chicago. - Installed RED4ext state is safe: the game plugin directory contains `EdgeWeightGPS.dll.disabled`, not an active `EdgeWeightGPS.dll`. -- Latest committed safe source before this update: `d68a874 Disable unstable - traffic scorer hook`. +- Latest committed safe source before this update: `55f4087 Document VAND GPS + search graph`. - Current source has `kEnableGpsTrafficEdgeWeightPatch = false` and `kEnableGpsLocalSearchHooks = false`. - The real route search is confirmed at `0x44f054`, called from @@ -44,6 +44,42 @@ Current date/time context: 2026-06-26, local timezone America/Chicago. highway/arterial corridors, or patch the navigation VAND graph/classes after extracting the relevant streamingsector resources. +## 2026-06-26 Spatial Edge-Cost Prototype + +- Added `tools/generate_spatial_edge_grid.py`, which combines + `work/raw-segment-json/all.traffic_persistent.json` lane flags with + `work/traffic-companions/json/all.lane_polygons.json` polygons. +- Generated + `red4ext/EdgeWeightGPS/src/GeneratedSpatialRoadGrid.hpp`. The grid is + 332 x 361 cells at 32 m/cell, origin `(-4640, -7392)`, with final cell + counts `H=7574`, `R=19617`, `G=20`, `P=996`, `unknown=91645`. +- Added disabled-by-default runtime plumbing behind + `kEnableGpsSpatialEdgeWeightPatch = false`. When enabled, it attaches only + `GPSRouteProducer 0x44cc7c` and `GPSEdgeCost 0x44f838` unless the old verbose + local-search probe is also enabled. +- The patch reads search-state vectors as `(world X, height, world Y)`, samples + the current endpoint, neighbor endpoint, and midpoint, chooses the strongest + spatial road class, then applies a multiplier after native `0x44f838` + returns. Current test multipliers are highway `0.62`, road `1.0`, + GPS-only `1.20`, pavement `1.35`, unknown `1.05`. +- The patch intentionally does not rewrite VAND point class bits. Static + materialization code branches on those bits later, so changing them in data is + riskier than adjusting cost at the edge-cost vtable slot. +- Fixed `DetourGpsEdgeCost` logging: native `0x44f838` indexes the provider + cost table by neighbor point class, not source point class. +- Build verification passed in the Fedora toolbox: + `toolbox run -c 2077 tools/build_red4ext_shim.sh`. +- The resulting DLL remains uninstalled. Game install still has only + `EdgeWeightGPS.dll.disabled`, not an active plugin DLL. + +Important caveat: + +- Runtime logs show long visible GPS routes are decomposed into many + `0x44cc7c` local searches. The `ret_rva=0x70aa22` caller with + `query_f78=10` and `query_ptr98_rva=0x8d76c4` mostly produces tiny connector + searches, not the whole route. Do not gate the spatial patch only on that + caller unless a later test proves it covers the desired route segment. + ## Current Installed State - Installed RED4ext plugin is disabled: @@ -76,12 +112,14 @@ In `red4ext/EdgeWeightGPS/src/Main.cpp`: - `kEnableGpsQueryLifecycleHooks = true` - `kEnableGpsRouteJobLifecycleHooks = false` - `kEnableGpsRouteJobStartTrace = false` +- `kEnableGpsSpatialEdgeWeightPatch = false` - `kEnableGpsLocalSearchHooks = false` - `kEnableRouteUiTraceHooks = false` If rebuilt with the current defaults, active hooks are query/async lifecycle -only. The local search/cost hooks below require `kEnableGpsLocalSearchHooks = -true`: +only. The spatial edge-cost patch requires `kEnableGpsSpatialEdgeWeightPatch = +true`. The full local search/cost hooks below require +`kEnableGpsLocalSearchHooks = true`: - query lifecycle: - `GPSQuerySubmit 0x70a42c` diff --git a/docs/red4ext-logging-shim.md b/docs/red4ext-logging-shim.md index 7af23c0..0785c9b 100644 --- a/docs/red4ext-logging-shim.md +++ b/docs/red4ext-logging-shim.md @@ -66,14 +66,23 @@ Current behavior: Active build note: -- The currently installed build is read-only. It disables provider class - multiplier overrides and enables GPS query lifecycle tracing plus local GPS - search tracing. +- The currently installed build is disabled on disk: + `EdgeWeightGPS.dll.disabled`. There is no active `EdgeWeightGPS.dll` in the + game plugin directory. +- Source defaults are still read-only for route behavior. They disable provider + class multiplier overrides and the spatial edge-cost patch, while keeping GPS + query lifecycle tracing available for probe builds. - The async route-job hooks are split behind `kEnableGpsRouteJobLifecycleHooks` and are disabled in the active probe; this keeps the log focused on `0x70a42c` submissions, `0x7094b8` result records, and local search/provider-cost stats. -- It hooks `GPSSearch` (`0x44f054`), `GPSRouteProducer` (`0x44cc7c`), +- `kEnableGpsSpatialEdgeWeightPatch` is a disabled-by-default implementation + path. When enabled, it hooks `GPSRouteProducer` (`0x44cc7c`) and + `GPSEdgeCost` (`0x44f838`), samples a generated traffic-lane spatial grid + using the search-state coordinates, and applies highway/road/pavement + multipliers to returned edge costs. +- The old verbose local-search probe is still available behind + `kEnableGpsLocalSearchHooks`. It hooks `GPSSearch` (`0x44f054`), `GPSResolveHandle` (`0x44e1a8`), `GPSEdgeCost` (`0x44f838`), and the two cost-provider filters `0x44ff68`/`0x450b08`. - The filter probe records pass/fail counts by point class and by the @@ -345,10 +354,14 @@ Current static producer lead: `(*(routePoint + 0x13) & 0x3f)`. The GPS planner is therefore weighted, but by a compact baked road-class table, not by traffic `maxSpeed` or lane connection probabilities. -- The active probe now hooks `0x44f054` and `0x44f838` read-only. It logs the - live provider vtable, the 64 class multipliers, start/target handles, and a - capped sample of edge-cost calls with point class IDs, masks, handles, and - returned costs. +- The read-only local-search probe can still hook `0x44f054` and `0x44f838` to + log the live provider vtable, the 64 class multipliers, start/target handles, + and a capped sample of edge-cost calls with point class IDs, masks, handles, + and returned costs. +- The new spatial edge-cost path is implemented but disabled by default. Its + generated grid is built from traffic lane polygons/flags, not from VAND point + classes, so it can bias the search toward highway cells without rewriting + VAND metadata that later materialization code branches on. Autodrive finding: diff --git a/docs/traffic-system-debrief.md b/docs/traffic-system-debrief.md index 4682f81..808e326 100644 --- a/docs/traffic-system-debrief.md +++ b/docs/traffic-system-debrief.md @@ -836,18 +836,30 @@ renamed to `EdgeWeightGPS.dll.disabled`. The main takeaway is still valuable, but narrower than first suspected: traffic lane flags are available in native route-side endpoint/candidate code, and `0x8d46cc` is an excellent landmark. It is not the city-wide graph-cost -function. The safer cost target is `0x44f838`, or a data patch against the -navigation `VAND` blobs it consumes. The next native work should avoid a full -detour of `0x8d46cc` and instead look for either: +function. -- a `0x44f838` edge-cost hook that classifies graph edges by spatial proximity - to highway/arterial corridors -- a navigation streamingsector patch that marks/weights selected `VAND` graph - points or edges -- an inline patch around the vanilla constants/branches if the selector proves - sufficient -- a safer result-stage rewrite only if upstream weighting cannot be patched - without desynchronizing the planner and renderer +The current prototype therefore targets `0x44f838` instead. It generates a +compact spatial grid from traffic lane polygons/flags and samples that grid +from the search-state coordinates passed to the edge-cost callback. The first +test multipliers are: + +```text +highway 0.62 +road 1.00 +GPSOnly 1.20 +pavement 1.35 +unknown 1.05 +``` + +This deliberately leaves VAND point class bits untouched. The materialization +path branches on those bits after search, so rewriting them in data could alter +route construction or instructions as well as cost. + +Runtime logs also show that long visible routes are decomposed into many local +`0x44cc7c` route-producer searches. The tempting world-map caller +`ret_rva=0x70aa22` mostly produced tiny connector searches in the resolver +logs, so the first spatial test should patch edge cost across route-producer +calls instead of gating only on that caller. ## Future Improvements @@ -861,8 +873,10 @@ Better versions of this mod could: polygons and highway flags - extract the full Night City navigation streamingsector set into workspace storage and summarize it with `tools/analyze_vand_navigation.py` -- implement a bounded `0x44f838` edge-cost hook or `VAND` data patch using that - join, rather than traffic `maxSpeed` +- tune the generated spatial grid resolution and multipliers after in-game A/B + tests +- add route-mode gating if the spatial edge-cost hook affects pedestrians, + autodrive, or other local navigation too broadly - inspect `GPSOnly` connector lanes if a later native trace proves they are consumed by the player GPS - build district-specific presets if a real data-cost surface is found diff --git a/red4ext/EdgeWeightGPS/src/GeneratedSpatialRoadGrid.hpp b/red4ext/EdgeWeightGPS/src/GeneratedSpatialRoadGrid.hpp new file mode 100644 index 0000000..52505e1 --- /dev/null +++ b/red4ext/EdgeWeightGPS/src/GeneratedSpatialRoadGrid.hpp @@ -0,0 +1,382 @@ +#pragma once + +#include +#include +#include + +namespace EdgeWeightGPS::Generated +{ +constexpr float kSpatialRoadGridMinX = -4640.0f; +constexpr float kSpatialRoadGridMinY = -7392.0f; +constexpr float kSpatialRoadGridCellSize = 32.0f; +constexpr uint32_t kSpatialRoadGridWidth = 332; +constexpr uint32_t kSpatialRoadGridHeight = 361; + +// Cell codes: H=highway, R=road, G=GPS-only, P=pavement, .=unknown. +// Generated by tools/generate_spatial_edge_grid.py from all.traffic_persistent and all.lane_polygons. +// Counts: H=7574 R=19617 G=20 P=996 unknown=91645. +constexpr std::array kSpatialRoadGridRows = {{ + ".....HHHHHHHHHHHH...........................................................................................................................................................................................................................................................................................................................", + ".....HHHHHHHHHHHHHHH........................................................................................................................................................................................................................................................................................................................", + ".....HHHHHHHHHHHHHHHH...................................RRR.................................................................................................................................................................................................................................................................................", + "...........HHHHHHHHHHH..................................RRR.................................................................................................................................................................................................................................................................................", + "...............HHHHHHHH.................................RRRR................................................................................................................................................................................................................................................................................", + ".................HHHHHH.................................RRRR................................................................................................................................................................................................................................................................................", + "..................HHHHHH................................RRRR................................................................................................................................................................................................................................................................................", + "...................HHHHH................................RRRR................................................................................................................................................................................................................................................................................", + "...................HHHHHH...............................RRRR................................................................................................................................................................................................................................................................................", + "....................HHHHHH..............................RRRR................................................................................................................................................................................................................................................................................", + ".....................HHHHH..............................RRRR................................................................................................................................................................................................................................................................................", + ".....................HHHHHH.............................RRRR................................................................................................................................................................................................................................................................................", + "......................HHHHHH...........................RRRRR................................................................................................................................................................................................................................................................................", + ".......................HHHHH..........................RRRRRR................................................................................................................................................................................................................................................................................", + ".......................HHHHHH....................RRRRRRRRRR.................................................................................................................................................................................................................................................................................", + "........................HHHHHH...............RRRRRRRRRRRRRR.................................................................................................................................................................................................................................................................................", + "........................HHHHHH...........RRRRRRRRRRRRRRRR...................................................................................................................................................................................................................................................................................", + ".........................HHHHHH......RRRRRRRRRRRRRRRRR......................................................................................................................................................................................................................................................................................", + "..........................HHHHHH....RRRRRRRRRRRRR...........................................................................................................................................................................................................................................................................................", + "..........................HHHHHH..RRRRRRRRRRR...............................................................................................................................................................................................................................................................................................", + "...........................HHHHHHRRRRRRRRRRRR...............................................................................................................................................................................................................................................................................................", + "............................HHHHHHRRRRR...RRR...............................................................................................................................................................................................................................................................................................", + "...............RRRR.........HHHHHHRRRR......................................................................................................................................................................................................................................................................................................", + "...............RRRRRRRRR....RHHHHHHR........................................................................................................................................................................................................................................................................................................", + "...............RRRRRRRRR..RRRRHHHHHH........................................................................................................................................................................................................................................................................................................", + "...............RRRRRRRRRRRRRRRRHHHHHH.......................................................................................................................................................................................................................................................................................................", + "................RRRRRRRRRRRRRRRHHHHHHH......................................................................................................................................................................................................................................................................................................", + "...............RRRRRRRRRRRRRRR..HHHHHH......................................................................................................................................................................................................................................................................................................", + ".........RRRRRRRRRRRRRRRRR.......HHHHHH.....................................................................................................................................................................................................................................................................................................", + "....RRRRRRRRRRRRRRRRRR............HHHHHH....................................................................................................................................................................................................................................................................................................", + "..RRRRRRRRRRRRRRRRR...............HHHHHHH...................................................................................................................................................................................................................................................................................................", + ".RRRRRRRRRRRRRR....................HHHHHH...................................................................................................................................................................................................................................................................................................", + "RRRRRRRR............................HHHHHH..................................................................................................................................................................................................................................................................................................", + "RRRRR................................HHHHHH.................................................................................................................................................................................................................................................................................................", + "RRRR.................................HHHHHHH................................................................................................................................................................................................................................................................................................", + "RRRR..................................HHHHHHH...............................................................................................................................................................................................................................................................................................", + "RRRR...................................HHHHHHR..............................................................................................................................................................................................................................................................................................", + "RRRR....................................HHHHHHRRR...........................................................................................................................................................................................................................................................................................", + ".RRR....................................RHHHHHHRR...........................................................................................................................................................................................................................................................................................", + ".RRR.....................................HHHHHHHRR..........................................................................................................................................................................................................................................................................................", + ".........................................RHHHHHHRRR.........................................................................................................................................................................................................................................................................................", + ".........................................RRHHHHHHRRR........................................................................................................................................................................................................................................................................................", + ".........................................RRRHHHHHHRR........................................................................................................................................................................................................................................................................................", + "..........................................RRHHHHHHHRR.......................................................................................................................................................................................................................................................................................", + "...........................................RRHHHHHHRR.......................................................................................................................................................................................................................................................................................", + "............................................RRHHHHHHR.......................................................................................................................................................................................................................................................................................", + "............................................RRRHHHHHR.......................................................................................................................................................................................................................................................................................", + ".............................................RRHHHHHRR......................................................................................................................................................................................................................................................................................", + ".............................................RRRHHHHRRR.........................................RRR.........................................................................................................................................................................................................................................", + "..............................................RRRRRRRRRR........................................RRR.........................................................................................................................................................................................................................................", + ".................................................RRRRRRRR.......................................RRR.........................................................................................................................................................................................................................................", + "..................................................RRRRRRRR........................RRRRRRRRRRRRRRRRR...................RRR...................................................................................................................................................................................................................", + "...................................................RRRRRRR....................RRRRRRRRRRRRRRRRRRRRRRRR................RRR...................................................................................................................................................................................................................", + "....................................................RRRRRRR...............RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.............RRR........RRR........................................................................................................................................................................................................", + "....................................................RRRRRRRR...........RRRRRRRRRRRRRRRR......RRRRRRRRRRRRRRRR.........RRR........RRR........................................................................................................................................................................................................", + ".....................................................RRRRRRR..........RRRRRRRRRRRR...............RRRRRRRRRRRRRRRR.....RRR........RRR........................................................................................................................................................................................................", + "......................................................RRRRRRR.......RRRRRRRRRRRR.....................RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR........................................................................................................................................................................................................", + "......................................................RRRRRRRR......RRRRRRR.RRRR........................RRRRRRRRRRRRRRRRRRRRRRRRRRRRRR......................................................................................................................................................................................................", + "......................................................RRRRRRRR.....RRRRRRRRRRRRR.........................RRR.RRRRRRRRRRRRRRRRRRRRRRRRR......................................................................................................................................................................................................", + "......................................................RRRRRRRRR...RRRRRRRRRRRRRR.........................RRR...................RRRRRRR......................................................................................................................................................................................................", + "........................................................RRRHHHHH.RRRRRRRRRRRRRR...................................................RRRR......................................................................................................................................................................................................", + "........................................................RRRHHHHHHRRRRR..RRRRRRR............................................RRR.....RRRR.....................................................................................................................................................................................................", + ".....................................................RRRRRRHHHHHHRRRRR.RRRRRRR.............................................RRR.....RRRR.....................................................................................................................................................................................................", + ".....................................................RRRRRRRHHHHHHRRR.RRRRRRRRRR...........................................RRR.....RRRR.....................................................................................................................................................................................................", + ".....................................................RRRRRRRRHHHHHH...RRRRRRRRRRRRRRRRRRRRRRRRRRRRPPPP.....................RRR.....RRRR.....................................................................................................................................................................................................", + ".....................................................RRRRR...HHHHHHH.RRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR..RRR......RRRR....................................................................................................................................................................................................", + ".....................................................RRRRR....HHHHHHRRRRR...RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR...............................................................................................................................................................................................", + "....................................................RRRRRRR....HHHHHHRRRR...RRRRRRRR....RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR............................................................................................................................................................................................", + "...................................................RRRRRRRRR....HHHHHHRR.....RRRRRRR......RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR............................................................................................................................................................................................", + "..................................................RRRRRRRRRRR...HHHHHHH.......RRRRRR.............RRRRRRRRRRRRRRRRRRRR......RRR....RRRRRRRRRRRRRR............................................................................................................................................................................................", + "................................................RRRRRRRRRRRRRR...HHHHHHH.......RRRRR............RRRRRRRRRRRRRRRRRRRRRRR....RRR....RRRRRRR...................................................................................................................................................................................................", + "...............................................RRRRRRR...RRRRR....HHHHHH........RRRRR.........RRRRRRRRRRRR....RRRRRRRRRRR..RRR....RRRRRRR...................................................................................................................................................................................................", + "..............................................RRRRRRR..RRRRRRRR....HHHHHH.......RRRRRR.......RRRRRRRRRRRR........RRRRRRRRRRRRRRRRRRRRRRRRR..................................................................................................................................................................................................", + "............................................RRRRRRRR..RRRRRRRRRR...RHHHHHH.......RRRRRR....RRRRRRRRRRR..............RRRRRRRRRRRRRRRRRRRRRRR.................................................................................................................................................................................................", + "...........................................RRRRRRR...RRRRRRRRRRRR.RRHHHHHHH.......RRRRRR..RRRRRRRRRRRR................RRRRRRRRRRRRRRRRRRRRR.................................................................................................................................................................................................", + "..........................................RRRRRRRRRRRRRRRRR.RRRRRRRRRHHHHHH........RRRRR.RRRRRRRR.RRR......................RRRRRRRR...RRRRRR................................................................................................................................................................................................", + ".......................................RRRRRRRRRRRRRRRRRRR..RRRRRRRRRRHHHHHHRRRR...RRRRRRRRRRRR............................RRRRRRRRR.RRRRRRRR...............................................................................................................................................................................................", + ".......................................RRRRRRRRRRRRRRRRR.....RRRRRRRRR.HHHHHHRRRR...RRRRRRRRRR................................RRRRRRRRRRRRRRRRRRRR..........................................................................................................................................................................................", + ".......................................RRRRRR...RRRRRRR.....RRRRRRRR....HHHHHHRRR....RRRRRRRR...................................RRRRRRRRRRRRRRRRRRR.........................................................................................................................................................................................", + ".......................................RRRRR..RRRRRRRR......RRRRRRR.....HHHHHHHRRR..RRRRRRRR.....................................RRRRRRR.RRRRRRRRRRRRRR.....................................................................................................................................................................................", + ".......................................RRRRRRRRRRRRRRRRRR.RRRRRRRR.......HHHHHHRRRRRRRRRRRRR......................................RRRRR...RRRRRRRRRRRRR.....................................................................................................................................................................................", + "........................................RRRRRRRRRRRRRRRRRRRRRRRRR.........HHHHHHRRRRRRRRRRRRR....................................RRRRR.....RRRRRRRRRRRR.....................................................................................................................................................................................", + ".........................................RRRRRRRRR.RRRRRRRRRRRR............HHHHHHRRRRRR.RRRRRR.................................RRRRRR......RRRRRRRRRRR......................................................................................................................................................................................", + ".........................................RRRRRRR...RRRRRRRRRRR.............HHHHHHHRRRR...RRRRRR..............................RRRRRRRR.......RRRR.RRRR.......................................................................................................................................................................................", + "........................................RRRRRRRR...RRRRRRRRRR...............HHHHHHHRR.....RRRRR............................RRRRRRRRRRR......RRRR............................................................................................................................................................................................", + "......................................RRRRRRRRRRR..RRRRRRRR..................HHHHHH.......RRRRRR..................RRRRRRRRRRRRRRRRRRRR.......RRR............................................................................................................................................................................................", + ".....................................RRRRRRRRRRRR..RRRRRRR....................HHHHHH.......RRRRRR..........RRRRRRRRRRRRRRRRRRRRR..RRRRR......RRR............................................................................................................................................................................................", + ".....................................RRRRRR.RRRRRRRRRRRRR.....................HHHHHHH.......RRRRRR.......RRRRRRRRRRRRRRRRRRRRR....RRRRR......RRR............................................................................................................................................................................................", + ".....................................RRRRR...RRRRRRRRRRR.......................HHHHHHH.......RRRRRR......RRRRRRRRRRRR.....RRRRR....RRRR......RRR............................................................................................................................................................................................", + ".....................................RRRR.....RRRRRRRR.........................RHHHHHH........RRRRR..RRRRRRRRR..RRRR.......RRRR..............RRR............................................................................................................................................................................................", + ".............................................RRRRRRRR.........................RRRHHHHHH.......RRRRRRRRRRRRRRR..............RRRRR............RRRR............................................................................................................................................................................................", + "........................................RRR.RRRRRRRRR........................RRRRRHHHHHH.......RRRRRRRRRRRRR................RRRR...........RRRRR............................................................................................................................................................................................", + "........................................RRRRRRRRRRRRRR......................RRRRRRHHHHHHH.......RRRRRRRRRRRR................RRRRR..........RRRRR............................................................................................................................................................................................", + "........................................RRRRRRRRRRRRRRR.......RRR.........RRRRRRRR.HHHHHHR.......RRRRR.......................RRRRRRR.......RRRRR............................................................................................................................................................................................", + "........................................RRRRRRRR..RRRRRR......RRRR.......RRRRRRR....HHHHHRP......RRRRRR......................RRRRRRRR......RRRRR............................................................................................................................................................................................", + ".......................................RRRRRRR.....RRRRR......RRRRR.....RRRRRRR......HHHHRR.......RRRRRR......................RRRRRRRR......RRRR............................................................................................................................................................................................", + ".................................RRRR.RRRRRRR......RRRRRR.....RRRRR...RRRRRRRR........RRRRRR.......RRRRRR..................RRRRRRRRRRRR......RRR............................................................................................................................................................................................", + ".................................RRRRRRRRRRR........RRRRRR....RRRRRRRRRRRRRRR.........RRRHHHH.......RRRRRR................RRRRRRRRRRRRR......RRR............................................................................................................................................................................................", + ".................................RRRRRRRRRR..........RRRRRR....RRRRRRRRRRRR...........RRRHHHHH......RRRRRR..............RRRRRRRRRRRRRRR....RRRRRRR..........................................................................................................................................................................................", + ".................................RRRRRRRR.............RRRRRR....RRRRRRRRRR.............RRHHHHH.RRRRRRRRRRRR............RRRRRRRR.....RRRRRRRRRRRRRRRR........................................................................................................................................................................................", + ".................................RRRRRRR...............RRRRR.....RRRRRRRR................HHHHHHRRRRRRRRRRRRR...........RRRRRR.......RRRRRRRRRRRRRRRRR.......................................................................................................................................................................................", + "...........................RRRRRRRRRRRRRR..............RRRRRR...RRRRRRR...................HHHHHHRRRRRRRRRRRRR..........RRRR......RRRRRRRRRRRRRRRRRRRRR......................................................................................................................................................................................", + "...........................RRRRRRRRRRRRRR...............RRRRRR.RRRRRRR....................HHHHHHHRRR....RRRRR..........RRRR...RRRRRRRRRRRRR....RRRRRRR......................................................................................................................................................................................", + "...........................RRRRRRRRRRRRRRRG......RRR.....RRRRRRRRRRRR......................HHHHHH.......RRRRRR.........RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR......................................................................................................................................................................................", + "............................RRRRRRRRRRRRRRG......RRRR.....RRRRRRRRRR........................HHHHHH.......RRRRRR.........RRRRRRRRRRRRR..RRRRRRRRRRRRRRR......................................................................................................................................................................................", + "............................RRRRRR.RRRRRRRG......RRRRR....RRRRRRRR...........................HHHHHH.......RRRRRR......RRRRRRRRRRRR.....RRRRRRRRRRR.RRR......................................................................................................................................................................................", + "............................GRRRRR.....GGGG......RRRRRR...RRRRRRR............................HHHHHHH.......RRRRRR..RRRRRRRRRRRR........RRRRRRRRRR..RRR.................RRR..................................................................................................................................................................", + "..............................RRRRR...............RRRRRRRRRRRRRR..............................HHHHHHH.......RRRRRRRRRRRRRRRRR..........RRRR..RRRR..RRR.................RRR..................................................................................................................................................................", + "..............................RRRRRR...............RRRRRRRRRRR.................................HHHHHH.......RRRRRRRRRRRRRRRRR..........RRR....RRRR.RRR.................RRR..................................................................................................................................................................", + "...............................RRRRRR..............RRRRRRRRRR...................................HHHHHH......RRRRRRRRRRR..RRRRRR........RRR....RRRR.RRR.................RRR..................................................................................................................................................................", + "................................RRRRRR..............RRRRRRRR.....................................HHHHHH.RRRRRRRRRRRR......RRRRR........RRRRRRRRRRRRRRR.................RRRR.................................................................................................................................................................", + ".................................RRRRR.............RRRRRRRR......................................HHHHHHRRRRRRRRRRRRR......RRRRR........RRRRRRRRRRRRRRR.................RRRR.................................................................................................................................................................", + ".................................RRRRRR...........RRRRRRRR........................................HHHHHHHRRRRRRRRRRRR......RRRR.......RRRRRRRRRRRRRRRR.................RRRR.................................................................................................................................................................", + "..................................RRRRRR.........RRRRRRRRR.........................................HHHHHHRRRRR..RRRRRR................RRRR.....RRRRRRR..................RRR.................................................................................................................................................................", + "...................................RRRRRR........RRRRRR.............................................RHHHHHRR.....RRRRRR...............RRRR....RRRRRRRR..................RRRR................................................................................................................................................................", + "....................................RRRRR........RRRR...............................................RHHHHHH.......RRRRRR..............RRRRRRRRRRRRRRRR.....RRRRR........RRRR...RRR..........................................................................................................................................................", + ".....................................RRRRR.........................................................RRHHHHHHR.......RRRRRRRR...........RRRRRRRRRRRRRRR....RRRRRRRRR......RRRR.RRRRR..........................................................................................................................................................", + ".....................................RRRRRR........................................................RRRHHHHHH.......RRRRRRRR...........RRRRRRRRRRR.RRR...RRRRRRRRRRRR....RRRRRRRRRR..........................................................................................................................................................", + "......................................RRRRRR.......................................................RRRRHHHHHH.......RRRRRRR...........RRR.RRRRRR.RRRRRRRRRRRRRRRRRRR.....RRRRRRRRR..........................................................................................................................................................", + ".......................................RRRRRR...........................................................HHHHHH.......RRRRRR...........RRR...RRRRRRRRRRRRRRRR...RRRRRR....RRRRRRRRRR.........................................................................................................................................................", + "........................................RRRRR...........................................................HHHHHHH.......RRRRR...........RRR....RRRRRRRRRRRRRR......RRRRR...RRRRRRRRRRRR.......................................................................................................................................................", + "......................................RRRRRRRR...........................................................HHHHHH.......RRRRRR.........RRRR....RRRRRRRR............RRRRR...RRRRRRRRRRRR.......................................................................................................................................................", + ".....................................RRRRRRRRRR..........................................................RHHHHHH.......RRRRRR........RRRRRRRRRRRRRRRR.............RRRRR...RRRRRRRRRRR.......................................................................................................................................................", + "....................................RRRRRRRRRRRR.........................................................RRHHHHHH.......RRRRRR.......RRRRRRRRRRRRRRRR..............RRRR...RRRRRRR.RRR.......................................................................................................................................................", + "...................................RRRRRRR.RRRRR.........................................................RRHHHHHH........RRRRRR......RRRRRRRRRRRRRRRRR.............RRRRR.RRRRR..............................................................................................................................................................", + ".................................RRRRRRRR...RRRRR...........................................................HHHHHR........RRRRR......RRRR..RRRRRRRRRRRR.............RRRRRRRRRR..............................................................................................................................................................", + "................................RRRRRRR.....RRRRRR..........................................................HHHHHH........RRRRRR.....RRR.....RRRRRRRRRRRR...........RRRRRRRRR...............................................................................................................................................................", + "...............................RRRRRRR.......RRRRRR........................................................HHHHHHH.........RRRRRRR...RRRR...RRRRRRRRRRRRRRR..........RRRRRRRR...............................................................................................................................................................", + ".............................RRRRRRRR.........RRRRRR.........................HHHH.........................HHHHHHHHH.........RRRRRR...RRRRRRRRRRRRRRRRRRRRRR...........RRRRRR................................................................................................................................................................", + "............................RRRRRRR............RRRRR.......................HHHHHHHH.....................HHHHHHHHHHH..........RRRRRR.RRRRRRRRRRRRRRRR..RRRRR............RRRRR................................................................................................................................................................", + "............................RRRRRR.............RRRRRR.....................HHHHHHHHHH...................HHHHHHHHHHHHH..........RRRRR.RRRRRRRRRRR.RRRR...................RRRR......RRR........................................................................................................................................................", + "............................RRRRR...............RRRRRR..................PRHHHHHHHHHHH...............HHHHHHHHHHHHHHHH..........RRRRRRRRRR..RRRRR.RRR....................RRRR......RRR........................................................................................................................................................", + ".................................................RRRRRR.................RRHHHHHHHHHHHHH...........HHHHHHHHHHHHHHHHHHH..........RRRRRRRRR...RRRR.RRR....................RRRR......RRR........................................................................................................................................................", + "..................................................RRRRR..............RRRRRHHHHRPHHHHHHHH......HHHHHHHHHHHHHHH.HHHHHHH...........RRRRRRRR...RRRRRRRR...................RRRR.......RRR........................................................................................................................................................", + "..................................................RRRRRR.............RRRRRRRRRRR.HHHHHHHHHHHHHHHHHHHHHHHHH.....HHHHHHH...........RRRRRRR....RRRRRRR...................RRRRRRR...............................................................................................................................................................", + "...................................................RRRRRR............RRRRRRRRRRR.PHHHHHHHHHHHHHHHHHHHHH.........HHHHHH...........RRRRRR.....RRRRRRR..................RRRRRRRRR..............................................................................................................................................................", + "....................................................RRRRRR...........PRRRRRRRRRRRRRRHHHHHHHHHHHHHHHH.............HHHHHH...........RRRRR...RRRRRRRRR................RRRRRRRRRRRRP............................................................................................................................................................", + ".....................................................RRRRR...........RRRRRRRRRRRRRRRPHHHHHHHHHHHH................HHHHHH............RRRR...RRRRRRRRR................RRRRRRRRRRRRRP...........................................................................................................................................................", + "......................................................RRRRR.........RRRRRRRRRRRRRRRRRPP...........................HHHHHH...........RRRR...RRRRRRRRR...............RRRRRR..PRRRRRRRRPPP......................................................................................................................................................", + "......................................................RRRRR.....PPPRRRRRRPRRRRRRRRRRRRRRRR.........................HHHHHRRRRRRR....RRRR...RRRR.RRR................RRRRR....PRRRRRRRRRRRRRRRP................................................................................................................................................", + ".......................................................RRRR.....PPRRRRRRRPRRRRRRRRRRRRRRRR.............RRR.........HHHHHHRRRRRRRRRRRRRR.RRRRRR.RRR...............RRRRR.......RRRRRRRRRRRRRRRR...............................................................................................................................................", + "......................................................RRRRR....PPRRRRRRRPPRRRRRRRRRRRRRRRR.............RRRRRR.....RRHHHHHHRRRRRRRRRRRRR.RRRRRR.RRR...............RRRR.........PRRRRRRRRRRRRRRRP.............................................................................................................................................", + ".....................................................RRRRRR...PPRRRRRRRPPPPPPRRRRRRRRRRRRRRRPPPP.......RRRRRRR....RRRHHHHHRRRRRRRRRRRRR.RRRRRR.RRRRRRRRRRR.......RRRR.................PRRRRRRRRR............................................................................................................................................", + ".....................................................RRRRRR...PRRRRRRRPPPPPPPPPRRRRRRRRRRRRRRPPP.......RRRRRRRR..RRRRHHHHHH.....RRRRRR..RRRRRRRRRRRRRRRRRR......PRRRR....................PRRRRRRRP..........................................................................................................................................", + "....................................................RRRRRR....RRRRRRRPPPPPPPPRRRRRRRRRRRRRRRRPPP........RRRRRRR..RRRRRHHHHHH.......RRR..RRRRRRRRRRRRRRRRRR......RRRR.......................RRRRRRRR.........................................................................................................................................", + "....................................................RRRRRRRRRRRRRRRRPPPPPPPPPRRRRRRRRRRRRRRRRRPP...........RRRR..RRRR.HHHHHH.......RRR..RRRRRRRRRR..RRRRRR.....RRRRR.......................RRRRRRRRR........................................................................................................................................", + "....................................................RRRRRRRRRRRRRRRRPPPPPPPPPRRRRRRRRRRRRRRRRRR....PPP.....RRRRR.RRRR..HHHHHH......RRRRRRRRRRRRRRR............RRRRRR.........................PRRRRRR........................................................................................................................................", + "....................................................RRRRRRRRRRRRRRRRRRRRRRRRRPRRRRRRRRRRRRRRRRRR.PPPPP......RRRRRRRRR...HHHHHH.....RRRRRRRRRRRRRRRRRR......RRRRRRRRP...........................RRRRR........................................................................................................................................", + "......................................................RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRPPPPP......RRRRRRRRR...HHHHHHH....RRRRRRRRRRRRRRRRRRR.....RRRRRRRP.............................PRRR........................................................................................................................................", + ".....................................................PPPRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRPPPP.......RRRRRRRRR...HHHHHH....RRRRRRRRRRRRRRRRRRRRPPPRRRRRRRP..........................................................................................................................................................................", + ".....................................................PPPRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRP.PPPP....RRRRRRRRR...HHHHHHH...RRRRRRRRRRRRRRRRRRRRRRRRRRRRRR...........................................................................................................................................................................", + ".....................................................PPPRRRRRRRRRRRRRRRPRRRRRRRRRRRRRRRRRRRRRRRRRRRR.PPPP...RRRRRRRRRRR..HHHHHHHH..RRRRRRRRRRRRR...RRRRRRRRRRRRR............................................................................................................................................................................", + ".....................................................PPPRRRRRRRRRRRRRRRRRPPPPRRRRRRRRRRRRRRRRRRRRRRRRPPPP..RRRRRR.RRRRR...HHHHHHHH.RRRRR.....RRR...RRRRRRRRRRRRP............................................................................................................................................................................", + ".....................................................PPPRRRRRRRRRRRRRRRRRRRRP.RRRRRRRRRRRRRRRRRRRRRRRRPPP.RRRRRR...RRRRRRRRHHHHHHHHRRRRRRRRRRRRR...PRRRRRRRRRRR.............................................................................................................................................................................", + ".....................................................PPPRRRRRPRRRRRRRRRRRRRRPPRRRRRRRRRRRRRRRRRRRRRRRRRPP.RRRRR....RRRRRRRRHHHHHHHHHRRRRRRRRRRRR....HHHRRRRRRRP.............................................................................RRRR............................................................................................", + ".....................................................PPPRRRRRPRRRRRRRRRRRRRRRPRRRRRRRRRRRRRRRRRRRRRRRRRPPRRRRR......RRRRRRRRHHHHHHHHHHHHHHRRRRRR....HHHHRRRRRRRRPP..........................................................................RRRR............................................................................................", + "......................................................PRRRRRPPRRRRRRRRRRRRRRRRPRRRRRRRRRRRRRRRRRRRRRRRRP.RRRR........RRRRRRR.HHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRR.....................................................................RRRRR...........................................................................................", + "......................................................PRRRRRPPPRRRRRRRRRRRRRRRRRRRRRRPPRRRRRRRRRRRRRRRRP.RRRR........RRRRRR..HHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRR.....................................................................RRRRR..........................................................................................", + "......................................................RRRRRPPPPPPPPPRRRRRRRRRRRRRRRRPPPRRRRRRRRRRRRRRRR...............RRRRR...HHHHHHHHHHHHHHHHHHHHHHHHHHHHR.RRRRRRRRRRRRR....................................................................RRRRR..........................................................................................", + "......................................................RRRRR....PPPPPRRRRR.RRRRRRRRR.PPPRRRRRRRRRRRRRPP.................RRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHH....RRRPRRRRRRR....................................................................RRRR..........................................................................................", + "......................................................RRRRR.........RRRRRPPRRRRRRR..PPPRRRRRRRRRRRRR...................RRRRRHHHHHHHHHHHHHHHHHRRRRRHHHHHHHHHHHHRRRRRRRRRRRRP...................................................................RRRRR.........................................................................................", + "......................................................RRRR...........RRRRRRRRRRRRRRPRRRRRRRRRRRRRRRR....................RRRHHHHHHHHHHHHHH.PPRRRRRRRRHHHHHHHHHHHHRRRRRRRRRRR..................................................RRR...............RRRRR........................................................................................", + "......................................................RRRR...........RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRP..................RRHHHHHHHHHHHHHHH.PRRRRRRRRRHHHHHHHHHHHHRRRRRRRRRRRR...............................................RRRRR...............RRRRR..................................RRRRRRRRRR............................................", + "......................................................RRRR...........PRRRRRRRRRRRRRRRRRRPPPRRRRRRRRRRPPP...............RRHHHHHHHHHHHHHHHHHRRRRRRRRRRHHHHHHHHHHHHRRRRRR.RRRRR..............................................RRRRRR................RRRRRRRRRRR..........................RRRRRRRRRRRR...........................................", + "......................................................RRRRR..........PPRRRRRRRRRRRRRRRRRRRPPRRRRRRRRRPPP.............RRRHHHHHHHHHHHHHHHHHHRRRRRRRRRRHHHRRHHHHHHHHRRRRR.RRRRR..............................................RRRRRR................RRRRRRRRRRRRR.....RRRRRR............RRRRRRRRRRRRRRR.........................................", + "......................................................RRRRR.........PPP.PRRRRRRRRRRRRRRRRRPPPPRRRRRRRPPP.............RRHHHHHHHHHHRRHHHHHHHRRRRRRRRRRRRRRRRRHHHHHHHRRRR..RRRRRRR...........................................RRRRRRR................RRRRRRRRRRRR...RRRRRRRRR...........RRRRR...RRRRRRRR........................................", + "......................................................RRRRR.........PPP.PPRRRRRRRRRRRRRRRRRR.....RRRPPPP.............HHHHHHHHHHHRRRRHHHHHHHRRRRRRRRRRRRRRRRRHHHHHHHRRRRRRRRRRRR...........................................RRRRRRRRR.............RRRRRR..RRRRRRRRRRRRRRRRR..........RRRRR......RRRRRRR.......................................", + "......................................................PRRRRP........PPPPPPRRRRRR...RRRRRRRRRRPP..RRRPPP.............HHHHHHHHHHHRRRRRRHHHHHHHRRRRRRRRRRRRRRRRRHHHHHHRRRRRRRRRRRR............................................RRRRRRRRR.......RRRRRRRRRR....RRRRRRRRRRRRRRRR.........RRRRR........RRRRRR.......................................", + ".......................................................RRRRR.........PPPPPRRRRRP.RHHHHRRRRRRHHHPPRRRPPPP...........HHHHHHHHHRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHRRRRRRRRHHHH................RRR..........................RRRRRRR.....RRRRRRRRRRRR.....RRRRRRRRRR.............RRRRRR..........RRRR.......................................", + ".......................................................RRRRR.........PPPPPRRRRRRRHHHHHRRRRRRHHHRRP.PPPPP.........HHHHHHHHHHRRRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHRRRRRRRHHHH...............RRRR.............................RRRRRR.RRRRRRRRRRRR.......RRRRRRRRR..............RRRRR...........RRRR.......................................", + ".......................................................PRRRRP........PPPPPRRRRRRRHHHHHRRRRRHHHHRRP.PPPPP........HHHHHHHHHRRRRRRRRRRRRRRRHHHHHRRRRRRRRRRRRRRRRRRRHHHHHRRRRRRRHHHH...............RRRR.............................RRRRRRRRRRRRRRRR.........RRRR.RRRRRR............RRRRR.............RRRR......................................", + "........................................................RRRRR.........PPPPPRRRRRRHHHHRRRRRHHHHHRRR.PPPPP.......HHHHHHHHHHHRRRRRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHRRRRRRRHHHHH..............RRRR..............................RRRRRRRRRRRRRRRRR.......RRRR...RRRR...........RRRRRR.............RRRR......................................", + "........................................................RRRRR..........PPPPPPPPPRHHHHHRRRRHHHHHRRR...PPP......HHHHHHHHHHHHHHRHHHRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHRRRRR..HHHHH..............RRR................................RRRRRRRRRRRRRRRR.......RRRR...RRRR...........RRRRR..............RRRR......................................", + "........................................................PRRRRP...............PPPPRHHHHRRRRHHHHHRRR..........RHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRHHHHHRRRHHHRRRRRRRRRRRRRRRRRRRRR..HHHH..............RRR...............RRRRR............RRRRRRR.RRRRRRRR.......RRRR...RRRR..........RRRRR...............RRRR......................................", + ".........................................................RRRRR...............PPPPPHHHHHRRRHHHRRRRRRRRR....RRRHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRHHHHHRRHHHHRRRRRRRRRRRRRRRRRRRRR..HHHHH.............RRR...............RRRRR...........RRRRRR..RRRRRRRRR.......RRRR...RRRR..........RRRRR..RRRR.........RRRR......................................", + ".........................................................RRRRR...............PPPPPHHHHHRRRRRRRRRRRRRRRR..RRRHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRHHHHHHRHHHHHRRRRRRRRRRRRRRRRRRRRP.HHHHH.............RRR...............RRRRR..........RRRRRR..RRRRRRRRR.......RRRR.....RRRR........RRRRRRRRRRRRRRR......RRRR......................................", + ".........................................................PRRRRP.................PPPHHHHRRRRRPRRRRRRRRRR..RRHHHHHHHHRRRRHHHHHHHHHHRRRRRRRRRRRHHHHHHHHHHHHRRRRRRRRRRRRRRRRRRRR.HHHHH.........RRRRRRR...............RRRRR........RRRRRRR..RRRRRRRRRR.......RRRR.....RRRRR......RRRRRRRRRRRRRRRRRRRRRRRRRR..RRR.................................", + "..........................................................RRRRR..................PPHHHHHR....RRRRRRRRRRRRRRHHHHHHHRRRRHHHHHHHHHRRPRRRRRRRRRRRHHHHHRHHHHHRRRRRRRRRRRRRRRRRRRR.HHHHHH.......RRRRRRRR................RRRR......RRRRRRRR..RRRRRRRRRR........RRRR.....RRRRRR...RRRRRRRRRRRRRRRRRRRRRRRRRRRR..RRR.................................", + "..........................................................RRRRR...................PPHHHHR....HHHHHHHRRHHHRHHHHHHHRRRRRHHHHHHHHHHRP.RRRRRRRRRRHHHHHHRHHHHRRRRRRRRRPRRRRRRRRRR.HHHHHH.......RRRRRRRR...............RRRRR...RRRRRRRRRRRRRRRRRRR...........RRRRR.....RRRRRRRRRRRRRRRRRRR....RRRRRRRRRRRRRRR.RRRR................................", + "..........................................................PRRRRR..................PPHHHHHRHHHHHHHHHHHHHHHHHHHHHHRRRRHHHHHHHHHHHHH...RRRRRRRPRRHHHHHHHHHHRRRRRRRRPPRRRRRRRRR..HHHHHH.......RRRRRRRR...............RRRRR.RRRRRRRRRRRRRRRRRRRR............RRRRR......RRRRRRRRRRRRR...............RRRRRRRRRRRRRR................................", + "...........................................................RRRRR.................PPPPHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRHHHHHHHHHHHHHH..RRRRRRRRPRHHHHHHHRRRRRRRRRRRRRRRRRRRRRRPPHHHHHH.......RRRRRRRR...............RRRRRRRRRRRRRRRRRRRRRRRRRRR.........RRRRRRRR......RRRRRRRRRRR...................RRRRRRRRRRRRRRRRRR.........................", + "...........................................................RRRRRP..............PPPPPHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRHHHHHHHPHHHHHHHHRRRRRRRRRPPRHHHHHHHRRRRRRRRRRRRRRRRPPPPPPP.HHHHH.......RRRRRRR...............RRRRRRRRRRRRR....RRRRRRRRRRR......RRRRRRRRRRRRR..RRRRRRRRRRR....................RRRRRRRRRRRRRRRRRRR.........................", + "...........................................................PRRRRR............PPPPPPHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRHHHHHHP.HHHHHHHHRRRRRRRRRRPRRHHHHHHHRRRRRRRRRRRRRRRPPPPPPP.HHHHH.......RRRRRRR...........RRRRRRRRRRRRRRR......RRRRRR.RRRR.....RRRRRRRRRRRRRRRRRRRRRRRRRRR....................RRRRRRRRRRRRRRRRRRR.........................", + "............................................................RRRRR............PPPPPHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRHHHHHR...HHHHHHHHRRRRRRRRRRRRRHHHHHHHRRRRRRRRRRRRRRPPPPPPPHHHHHH.......RRRRRRR........RRRRRRRRRRRRRRR........RRRRRRR.......RRRRRRRRRRRRRRRRRRRRRRRRRRRRRR....................RRRR..RRRRRRRRRR............................", + "............................................................PRRRRR...........PPPPHHHHHHHHHHHHH.HHHHHHHHHHHHHHRRRRRHHHHHRRR..PHHHHHHHHRRRRRRRRRRRRHHHHHHHHRRRRRRRRRRRRRPPPPPPHHHHHHH....RRRRRRRRRR.....RRRRRRRRRRRRRRR..........RRRRRRRR......RRRRRRRRRRRRR.RRRRRRRRRRRRRRRRRR..................RRRRRR..RRRRRRRRR............................", + ".............................................................RRRRR...........PPP.HHHHHHHHHHH...HHHHHPPPHHHHHHHRRRRHHHHHRRRPRRHHHHHHHHRRRRRRRRRRRRRHHHHHHHRRRRRRRRRRRRRPPPPHHHHHHHHHH...RRRRRRRRRR..RRRRRRRRRRRRRRRRRR..........RRRRRRR......RRRRRRRRR.RRRR.RRRRRRRR.....RRRRR..................RRRRRR..RRRRRRRRR............................", + ".............................................................RRRRRR.............HHHHHHHPHHHHHRRHHHHHRRRRRHHHHHHRRRHHHHHRRRRHHHHHHHHHHHRRRRRRRRRR.RRHHHHHHHRRRRRRRRRRRRPPPHHHHHHHHHHH...RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR........RRRRRR.......RRRRRRR.....RRRRRRRRRR........RRRRR.................RRRRRR......RRRR.............................", + ".............................................................PRRRRR..........RRRHHHHHHRRRHHHHRRHHHHHRRRRRHHHHHHRRHHHHHHRRRRHHHHHHHHHHH.RRRRRRRRRRRHHHHHHHHHHHHHRRRRRRRRHHHHHHHHHHHHH..RRRR..RRRRRRRRRRRRRRRR..RRRRRRRR......RRRRRRR.......RRRRRR.......RRRRRRRR..........RRRRRR................RRRR..RRRR..RRRR.............................", + "..............................................................RRRRRR.....PPPRRRRHHHHHRRRRHHHHRRHHHHHRRRRRRHHHHHHHHHHHHHHRRRHHHH.HHHHHHHRRRR.RRRRRRHHHHHHHHHHHHHRRRRRRRHHHHHHHHHHHHHH.RRRRR..RRRRRRRRRRRR.RRR...RRRRRRRR...RRRRRRRR.......RRRRRR........RRRRRRR............RRRRRRRRRRRRR........RRRR.RRRRR..RRRRR............................", + "..............................................................PRRRRRR....PPPRRRRHHHHHRRRRRRRRPPRHHHHRRRRRRRPPRHHHHHHHHHHRRRHHHH.HHHHHHHHRRR.PRRRRRHHHHHHHHHHHHHRRRRRHHHHHHHHHHHHHHHHHRRRRR.RRRRRRRRRRRRRRRRRR...RRRRRRRRRRRRRRRRRR......RRRRRR.........RRRRRR..............RRRRRRRRRRRRRR.....RRRRRRRRRRR...RRRR............................", + "...............................................................RRRRRRP...PPPRRRRHHHHHRRRRHHHHHHHHHHHRRRRRRRR.RHHHHHHHHHHRRRHHHH..HHHHHHHRR...RRRRRRRHHHHHHHHHHHRRRRHHHHHHHHHHP.HHHHHHRRRR..RRRRR...RRRRRRRRRR...RRRRRRRRRRRRRRRRR.....RRRRRRR..........RRRRRR...............RRRRRRRRRRRRRRR...RRRRRRRRRRR...RRRR............................", + "................................................................RRRRRR..PPPRRRRRHHHHHRHHHHHHHHHHHHHHRRRRRRRR.PHHHHHHHHHHRRRHHHHRRRHHHHHHH.....RRRRRRRRHHHHHHHHRRRRRHHHHHHHHPPPPHHHHHHRRR...RRRR......RRRRRRRR...RRRRRRRRRRRRRRRRR....RRRRRRR...........RRRRR................RRRRRRRRRRRRRRRR..RRRRRRRRRR.....RRR............................", + "................................................................PRRRRRR.RRRRRRRRHHHHHRHHHHHHHHHHHHHHRRRRRRRR.PHHHHHHHHHRRRRHHHHRRRHHHHHHHH....PRRRRRHHHHHHHHHRRRRRRHHHHHHRRRPPP.HHHHHHRR...RRRR.......RRRRRRR...RRRRRRRRRR.RRRRR...RRRRRRRR.............RRRRR............RRRRRRRRRR..RRRRRRRR.RRRRRRRRR......RRR............................", + ".................................................................RRRRRRRRRRRRRRHHHHHHRHHHHHHHHHHHHHHRRRRHHHRRPPHHHHHHHHRRRRHHHHRRRRHHHHHHHH...HHHRRHHHHHHHHHHHRRRRRHHHHRRRRRRPPPHHHHHHRR...RRR.........RRRRRR..RRRRR.......RRRRR..RRRRRRRR..............RRRRRRRRRR.....RRRRRRRRRRRRR....RRRRRRRRRRR..........RRR............................", + "..................................................................RRRRRRRRRRRRRHHHHHHRHHHHHRRPPPHHHHRRRHHHHHRRPHHHHHRRRRRRRHHHHRRRRRHHHHHHHH.HHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRPPPHHHHHHR...RRRR.........RRRRRRRRRRRR.......RRRRR..RRRRRRRR...............RRRRRRRRRRRRRRRRRRRRRRRRRRRRR....RRRRRRRRR..RRRRR.RRRRRR..................RRRRRRRRRR", + "...................................................................RRRRRRRRRRRRHHHHHHRRRRPRRRPPPHHHHRRRHHHHHRRRHHHHHRRRRRRHHHHHRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRPPHHHHHHR...RRRR..........RRRRRRRRRRR.......RRRRR.RRRRRRRR................RRRRRRRRRRRRRRRRRRRRR...RRRRR.....RRRRRRRRRRRRRRRRRRRRRRR.......RRRRRRRRRRRRRRRRRRRR", + "...................................................................PRRRRRRRPRRRHHHHHHHRRRRRRRPPPHHHHRRRHHHHHRRRHHHHRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRHHHHRRRRRRRRRRRRRRRRPRRHHHHH....RRRR...........RRRRRRRRR.......RRRRR..RRRRRRRRRRR.............RRRRRRRRRRRRRRRRRRR......RRRRR......RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", + "....................................................................RRRRRRPPRRRRHHHHHHHRRRRRRPPPHHHHRRRHHHHRRRHHHHHRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRHHHHRRRRRRRRRRRRRRRRRRRHHHHH....RRRR...........RRRRRRR.......RRRRRRR.RRRRRRRRRRRRR............RRRRRRR....RRRRRRRR......RRRRR.......RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", + "....................................................................RRRRRRRPRRRRHHHHHHHHRRRRRRRRHHHHRRRRRRRRRRHHHHHRRRHHHHHHHHHHHHHHHHRHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRRHHHRRRRRRRRRHHHHR...RRRR...........RRRRRR........RRRRRR..RRRRR.RRRRRRRR...........RRRR...........RRRR.......RRRR....RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR...........", + "..................................................................PPRRRRRRRRRRRPHHHHHHHHRRRRRRRRRHHHRRRRRRRRRRHHHHHPRHHHHHHHHRRRRHHHHHRRHHHHHHHHHHHPRRRRRRRRRHHHHRRRRHHHHHRRRRRRRRHHHHH...RRR............RRR...........RRRRRR.RRRRR.....RRRRRR...........RRRR..RRRRRRR.RRRR.......RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.....................", + "..................................................................PPRRRRRRRRRRRPHHHHHHHHRPRRRRRRRHHHRRRRRRRRRRHHHHR.HHHHHHHHRRRRRRRRRRP.RHHHHHHHHHHHRRRRRRRRRHHHHHRRRHHHHHHRRRRRRRHHHHH...RRR..........................RRRRR..RRRRR......RRRRR...........RRRR..RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.RRRR..........................", + "..................................................................PPRRRRRRRRRRRPHHHHHHHHRRRRRRRRRHHHRRRRRHHHRHHHHHHHHHHHHHHRRRRRRRRRRRPRRHHHHHHHHHHHHHRRRRRRRHHHHHHRRHHHHHHRRRRRHHHHHHH..RRRR..........................RRRRR..RRRR........RRRRR..........RRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR............RRR..........................", + "..................................................................PPRRRRRRRRRRRRHHHHHHHHRRRRRRRRRHHHPPHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRHHHHHHHHHHHHHHRRRRRRRHHHHHHRRHHHHHHRRRRHHHHHHH..RRRR.........................RRRRR..RRRRR.........RRRR..........RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR..RRRR...............RRR..........................", + "..................................................................PPRRRRRRRRRRRRHHHHHHHHRRRRRRRRRRRRPHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRRHHHHRHHHHHHHHHHRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHH..RRRR.........................RRRR...RRRR..........RRRR........RRRRRRRRRRRRRRRRRRRRRRRRRRR.RRRRR....RRRR...............RRRR.........................", + "..................................................................PPRRRRRRRRRRRRHHHHHHHHRRRRRRRRRRRRHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRRRRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRR........................RRRRRRRRRRRR...........RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR........RRRR....RRRR...............RRRR.........................", + "..................................................................PPRRRRRRRRRRRRHHHHHHHHRRRRRPRRRRRHHHHHHHHHHHHHHHHHHRPPRRRRRRRRRRRRRRRRRRRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRR..RRRRRR.............RRRRR.RRRRRRR......RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR..........RRRRR...RRRR...............RRRR.........................", + "..................................................................PPRRRRRRRRRRRRHHHHHHHHPPRRRRRRRRHHHHHHHHPRHHHHHHHHRRRPPRRRRRRRRRRRRRRRRRRRR.RRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRR...........RRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR........RRRRRR........RRRRRRRRRRRR.........RRRRRRRRRR.........................", + "...................................................................PRRRRPRRRRRPPHHHHHHHHHPRRRRRRRRHHHHHHRRRRHHHHHHHHHRRRPRRRRRRRRRRRRRP..PPP...RRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRRRR.......RRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRR...RRRR.........RRRRRRR.......RRRRRRRRRRR...RRRRRRRRRRRRRRRR.........................", + "...................................................................PPRRRPPRRRRPPHHHHHHHHHPRRRRRRRHHHHHHRRRRRHHHHHHHHHHRRPPRRRRRRRRRRR..........PRHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRHHHHH..RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR...........RRRR.........RRRRRRRR.......RRRRRRRRR....RRRRRRRRRRRRRRR..........................", + "...................................................................PPRRRPPRRRRPPHHHHHHHHHHRRRPRRRHHHHHRRRRRRHHHHHHHHHHRRRPPHHHHHRRRRR...........RHHHHHHHHHHHHHHRRHHHHRRRRRRRRRRRRRHHHHRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR...RRRRR..........RRRRRR.........RRRRRR.......RRRRRRR......RRRRRRRRRRRRRR...........................", + "...................................................................PGRRRPPRRRRPPHHHHHHHHHHRRRRRRRHHHHHRRRRRRHHHHRHHHHHHRRRHHHHHHRRRRRP..........HHHHHHHHHHHHHRRRRHHHHRRRRRRRRRRRRRRHHHRR....RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR..........RRRR..........RRRRRRR.........RRRRRR.......RRRRR.......RRRR....RRR..............................", + "...................................................................PGRRRRRRRRRRRHHHHHHHHHHHHRRRRRHHHHRRRRRRRHHHHRRHHHHHHHHHHHHHHRRRRRR..........HHHHHHHHHHHPRRRRRHHHHRRRRRRRRRRRRRRRRRRR......RRRRRRRR.RRRRRRRRRRRRRRRRRRR.........RRRRRRRRRRRRR...........RRRRRRR.........RRRRRRR.....RRRRR.......RRR.....RRR..............................", + ".............................................................RRRP..PGRRRRRRRRRRRHHHHHHHHHHHHHRRRHHHHHRRRRRRRHHHHRRHHHHHHHHHHHHHHRRRRRRR........HHHHHHHHHHRRRRRRRRHHHHRRRRRRRRRRRRRR.RRRR........RRRRRRRRRRRRRRRRRRR...............RRRRRRRRRRRRRR...........RRRRRRRRRR.......RRRRRRRRRRRRRRRR.......RRR......................................", + ".............................................................RRRP.PPGRRRRRRRRRRRHHHHHRHHHHHHHHHHHHHHHPPPPRRRHHHHRRRHHHHHHHHHHHRRRRRRRRRR......RHHHHHHHHHRRRRRRRRRHHHHRRRRRRRRRRRRR..RRRR..........RRRRRRRRRRRRRRRRRR..............RRRRRRRRRRRRRR...........RRRRRRRRRRRR......RRRRRRRRRRRRRRR.......RRR......................................", + ".............................................................RRRP.PPGRRRPPRRRRPPHHHHHRRHHHHHHHHHHHHHHRRRRRRHHHHHRRRRHHHHHHHHHRRRRRRRRRRR....GRRHHHHHHH.RRRRRRRRRRHHHHRRRRRRRRRRR....RRRRR..........RRRRRRRRRRRRRRRRRR.............RRRRRR..RRRRRR...........RRRRRRRRRRRRR......RRRRRRRRRRRRRR......RRRR......................................", + ".............................................................RRRP.RRRRRRPPRRRRPPHHHHHRRRHHHHHHHHHHHHRRRRRRRHHHHRRRHHHHHHHHHHRRRRRRRRRRRRR..PRRHHHHHHH..RRRRRRRRRRHHHHRRRRRRRRR......RRRRRRRR.......RRRRRRRRRRRRRRRRRRR..............RRRR....RRRRRR........RRRRR..RRRRRRRRR.......RRRRRRRRRRRR.....RRRR......................................", + ".............................................................RRRP.RRRRRRPPRRRRPPHHHHHRRRRHHHHHHHHHHHHHRRRRRHHHHRRHHHHHHHHHRRRRRRRRR.RRRRRRRRRRHHHHHHPPRRRRRRRRRRHHHHHR.RRRRRRRR.....RRRRRRRR........RRRRRRRRRR..RRRRRRR..RRRRR.....RRRRR....RRRRRRR.....RRRRRRR..RRRRRRRRRRR......RRRRRRRRRRRR...RRRRR......................................", + ".............................................................RRRP.RRRRRRRPRRRRPPHHHHHRRRRRHHHHHHHHHHHHHHHHHHHHHRHHHHHHHHHRRRRRRRRRRR.RRRRRRRRRHHHHHH.RRRRRRRRRRHHHHHHR....RRRRRRR....RRRRRRR.........RRRRRRRRR...RRRRRRR.RRRRRRR..RRRRR.....RRRRRRR.....RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.RRRRRRRRRRRRR......................................", + ".............................................................RRRP.RRRRRRRPRRRRRRHHHHHRRRRPHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRPRRRHHHHHHHHHH..RRRRRRRRRRHHHHHHP.....RRRRRRR......RRRR.........RRRRRR.......RRRRRRRRRRRRRRRRRRRRR.......RRRRR...RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR....RRRRRRRRRRR.......................................", + ".............................................................RRRP.RRRRRRRRRRRRRRHHHHHRRRRPPHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRR.RRHHHHHHHHHHHRRRRRRRRRRRRHHHHH........RRRRRRR.....RRRR..........RRRRR........RRRRRRRRRRRRRRRRRRR..........RRRRRRRRRRRRRRRRRRRRR...RRRRRRRRRRRRR......RRRRRRRRR........................................", + ".............................................................RRRPRRRRRRRRRRRRRRRHHHHHRRRRPHHHHHHHHPP...HHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRHHHHHHHHHHHHHRRRRRRRRRRRHHHH..........RRRRRRR....RRRR..........RRRRR.........RRRRRRRR.RRRRRRRR...........RRRRRRRRRRRRRRRRR.........RRRRRRRRRR........RRRRRRR.........................................", + ".............................................................RRRPRRRRRRRRRRRRRRRRHHHHRRRRPHHHHHHHHHPPPPPPHHHHHHHHHHRRRHHHHHHRRRRRRRRRRRHHHHHHHHHHHHHHRRRRRRRRRRRRR.............RRRRRR...RRRR...........RRRRR.........RRRRRRR....................RRRRRRRRRRRRRRRR.........RRRRR................RRRRR.........................................", + ".............................................................RRRRRRRRRRRRPRRRRPRRHHHHRRRRHHHHHHHHHHHHRRRHHHHHHHHHHRRRRHHHHHHRRRRRRRRRRRHHHHRRRHHHHHHHHRRRRRRRRRRR...............RRRRRRRRRRRR............RRRR..........RRRRRRR....................RRRRRR.RRRRRRR.........RRRRR..................RRRR.........................................", + ".............................................................RRRRRRRRRRRRPRRRRPRRHHHHRRRRHHHHHHHHHHHHRHHHHHHHHHHRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHRRRRRRRRRRR................RRRRRRRRRR.............RRRRR..........RRRRRRR....................RRRRRRRRRRRRR.........RRRRR...............................................................", + ".............................................................RRRRR.RRRRRRPRRRRPRRHHHHRRRRHHHHHHHHHHHHRHHHHHHHHHHRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRHHHHHHHHRRRRRRRRRP.................RRRRRRRRR..............RRRR...........RRRRRRR....................RRRRRRRRRRRR........RRRRRR...............................................................", + ".............................................................PRRRRR.PRRRRPRRRRPRRHHHHRRRRHHHHPRHHHHHHHHHHHHHHHHHRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHHRRPPRRRR......................RRR................RRRR.............RRRRRRRRR.................RRRRRRRR..........RRRRRR................................................................", + "..............................................................RRRRRPPRRRRPRRRRRRHHHHHRRRRHHHRRRHHHHHHHHHHHHHHHHHRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHR..RRRRR.........................................RRRR..............RRRRRRRRR................RRRRRRRR.........RRRRRR.................................................................", + "..............................................................PRRRRRRRRRRRRRRRRRHHHHHRRRRHHHRRRRHHHHHHHHHHHPPHHHRRRRRRRRRRHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHHRRRRRRR.........................................RRRR...............RRRRRRRRR................RRRRRRRRRRR....RRRRRR..................................................................", + "...............................................................RRRRRRRRRRRRRRRRRHHHHHRRRRHHHRRRRHHHHHHHHHHHRRHHHRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHHRRRRRP..........................................RRR................RRRRRRRRRRRRRRR..........RRRRRRRRRRRRRRRRRRR...................................................................", + "................................................................RRRRRRRRRRRRRRRRHHHHHRRRRRRRRRHHHHHHHHHHRRRRRHHHRRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHRRRRR...........................................RRR................RRRRRRRRRRRRRRRR..........RRRRRRRRRRRRRRRRR....................................................................", + "...................................................................RRRRRR.RRRRRRHHHHHRRRRRRR.HHHHHHHHHHHHHRRRHHHRRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHHRRRR...........................................RRR................RRRRRRRRRRRRRRRRR..........RRRRRRRRRRRRRRR.....................................................................", + "...................................................................RRRRRRRRRRRRRHHHHHRRRRRRRHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHHRRRR...........................................RRRR................RRRRRRRRRRRRRRRR..........RRRRRR.RRRRRRRR.....................................................................", + "...............................PPPP..................................RRRRRRRRRRRHHHHHRRRRRHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRRPHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHRRR............................................RRRR................RRRRRRRRRRRRRRRR...........RRRRR...RRRRRR.....................................................................", + "...............................PPPPP.................................RRRRRRRRRRHHHHHHRRRRHHHHHHHHHHRHHHHHHHRRRRRRRRRRRRRRRRRRHHHHHHRRRRRRRRRRPRRRRRRRHHHHHHRRR............................................RRRRRRR.............RRRRRRRRRRRRRRRR............RRRR.....RRRR..........RRRR.......................................................", + "...............................PPPPP.................................RRRRRRRRRRHHHHH.RRHHHHHHHHHHRRRHHHHHHHHHHRP.RRRRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRHHHHHHRRR.............................................RRRRRRRR...........RRRRRRRRRRRRRRR.............RRRR......RRRR.......RRRRRR.......................................................", + "...............................PPPPP.................................RRRRRRRRRHHHHHH.RRHHHHHHHHHPPRRRHHHHHHHHHRRRRRRRRRRRRRRRRRHHHHHHRRRRRRRRRRRRRRPRHHHHHHRRR.............................................RRRRRRRRR...........RRRRRRRRRRRRR..............RRRR......RRRR.....RRRRRRRR.......................................................", + ".....................................................................PRRR.RRRRHHHHHHPHHHHHHHHHRRRPRRRRHHHHHHHHRRRRRRRRPPPRRRRRRHHHHHHRRRRRRRRRRRRRPPHHHHHHHRRR................................................RRRRRRR...........RRRRRRRRRRRR.............RRRRR......RRRR..RRRRRRRRRR........................................................", + "..............................PPP....................................PRRR.RRRRHHHHHHHHHHHHHHHRRRRRRRRRRHHHHHHHHRRRRRR.PPP.RRRRRRHHHHHHRRRRRRRRRRPPPHHHHHHHHRR...................................................RRRRRR..........RRRRRRRRRRRRRR...........RRRRR......RRRRRRRRRRRRRR..........................................................", + ".............................PPPPPPPPPP..............................PRRR.RRRRHHHHHHHHHHHHHHPRRRRRRRRRRHHHHHHHHRRRRR.PPPPPRRRRRRRHHHHHHRRRRRRRRPPHHHHHHHHHRRR....................................................RRRRRR.......RRRRRRRRRRRRRRRRR.........RRRRR........RRRRRRRRRRR............................................................", + ".............................PPPPPRRRRRRP............................PRRR.RRRRHHHHHHHHHHHRRRRRRRRRRRRRRHHHHHHHHHRR...PPPPRRRRRRRRHHHHHHHRRRRRRPPHHHHHHHHHRRR......................................................RRRRRRR....RRRRRRRRRRR.RRRRRRRR.......RRRRR........RRRRRRRR...............................................................", + ".............................PPPPRRRRRRRR..........................HHHHHHHHHHHHHHHHHHHHHRRRRRRHHHHRRRRRRRHHHHHHHH....PPPPRRRRRRRRRHHHHHHRRRRPPPHHHHHHHHHHRRR.......................................................RRRRRRRR.RRRRRRRRRRR...RRRRRRRR.....RRRRR.........RRRRRR.................................................................", + ".............................PPPPRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRHHHHRHHHHRRRRRRRRHHHHHHH....PPPPRRRRRRRRRRHHHHHHRRPPPHHHHHHHHHHRRRR........................................................RRRRRRRRRRRRRR..........RRRRRRRR..RRRRRR.........RRRR...................................................................", + ".............................PPPPRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRHHHHRHHHHRRRRRRRRRHHHHHHH....PPRRRRRRRRRRRRHHHHHHRPPHHHHHHHHH.RRRRR.........................................................RRRRRRRRRRRR............RRRRRRRRRRRRRR..........RRRR...................................................................", + ".............................PPPPRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRHHHHRHHHHRRRRRRRRRRHHHHHHH...PPRRRRRRRRRRRRHHHHHHRRHHHHHHHHH.RRRRRP...........................................................RRRRRRRRR...............RRRRRRRRRRR...........RRRR...................................................................", + "...............................PPRRRRRHHHHHHHHHHHHHHHHHHH............PHHHHHHHHHHHHHRRRHHHHHHHRHHHHRRRRRRRRR.HHHHHHHH..PPRRRRRRRRRRRRRHHHHHHRHHHHHHHH.RRRRRR..........................................................RRRRRRRRRR..................RRRRRRRRR..........RRRRR...................................................................", + ".................................RRRRRRRR............................PRRRRRRRHHHHHRRRRHHHHHHHRHHHHRRRRRRRRPP.HHHHHHHH.HHHHRRRRRRRRRRRRHHHHHHHHHHHHH..RRRRR..........................................................RRRRRRRRR.....................RRRRRRRRR.........RRRR....................................................................", + ".................................PRRRRRRP............................PPPPRRRRHHHHHRRRRHHHHHHHPHHHHRPP..RRRPP..HHHHHHHHHHHHRRRRRRRRRRRRHHHHHHHHHHHH..RRRRRP.........................................................RRRRRRRRR........................RRRRRRRR........RRRR....................................................................", + ".................................PPPPPP....................................RRHHHHHRRRRHHHHHHH.HHHHRP...RRRPP...HHHHHHHHHHHRRRRRRRRRRRRRHHHHHHHHHH...RRRRR..........................................................RRRRRRRRR........................RRRRRRRRRR......RRRR....................................................................", + "...........................................................................RRHHHHHRRRRRHHHHHH.HHHHRP...RRRP.....HHHHHHHHHHRRRRRRRRRRRRRRHHHHHHHH....RRRRPP........................................................RRRRRRRRRR........................RRRRRRRRRRR....RRRR.....................................................................", + "...........................................................................RRHHHHHRRRRRRHHHHHHHHHHRP...RRRPP.....HHHHHHHHHHPRRRRRRRRRRRRHHHHHHHH....RRRRPP........................................................RRRRRRRRR.........................RRRRRRRRRRRRR..RRRR.....................................................................", + ".............................................................................HHHHH...PRRRHHHHHHHHHRRRRRRRRPP......HHHHHHHHHHHRRRRRRRRRRRHHHHHHHHRRRRRRRRRRR......................................................RRRRRRRRRR.........................RRRRRRRRRRRRRRRRRRR.....................................................................", + ".............................................................................HHHHH...PRRRHHHHHHHHHRRRRRRRRPP.......HHHHHHHHHHHHRRRRRRRRRHHHHHHHRRRRRRRRRRRRR.....................................................RRRR...............................RRRRRR..RRRRRRRRRRR.....................................................................", + ".............................................................................HHHHH...PRRRRHHHHHHHHRRRRRRRRPP.......HHHHHHHHHHHHHHHRRRRHHHHHHHHHRRRRRRRRRRRRR....................................................RRRRR...............................RRRRRR...RRRRRRRRR......................................................................", + ".............................................................................HHHHH....RRRRHHHHHHHHRRRRRRRRP.........HHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRR....................................................RRRRR.........................................RRRRRRRR......................................................................", + ".............................................................................HHHHH........HHHHHHHH..................HHHHRRHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRR...................................................RRRRR............................................RRRRRRR.....................................................................", + "..............................................................................HHHH........HHHHHHHHH.................RRRRRRRRHHHHHHHHHHHHHHHHHHHRRRRRRRRPRRRR...................................................RRRRR.............................................RRRRRR.....................................................................", + "..............................................................................HHHH........HHHHHHHHH.................RRRRRRRRRRRRHHHHHHHHHHHHHHHRRRRRRRRRRRRR..................................................RRRRR...............................................RRRRR.....................................................................", + "..............................................................................HHHH........HHHHHHHHH.................RHHHRRHHHHHPPRRRRRRHHHHHHHHPRRRRR.RRRRRR..................................................RRRRR................................................RRRR.....................................................................", + "..............................................................................HHHHH.......HHHHHHHHHHHHHHHHH.........RHHHHHHHHHHHRRRRRRRHHHHHHH..RRRRR.RRRRRR.................................................RRRRR..........................................................................................................................", + "..............................................................................HHHHH.......HHHHHHHHHHHHHHHHH.......HHHHHHHHHHHHHHHHHRRRRRRHHHH...RRRR..RRRRRR.................................................RRRRR......................................................RRRR................................................................", + "..............................................................................HHHHHH..HHHHHHHHHHHHHHHHHHHHHH.....HHHHHHHHHRHHHHHHHHRRRRRHHHHH..RRRRR.RRRRRR.................................................RRRRR.......................................................RRRRR...............................................................", + "..............................................................................HHHHHHHHHHHHHHHHHHHHHRRRRHHHHHHHHHHHHHHHHHHHRRRHHHHHHRRHHHHHHHH..RRRRR.RRRRRR.................................................RRRRR.......................................................RRRRRRRRR...........................................................", + "..............................................................................HHHHHHHHHHHHHHHHRHHHHRRRRRHHHHHHHHHHHHHHHHHHRRHHHHHHHRHHHHHHHHH.PRRRRR.RRRRR.................................................RRRRR.........................................................RRRRRRRRR..........................................................", + "...............................................................................HHHHHHHHHHHHHHHPHHHHRRRRRHHHHHHHHHHHHHHHHHHRRHHHHHHHHHHHHHHHHH.RRRRRR.RRRRRP................................................RRRR...........................................................RRRRRRRR..........................................................", + "...............................................................................HHHHHHHHHHHHHHHHHHHHRRRRRHHHHHHHHHHHHHHHHHHRRHHHHHHHHHHHHHHHHH.RRRRRR.RRRRRRRRRRRRRRRR.....................................RRRRR............................................................RRRRRRRR.........................................................", + "................................................................................HHHHHHHP..HHHHHHHHHHRRRRRRRHHHH...HHHHHHRRRRHHHHHHHHHHHHHHHHPRRRRRRR..RRRRRRRRRRRRRRR.....................................RRRR................................................................RRRRRR........................................................", + "................................................................................HHHHHHH...PHHHHRHHHHHRRRRRRHHHH...HHHHHRRRRRHHHHHHHHHHRHHHHHPRRRRRRRR..RRRRRRRRRRRRRR.....................................RRRR.................................................................RRRRRRRRR....................................................", + "................................................................................HHHHHHHH..PHHHHRHHHHHRRRRRRHHHH....RRRRRRRRRHHHHHHHHRRRHHHHH.RRRRRRRR...PRRRRRRRRRRRR....................................RRRRR.................................................................RRRRRRRRRR...................................................", + "...............................................................................PHHHHHHHH...HHHHHHHHHHRRRRRRRRRRRRR.RRRRRRRRHHHHHHHHPRRHHHHHH.RRRRRRRRR.RRRRRRRRRRRRR.....................................RRRR...................................................................RRRRRRRRR...................................................", + "...............................................................................PHHHHHHHHHHHHHHHHHRHHHRRRRRRRRRRRRR.RRRRRRHHHHHHHHHRRRRHHHHHHRRRRRRRRRRRRRRRRRRRRRRR......................................RRRR........................................................................RRRRR..................................................", + "...............................................................................PHHHHHHHHHHHHHHHHHRHHHHHHHRRRRRRRRR.HHHHRHHHHHHHHRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRRRRRR......................................RRRR........................................................................RRRRRR.................................................", + "..............................................................................PPRRRHHHHHHHHHHHHHHRHHHHHHHRRRRRRRRRHHHHHHHHHHHHHRRRRRRRHHHHHHRRRRRRRRRRRRRRRRRRRRRRR......................................RRRR.........................................................................RRRRRRR...............................................", + "..............................................................................PPRRRRHHHHHHHHHHHRRRHHHHHHHRRRRRRRRRHHHHHHHHHHHHRRRRRRRRHHHHHHRRRR......RRRRRRRRRR.........................................RRRR.........................................................................RRRRRRRRRRRRR.........................................", + "..............................................................................PPRRRRHHHHH..HHHHRRRHHHHHHHHHHRRRRRPHHHHHHHHHHHRRRRRRRRRHHHHHHRRRR.......PRRRRRRRR.........................................RRRRR..........................................................................RRRRRRRRRRR.........................................", + "..............................................................................PPRRRRHHHHH..HHHHRRRHHHHRGRHHHRRRRRPHHHHHHHHHHRRRRRRRRRRHHHHHHRRRR.....RRRRRRRRRRR..........................................RRRR...........................................................................RRRRRRRRRR.........................................", + "..............................................................................PPRRRRHHHHHRRRHHHRRRHHHHRRRHHHRRRRRHHHHHHHHHHHRRRRRRRRRRHHHHHHRRRRR....RRRRRRRRRRR..........................................RRRRR.............................................................................................................................", + ".............................................................................PPPRRRRHHHHHRRRHHHRRRHHHHHRRHHHHRRHHHHHHHHHHHRRRRRRRRRRRRHHHHHRRRRRR....RRRRRRRRRR...........................................RRRRR.............................................................................................................................", + ".............................................................................PPRRRRRHHHHHRRRHHHHRRHHHHHRHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRHHHHHRRRRRR....RRRRRRRR..............................................RRRR.............................................................................................................................", + "............................................................................PPPRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRHHHHH..RRRRPPP.RRRRRRRR..............................................RRRRR............................................................................................................................", + "............................................................................PPPRRRRPHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH...RRRRRRRRRRRRRRHHHHH...RRRPPP.RRRRRRRR...............................................RRRR............................................................................................................................", + "............................................................................PPPRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHR.....PRRRRHHHHHRRHHHHHH...RRRPPP..RRRRRP................................................RRRR............................................................................................................................", + "........................................................................RRRRRPPRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRR.......RRRHHHHHHHHHHHHH...RRRRPP........................................................RRRR............................................................................................................................", + "........................................................................RRRRRRPRHHHHHHHHHHHHRRRRRRRRHHHHHHHHRHHHRRRR......PRRRHHHHHHHHHHHHH...RRRRRP.........................................................RRR............................................................................................................................", + ".......................................................................RRRRRRRRHHHHHHHHHHH..RRRRRRRRRHHHHHHHRRRRRRRRP.....RRRRHHHHHHHHHHHHH...RRRRRRRRR......................................................RRR............................................................................................................................", + ".......................................................................RRRRRRRRHHHHHHHHHHHHHRRRRRRRRRHHHHHHHRRRRRRRPPPP...RRRRRHHHHHHHHHHHH...RRRRRRRRR......................................................RRR............................................................................................................................", + ".......................................................................RRRRRRRHHHHHHHHHHHHHHHRRRRRRRRHHHHHHHRRRRRRRRPPP..PRRRRP..HHHHHHHHHHH...RRRRRRRR......................................................RRRR...........................................................................................................................", + ".......................................................................RRRRRRRHHHHHHHHHHHHHHHHHRRRRRRHHHHHHHRRRRRRRRRRRRRRRRRRRRRPHHHHHHHHHH.......RRRR......................................................RRRR...........................................................................................................................", + ".........................................................................RRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRRRRRRRRRRRRRRRRRRRRHHHHHHHHHH.......RRRR......................................................RRRRR..........................................................................................................................", + "..........................................................................RRHHHHHHRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHRRRHHHRHHHHHHHRRRHHHHHHHHHHH......RRRRR......................................................RRRRRR.........................................................................................................................", + "............................................................................HHHHHHRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH...RRRRRR........................................................RRRRRR........................................................................................................................", + "...........................................................................RHHHHHRRRRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHPPRRRRRRR.........................................................RRRRRR.......................................................................................................................", + "...........................................................................RHHHHR.RRRRRRRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHPRRRRRRR...........................................................RRRRR.......................................................................................................................", + "..........................................................................GRHHHHP..RRRRRRRRRRRRRRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHPRRRRRR.............................................................RRRRRRR....................................................................................................................", + "..........................................................................GRRRRRP.PRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRPPPPHHHHRHHHHHHHHHHHHHHHHHHHRRRRR...............................................................RRRRRRR....................................................................................................................", + "..........................................................................GRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHHHHRHHHHRRRRHHHHHHHHHHHRRRRR...............................................................RRRRRRR....................................................................................................................", + "..........................................................................GRRRRRRRRRRRPRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHHHHRHHHHRRRRRHHHHHHHHHHRRRRR.............................................................RRRRRRRRR....................................................................................................................", + "...........................................................................PRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHHHHRRHHH.....HHHHHHHHHRRRRRR............................................................RRRRRRR.......................................................................................................................", + ".............................................................................PRRRRRRRRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHHHH......HHHHHHHRRRRRRR..........................................................RRRRRRRR........................................................................................................................", + "...............................................................................RRRRRRRRRRRR...RRRRRRRRRRRRRRRRRRRRRRRPRRRRHHHH......HHHHHHRRRRRRRR........................................................RRRRRRRR..........................................................................................................................", + ".................................................................................RRRRRRRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRPRRRRHHHH......HHHHHHRRRRRRR........................................................RRRRRRRR...........................................................................................................................", + "...................................................................................RRRRRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.....HHHHHH..............................................................RRRRRRR.............................................................................................................................", + "...................................................................................PRRRRRRRRRPRRRRRRRRRRRRRRP.RRRRRRRRRRRRRRRRRRR...HHHHH...............................................................RRRRR...............................................................................................................................", + "...................................................................................RRRRRRRRRRRRRRRRRRRRRRRRRRPRRRRRRRRRRRRRRRRRRR..HHHHHH...............................................................RRRR................................................................................................................................", + "..................................................................................PRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.RRRRRR.HHHHHH................................................................RRR.................................................................................................................................", + "..................................................................................RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHHHRRRR..RRRRRHHHHHHH....................................................................................................................................................................................................", + ".................................................................................PRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHHHHHRRRR..RRRHHHHHHH.....................................................................................................................................................................................................", + ".................................................................................RRRRRRRRRRRRRRRRRRRRRRR..PRRRRRRRHHHHHRRRRR.RRRHHHHHHH.....................................................................................................................................................................................................", + "................................................................................RRRRRRRRRRRRRRRRRRRRRR......RRRRRHHHHHHRRRRRRRRRHHHHHH......................................................................................................................................................................................................", + "................................................................................RRRRRRRRRRRRRRRRRRRRRR.......RRRRHHHHHRRRRRRRRRRHHHHH.......................................................................................................................................................................................................", + "...............................................................................RRRRRRRRRRRRRRRRRRRRRRRRR.....PRRHHHHHHRRRRRRRRRRHHHH........................................................................................................................................................................................................", + "...............................................................................RRRRRRRRRRRRRRRRRRRRRRRRRRRRR..RRHHHHHRRRPRRRRRRRRRP.........................................................................................................................................................................................................", + "............................................................................PPRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR..RHHHHHRRRRRRRRRRRRP..........................................................................................................................................................................................................", + "...........................................................................RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHHHHHRRRRRRRRRRRRR...........................................................................................................................................................................................................", + "..........................................................................RRRRRRRRRRRRRRRRRRRRRPRRRRRRRRRRRRRRRHHHHHRRRRRRRRRRRRRR..........................................................................................................................................................................................................", + "..........................................................................RRRRRRRRRRRRRRRRRRRR...RRRRRRRRRRRRRRHHHHRRRRRRRRRRRRRRR..........................................................................................................................................................................................................", + ".........................................................................RRRRRRRRRRRRRRRRRRR......RRRRRRRRRRRRRHHHHRRRR.......RRRRP.........................................................................................................................................................................................................", + "........................................................................RRRRRRRRRRRRRRRRRRR........RRRRRR.RRRRHHHHHRRRRR......RRRRR.........................................................................................................................................................................................................", + "........................................................................RRRRRRRRRRRRRRRRRP.........RRRRRR.RRRRHHHHHRRRRR.......RRRR.........................................................................................................................................................................................................", + "........................................................................RRRRRRRRRRRRRRRR...........RRRRRRRRRRHHHHHRRRRRR.......RRRR.........................................................................................................................................................................................................", + ".........................................................................RRRRRRRRRRRRRP............PRRRRRRP.HHHHHHRRRRRR.......RRRR.........................................................................................................................................................................................................", + "..........................................................................RRRRRRRRRRR............RRRRRRRRRHHHHHHHHRRRRRRR......RRRR.........................................................................................................................................................................................................", + "...........................................................................PRRRRRRRR............RRRRRRRRHHHHHHHHHRRRRRRRRRRP...RRRRR........................................................................................................................................................................................................", + "..............................................................................RRRR.............PRRRRRRRHHHHHHHHHRRRRRRRRRRRR...RRRRR........................................................................................................................................................................................................", + "..............................................................................................PPRRRRRRHHHHHHHHHRRRRRPRRRRRRRRRRRRRRR........................................................................................................................................................................................................", + ".............................................................................................PPPRRRRHHHHHHHHHHRRRRRR...RRRRRRRRRRRR.........................................................................................................................................................................................................", + ".............................................................................................PPRRRRHHHHHHHHHRRRRRRRR...RRRR.RRRRRRP.........................................................................................................................................................................................................", + ".............................................................................................PRRRRHHHHHHHHRPRRRRRRRP..RRRRR..RRRRR..........................................................................................................................................................................................................", + ".............................................................................................PRRHHHHHHHHHRR.RRRRRRRRRRRRRR...RRRRR..........................................................................................................................................................................................................", + ".............................................................................................RRHHHHHHHH......RRRRRRRRRRRRR....RRRR..........................................................................................................................................................................................................", + "............................................................................................RRRHHHHHHH.......GRRRRRRRRRRRRRRRRRRRR..........................................................................................................................................................................................................", + "............................................................................................RRRHHHHH...............RRRRRRRRRRRRRRR..........................................................................................................................................................................................................", + "............................................................................................RRRHHHH...................RRRRRRRRRRRR..........................................................................................................................................................................................................", + "............................................................................................RRRHHHR.........RRRRR.....RRRRRRRRRRRR..........................................................................................................................................................................................................", + "............................................................................................HHHHRRRR.......RRRRRR......RRRRRRRRRRR..........................................................................................................................................................................................................", + "...........................................................................................HHHHHRRRRR....RRRRRRRRR......RRRRRRRRRR..........................................................................................................................................................................................................", + "..........................................................................................HHHHHHRRRRRR..RRRRRRRRRRR.....RRRRRRRRR...........................................................................................................................................................................................................", + "..........................................................................................HHHHHHRRRRRRRRRRRRRRRRRRRR....RRRRRRRRR...........................................................................................................................................................................................................", + ".........................................................................................HHHHHHRRRRRRRRRRRRRR..RRRRR..RRRRRRRRRRR...........................................................................................................................................................................................................", + "........................................................................................HHHHHH.RRRRRRRRRRRRR...RRRRRRRRRRRRRRRRRR...........................................................................................................................................................................................................", + "..................................................................PPP..................HHHHHHH.RRRRRRRRRRRRRR...RRRRRRRRRRR.RRRRR...........................................................................................................................................................................................................", + "..................................................................PPP..................HHHHHH..RRRRRRRRRRRRRR...RRRRRRRRRR.RRRRRR...........................................................................................................................................................................................................", + ".................................................................PPPPP.............PPPRHHHHH...PRRRRRRRRRRRRRR.RRRRRRRRR.PRRRRRR............................................................................................................................................................................................................", + "........................................................PPRRRRRRRRRRRRRRP..RRRRRRRRRRRRHHHH.....RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.............................................................................................................................................................................................................", + "................................................PRRRRRRRRRRRRRRRRRRRRRRRRRPRRRRRRRRRRRRRRRR.......RRRRRRRRRRRRRRRRRRRRRRRRRRRR..............................................................................................................................................................................................................", + ".............................................PRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR.........RRRRRRRRRRRRRRRRRRRRRRRRRR...............................................................................................................................................................................................................", + "............................................RRRRRRRRRRRRRRRRRRRRRRPPRRRRRRRRRRRRRRRRRRRRR..............RRRRRRRRRRRRRRRRRRRP.................................................................................................................................................................................................................", + "..........................................PRRRRRRRRRRRRRRPP..........PRRRRRRRRRRRRRRRRRRRR................RRRRRRRRRRPRRR....................................................................................................................................................................................................................", + ".........................................RRRRRRRRRP....................PRRRRRRPP.....RRRRRP.................................................................................................................................................................................................................................................", + "........................................RRRRRRRRP....................................RRRRRR.................................................................................................................................................................................................................................................", + "...............PPPPP..................PRRRRRRRR......................................RRRRRRR................................................................................................................................................................................................................................................", + "............RRRRRRRRRRRR............RRRRRRRRRR.......................................RRRRRRRP...............................................................................................................................................................................................................................................", + ".........PRRRRRRRRRRRRRRRRR.....PRRRRRRRRRRRP....................................RRRRRRRRRRRR...............................................................................................................................................................................................................................................", + ".......PRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR....................................RRRRRRRRRRRRRRR..............................................................................................................................................................................................................................................", + "......RRRRRRRRRRRPRRRRRRRRRRRRRRRRRRRRRRRP...................................RRRRRRRRRRR.RRRRR..............................................................................................................................................................................................................................................", + "....RRRRRRRRRRP......PRRRRRRRRRRRRRRRRP.....................................RRRRRRRRRRR..PRRRRR.............................................................................................................................................................................................................................................", + "..PRRRRRRRRRP...........PRRRRRRRRRRP.......................................RRRRRRR........RRRRRR............................................................................................................................................................................................................................................", + "RRRRRRRRRRP................................................................RRRRRR..........RRRRRP...........................................................................................................................................................................................................................................", + "RRRRRRRRR................................................................RRRRRR............PRRRRR...........................................................................................................................................................................................................................................", + "RRRRRRR..................................................................RRRRR..............RRRRRR..........................................................................................................................................................................................................................................", + "RRRRRP...................................................................RRRRR...............RRRRR..........................................................................................................................................................................................................................................", + "RRRR.....................................................................RRRR.................RRRR..........................................................................................................................................................................................................................................", +}}; + +} // namespace EdgeWeightGPS::Generated diff --git a/red4ext/EdgeWeightGPS/src/Main.cpp b/red4ext/EdgeWeightGPS/src/Main.cpp index 21c781e..d36c3e7 100644 --- a/red4ext/EdgeWeightGPS/src/Main.cpp +++ b/red4ext/EdgeWeightGPS/src/Main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,8 @@ #include #include +#include "GeneratedSpatialRoadGrid.hpp" + namespace RED4ext::v1 { struct Logger @@ -103,10 +106,15 @@ constexpr bool kEnableGpsTraceHooks = true; constexpr bool kEnableGpsQueryLifecycleHooks = true; constexpr bool kEnableGpsAsyncTrafficProbe = true; constexpr bool kEnableGpsTrafficEdgeWeightPatch = false; +constexpr bool kEnableGpsSpatialEdgeWeightPatch = false; +constexpr bool kEnableGpsSpatialEdgeWeightPatchTrace = false; constexpr bool kEnableGpsRouteJobLifecycleHooks = false; constexpr bool kEnableGpsRouteJobStartTrace = false; constexpr bool kEnableGpsLocalSearchHooks = false; constexpr bool kEnableRouteUiTraceHooks = false; +constexpr bool kEnableGpsLocalSearchTraceHooks = kEnableGpsTraceHooks && kEnableGpsLocalSearchHooks; +constexpr bool kEnableGpsRouteProducerHook = kEnableGpsLocalSearchTraceHooks || kEnableGpsSpatialEdgeWeightPatch; +constexpr bool kEnableGpsEdgeCostHook = kEnableGpsLocalSearchTraceHooks || kEnableGpsSpatialEdgeWeightPatch; constexpr uintptr_t kGpsSystemTickRva = 0x0E6B62C; constexpr uintptr_t kJournalTrackEntryImplRva = 0x05944FC; constexpr uintptr_t kJournalListenerArrayOffset = 0x210; @@ -197,6 +205,12 @@ constexpr uint16_t kTrafficLaneFlagGpsOnly = 0x0200; constexpr uint16_t kTrafficLaneFlagNoAiDriving = 0x2000; constexpr uint16_t kTrafficLaneFlagHighway = 0x4000; constexpr uint16_t kTrafficLaneFlagNoAutodrive = 0x8000; +constexpr bool kGpsSpatialPatchRequiresRouteProducer = true; +constexpr float kGpsSpatialHighwayMultiplier = 0.62f; +constexpr float kGpsSpatialRoadMultiplier = 1.0f; +constexpr float kGpsSpatialGpsOnlyMultiplier = 1.20f; +constexpr float kGpsSpatialPavementMultiplier = 1.35f; +constexpr float kGpsSpatialUnknownMultiplier = 1.05f; struct GpsProviderClassOverride { @@ -982,6 +996,122 @@ struct Vector3Value float z; }; +int GpsSpatialRoadClassRank(char aCode) +{ + switch (aCode) + { + case 'H': + return 4; + case 'R': + return 3; + case 'G': + return 2; + case 'P': + return 1; + default: + return 0; + } +} + +const char* GpsSpatialRoadClassName(char aCode) +{ + switch (aCode) + { + case 'H': + return "highway"; + case 'R': + return "road"; + case 'G': + return "gpsonly"; + case 'P': + return "pavement"; + default: + return "unknown"; + } +} + +float GpsSpatialRoadClassMultiplier(char aCode) +{ + switch (aCode) + { + case 'H': + return kGpsSpatialHighwayMultiplier; + case 'R': + return kGpsSpatialRoadMultiplier; + case 'G': + return kGpsSpatialGpsOnlyMultiplier; + case 'P': + return kGpsSpatialPavementMultiplier; + default: + return kGpsSpatialUnknownMultiplier; + } +} + +char LookupGpsSpatialRoadClass(float aX, float aMapY) +{ + using namespace EdgeWeightGPS::Generated; + + if (!std::isfinite(aX) || !std::isfinite(aMapY)) + { + return '.'; + } + + const auto columnFloat = (aX - kSpatialRoadGridMinX) / kSpatialRoadGridCellSize; + const auto rowFloat = (aMapY - kSpatialRoadGridMinY) / kSpatialRoadGridCellSize; + if (columnFloat < 0.0f || rowFloat < 0.0f) + { + return '.'; + } + + const auto column = static_cast(std::floor(columnFloat)); + const auto row = static_cast(std::floor(rowFloat)); + if (column < 0 || row < 0 || column >= static_cast(kSpatialRoadGridWidth) || + row >= static_cast(kSpatialRoadGridHeight)) + { + return '.'; + } + + const auto& rowData = kSpatialRoadGridRows[static_cast(row)]; + if (static_cast(column) >= rowData.size()) + { + return '.'; + } + + return rowData[static_cast(column)]; +} + +bool TryLookupGpsSpatialEdgeClass(void* aCurrentState, void* aNeighborState, char& aCode) +{ + Vector3Value current{}; + Vector3Value neighbor{}; + if (!aCurrentState || !aNeighborState || !TryReadMemory(aCurrentState, current) || + !TryReadMemory(aNeighborState, neighbor)) + { + return false; + } + + const auto midpointX = (current.x + neighbor.x) * 0.5f; + const auto midpointMapY = (current.z + neighbor.z) * 0.5f; + + // Search states are (world X, height, world Y); route producer query vectors use (X, Y, Z, W). + const std::array candidates = { + LookupGpsSpatialRoadClass(midpointX, midpointMapY), + LookupGpsSpatialRoadClass(current.x, current.z), + LookupGpsSpatialRoadClass(neighbor.x, neighbor.z), + }; + + aCode = '.'; + for (const auto candidate : candidates) + { + if (GpsSpatialRoadClassRank(candidate) > GpsSpatialRoadClassRank(aCode)) + { + aCode = candidate; + } + } + + return true; +} + void AppendVector3Pointer(std::ostringstream& aLine, const char* aLabel, const void* aVector) { Vector3Value value{}; @@ -4068,7 +4198,7 @@ int32_t DetourGpsRouteProducer(void* aGraph, void* aQuery, void* aOutResult) { std::lock_guard lock(gGpsCostLogMutex); callCount = gGpsRouteProducerLogCount++; - shouldLog = callCount < kMaxCalls; + shouldLog = kEnableGpsLocalSearchTraceHooks && callCount < kMaxCalls; } if (shouldLog) @@ -4331,6 +4461,21 @@ float DetourGpsEdgeCost(void* aCostProvider, void* aCurrentState, void* aNeighbo const auto sourceClass = ReadGpsPointClass(aCurrentPoint); const auto neighborClass = ReadGpsPointClass(aNeighborPoint); + const auto originalResult = result; + + char spatialClass = '.'; + float spatialMultiplier = 1.0f; + bool spatialAdjusted = false; + const auto spatialPatchAllowed = + kEnableGpsSpatialEdgeWeightPatch && + (!kGpsSpatialPatchRequiresRouteProducer || gActiveGpsRouteProducerCall != UINT32_MAX); + if (spatialPatchAllowed && result > 0.0f && std::isfinite(result) && + TryLookupGpsSpatialEdgeClass(aCurrentState, aNeighborState, spatialClass)) + { + spatialMultiplier = GpsSpatialRoadClassMultiplier(spatialClass); + result *= spatialMultiplier; + spatialAdjusted = spatialMultiplier != 1.0f; + } if (gActiveGpsEdgeCostStats) { @@ -4339,9 +4484,9 @@ float DetourGpsEdgeCost(void* aCostProvider, void* aCurrentState, void* aNeighbo } float multiplier = 0.0f; - const auto hasMultiplier = sourceClass < 64 && - TryReadFloatField(aCostProvider, 0x08 + static_cast(sourceClass) * sizeof(float), - multiplier); + const auto hasMultiplier = + neighborClass < 64 && + TryReadFloatField(aCostProvider, 0x08 + static_cast(neighborClass) * sizeof(float), multiplier); uint32_t callCount = 0; uint32_t classCallCount = 0; @@ -4349,21 +4494,29 @@ float DetourGpsEdgeCost(void* aCostProvider, void* aCurrentState, void* aNeighbo { std::lock_guard lock(gGpsCostLogMutex); callCount = gGpsEdgeCostLogCount++; - if (sourceClass < gGpsEdgeCostClassLogCounts.size()) + if (neighborClass < gGpsEdgeCostClassLogCounts.size()) { - classCallCount = gGpsEdgeCostClassLogCounts[sourceClass]++; + classCallCount = gGpsEdgeCostClassLogCounts[neighborClass]++; } - shouldLog = callCount < 32 || (sourceClass < 64 && classCallCount < 1); + shouldLog = + (kEnableGpsLocalSearchTraceHooks && (callCount < 32 || (neighborClass < 64 && classCallCount < 1))) || + (kEnableGpsSpatialEdgeWeightPatchTrace && spatialAdjusted && callCount < 128); } if (shouldLog) { - const auto baseCost = hasMultiplier && multiplier != 0.0f ? result / multiplier : 0.0f; + const auto baseCost = hasMultiplier && multiplier != 0.0f ? originalResult / multiplier : 0.0f; std::ostringstream line; line << "hook GPSEdgeCost 0x44f838 call=" << callCount << " classCall=" << classCallCount << " sourceClass=" << static_cast(sourceClass) << " neighborClass=" << static_cast(neighborClass) << " value=" << result; + if (spatialPatchAllowed) + { + line << " originalValue=" << originalResult << " spatialClass=" << GpsSpatialRoadClassName(spatialClass) + << " spatialMultiplier=" << spatialMultiplier + << " spatialAdjusted=" << static_cast(spatialAdjusted); + } if (hasMultiplier) { line << " multiplier=" << multiplier << " baseCost=" << baseCost; @@ -4815,21 +4968,30 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e reinterpret_cast(&DetourGpsRouteJobStart), reinterpret_cast(&gOriginalGpsRouteJobStart)); } - if (kEnableGpsProviderClassPatch || (kEnableGpsTraceHooks && kEnableGpsLocalSearchHooks)) + if (kEnableGpsProviderClassPatch || kEnableGpsLocalSearchTraceHooks) { AttachProbeHook("GPSSearch 0x44f054", kGpsSearchRva, reinterpret_cast(&DetourGpsSearch), reinterpret_cast(&gOriginalGpsSearch)); } - if (kEnableGpsTraceHooks && kEnableGpsLocalSearchHooks) + if (kEnableGpsRouteProducerHook) { AttachProbeHook("GPSRouteProducer 0x44cc7c", kGpsRouteProducerRva, reinterpret_cast(&DetourGpsRouteProducer), reinterpret_cast(&gOriginalGpsRouteProducer)); + } + if (kEnableGpsLocalSearchTraceHooks) + { AttachProbeHook("GPSResolveHandle 0x44e1a8", kGpsResolveHandleRva, reinterpret_cast(&DetourGpsResolveHandle), reinterpret_cast(&gOriginalGpsResolveHandle)); + } + if (kEnableGpsEdgeCostHook) + { AttachProbeHook("GPSEdgeCost 0x44f838", kGpsEdgeCostRva, reinterpret_cast(&DetourGpsEdgeCost), reinterpret_cast(&gOriginalGpsEdgeCost)); + } + if (kEnableGpsLocalSearchTraceHooks) + { AttachProbeHook("GPSFilteredProviderFilter 0x44ff68", kGpsFilteredProviderFilterRva, reinterpret_cast(&DetourGpsFilteredProviderFilter), reinterpret_cast(&gOriginalGpsFilteredProviderFilter)); @@ -4993,15 +5155,24 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e { DetachProbeHook("GPSRouteJobStart 0x818928", kGpsRouteJobStartRva); } - if (kEnableGpsProviderClassPatch || (kEnableGpsTraceHooks && kEnableGpsLocalSearchHooks)) + if (kEnableGpsProviderClassPatch || kEnableGpsLocalSearchTraceHooks) { DetachProbeHook("GPSSearch 0x44f054", kGpsSearchRva); } - if (kEnableGpsTraceHooks && kEnableGpsLocalSearchHooks) + if (kEnableGpsRouteProducerHook) { DetachProbeHook("GPSRouteProducer 0x44cc7c", kGpsRouteProducerRva); + } + if (kEnableGpsLocalSearchTraceHooks) + { DetachProbeHook("GPSResolveHandle 0x44e1a8", kGpsResolveHandleRva); + } + if (kEnableGpsEdgeCostHook) + { DetachProbeHook("GPSEdgeCost 0x44f838", kGpsEdgeCostRva); + } + if (kEnableGpsLocalSearchTraceHooks) + { DetachProbeHook("GPSFilteredProviderFilter 0x44ff68", kGpsFilteredProviderFilterRva); DetachProbeHook("GPSBaseProviderFilter 0x450b08", kGpsBaseProviderFilterRva); } diff --git a/tools/generate_spatial_edge_grid.py b/tools/generate_spatial_edge_grid.py new file mode 100644 index 0000000..5b10cfc --- /dev/null +++ b/tools/generate_spatial_edge_grid.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python3 +"""Generate a compact road-class grid for the RED4ext GPS edge-cost shim.""" + +from __future__ import annotations + +import argparse +import json +import math +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Iterable + + +FLAGS = { + "Pavement": 0x0008, + "Road": 0x0010, + "GPSOnly": 0x0200, + "Highway": 0x4000, +} + +CATEGORY_CODES = { + "unknown": ".", + "pavement": "P", + "gpsonly": "G", + "road": "R", + "highway": "H", +} + +CATEGORY_PRIORITY = { + ".": 0, + "P": 1, + "G": 2, + "R": 3, + "H": 4, +} + + +@dataclass(frozen=True) +class GridSpec: + min_x: float + min_y: float + width: int + height: int + cell_size: float + + +def flag_value(value: Any) -> int: + if isinstance(value, int): + return value + if isinstance(value, str): + return int(value) + if isinstance(value, dict): + for key in ("Value", "$value", "value"): + if key in value: + return flag_value(value[key]) + return int(value or 0) + + +def lane_category(flags: int) -> str: + if flags & FLAGS["Highway"]: + return "highway" + if flags & FLAGS["GPSOnly"]: + return "gpsonly" + if flags & FLAGS["Road"]: + return "road" + if flags & FLAGS["Pavement"]: + return "pavement" + return "unknown" + + +def load_lanes(path: Path) -> list[dict[str, Any]]: + data = json.loads(path.read_text(encoding="utf-8")) + return data["Data"]["RootChunk"]["data"]["lanes"] + + +def load_lane_polygons(path: Path) -> list[list[tuple[float, float]]]: + data = json.loads(path.read_text(encoding="utf-8")) + rows = data["Data"]["RootChunk"]["data"] + polygons: list[list[tuple[float, float]]] = [] + for row in rows: + polygon = row.get("value", {}).get("polygon") or [] + polygons.append([(float(point["X"]), float(point["Y"])) for point in polygon]) + return polygons + + +def point_in_polygon(x: float, y: float, polygon: list[tuple[float, float]]) -> bool: + inside = False + count = len(polygon) + if count < 3: + return False + + previous_x, previous_y = polygon[-1] + for current_x, current_y in polygon: + if (current_y > y) != (previous_y > y): + edge_x = (previous_x - current_x) * (y - current_y) / (previous_y - current_y) + current_x + if x < edge_x: + inside = not inside + previous_x, previous_y = current_x, current_y + + return inside + + +def orientation(ax: float, ay: float, bx: float, by: float, cx: float, cy: float) -> float: + return (by - ay) * (cx - bx) - (bx - ax) * (cy - by) + + +def on_segment(ax: float, ay: float, bx: float, by: float, cx: float, cy: float) -> bool: + return min(ax, cx) <= bx <= max(ax, cx) and min(ay, cy) <= by <= max(ay, cy) + + +def segments_intersect( + ax: float, + ay: float, + bx: float, + by: float, + cx: float, + cy: float, + dx: float, + dy: float, +) -> bool: + o1 = orientation(ax, ay, bx, by, cx, cy) + o2 = orientation(ax, ay, bx, by, dx, dy) + o3 = orientation(cx, cy, dx, dy, ax, ay) + o4 = orientation(cx, cy, dx, dy, bx, by) + + if (o1 > 0) != (o2 > 0) and (o3 > 0) != (o4 > 0): + return True + + eps = 1e-5 + if abs(o1) <= eps and on_segment(ax, ay, cx, cy, bx, by): + return True + if abs(o2) <= eps and on_segment(ax, ay, dx, dy, bx, by): + return True + if abs(o3) <= eps and on_segment(cx, cy, ax, ay, dx, dy): + return True + if abs(o4) <= eps and on_segment(cx, cy, bx, by, dx, dy): + return True + return False + + +def polygon_intersects_cell( + polygon: list[tuple[float, float]], + min_x: float, + min_y: float, + max_x: float, + max_y: float, +) -> bool: + center_x = (min_x + max_x) * 0.5 + center_y = (min_y + max_y) * 0.5 + if point_in_polygon(center_x, center_y, polygon): + return True + + corners = ((min_x, min_y), (max_x, min_y), (max_x, max_y), (min_x, max_y)) + if any(point_in_polygon(x, y, polygon) for x, y in corners): + return True + + if any(min_x <= x <= max_x and min_y <= y <= max_y for x, y in polygon): + return True + + cell_edges = ( + (min_x, min_y, max_x, min_y), + (max_x, min_y, max_x, max_y), + (max_x, max_y, min_x, max_y), + (min_x, max_y, min_x, min_y), + ) + previous_x, previous_y = polygon[-1] + for current_x, current_y in polygon: + for edge in cell_edges: + if segments_intersect(previous_x, previous_y, current_x, current_y, *edge): + return True + previous_x, previous_y = current_x, current_y + + return False + + +def grid_index(spec: GridSpec, x: float, y: float) -> tuple[int, int]: + column = math.floor((x - spec.min_x) / spec.cell_size) + row = math.floor((y - spec.min_y) / spec.cell_size) + return int(column), int(row) + + +def mark_cell(grid: list[list[str]], column: int, row: int, code: str) -> bool: + if row < 0 or row >= len(grid) or column < 0 or column >= len(grid[row]): + return False + if CATEGORY_PRIORITY[code] <= CATEGORY_PRIORITY[grid[row][column]]: + return False + grid[row][column] = code + return True + + +def iter_cells_for_polygon(spec: GridSpec, polygon: list[tuple[float, float]]) -> Iterable[tuple[int, int]]: + xs = [point[0] for point in polygon] + ys = [point[1] for point in polygon] + min_col, min_row = grid_index(spec, min(xs), min(ys)) + max_col, max_row = grid_index(spec, max(xs), max(ys)) + + for row in range(max(0, min_row), min(spec.height - 1, max_row) + 1): + for column in range(max(0, min_col), min(spec.width - 1, max_col) + 1): + cell_min_x = spec.min_x + column * spec.cell_size + cell_min_y = spec.min_y + row * spec.cell_size + if polygon_intersects_cell( + polygon, + cell_min_x, + cell_min_y, + cell_min_x + spec.cell_size, + cell_min_y + spec.cell_size, + ): + yield column, row + + +def build_grid( + lanes: list[dict[str, Any]], + polygons: list[list[tuple[float, float]]], + cell_size: float, + inflate_cells: int, +) -> tuple[GridSpec, list[list[str]], dict[str, int]]: + points = [point for polygon in polygons for point in polygon] + if not points: + raise ValueError("no polygon points found") + + min_x = math.floor(min(point[0] for point in points) / cell_size) * cell_size + min_y = math.floor(min(point[1] for point in points) / cell_size) * cell_size + max_x = math.ceil(max(point[0] for point in points) / cell_size) * cell_size + max_y = math.ceil(max(point[1] for point in points) / cell_size) * cell_size + spec = GridSpec( + min_x=min_x, + min_y=min_y, + width=int(round((max_x - min_x) / cell_size)), + height=int(round((max_y - min_y) / cell_size)), + cell_size=cell_size, + ) + + grid = [[CATEGORY_CODES["unknown"] for _ in range(spec.width)] for _ in range(spec.height)] + for index, (lane, polygon) in enumerate(zip(lanes, polygons, strict=True)): + if len(polygon) < 3: + continue + code = CATEGORY_CODES[lane_category(flag_value(lane.get("flags", 0)))] + if code == CATEGORY_CODES["unknown"]: + continue + + changed_cells: set[tuple[int, int]] = set() + for column, row in iter_cells_for_polygon(spec, polygon): + for dy in range(-inflate_cells, inflate_cells + 1): + for dx in range(-inflate_cells, inflate_cells + 1): + changed_cells.add((column + dx, row + dy)) + + for column, row in changed_cells: + mark_cell(grid, column, row, code) + + counts = {code: sum(row.count(code) for row in grid) for code in CATEGORY_PRIORITY} + return spec, grid, counts + + +def write_header(path: Path, spec: GridSpec, grid: list[list[str]], counts: dict[str, int]) -> None: + lines = [ + "#pragma once", + "", + "#include ", + "#include ", + "#include ", + "", + "namespace EdgeWeightGPS::Generated", + "{", + f"constexpr float kSpatialRoadGridMinX = {spec.min_x:.1f}f;", + f"constexpr float kSpatialRoadGridMinY = {spec.min_y:.1f}f;", + f"constexpr float kSpatialRoadGridCellSize = {spec.cell_size:.1f}f;", + f"constexpr uint32_t kSpatialRoadGridWidth = {spec.width};", + f"constexpr uint32_t kSpatialRoadGridHeight = {spec.height};", + "", + "// Cell codes: H=highway, R=road, G=GPS-only, P=pavement, .=unknown.", + "// Generated by tools/generate_spatial_edge_grid.py from all.traffic_persistent and all.lane_polygons.", + f"// Counts: H={counts['H']} R={counts['R']} G={counts['G']} P={counts['P']} unknown={counts['.']}.", + "constexpr std::array kSpatialRoadGridRows = {{", + ] + + for row in grid: + lines.append(f' "{("").join(row)}",') + + lines.extend( + [ + "}};", + "", + "} // namespace EdgeWeightGPS::Generated", + "", + ] + ) + path.write_text("\n".join(lines), encoding="utf-8") + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--traffic-json", type=Path, default=Path("work/raw-segment-json/all.traffic_persistent.json")) + parser.add_argument( + "--lane-polygons-json", + type=Path, + default=Path("work/traffic-companions/json/all.lane_polygons.json"), + ) + parser.add_argument( + "--output", + type=Path, + default=Path("red4ext/EdgeWeightGPS/src/GeneratedSpatialRoadGrid.hpp"), + ) + parser.add_argument("--cell-size", type=float, default=32.0) + parser.add_argument("--inflate-cells", type=int, default=1) + args = parser.parse_args() + + lanes = load_lanes(args.traffic_json) + polygons = load_lane_polygons(args.lane_polygons_json) + if len(lanes) != len(polygons): + raise ValueError(f"lane/polygon count mismatch: {len(lanes)} != {len(polygons)}") + + spec, grid, counts = build_grid(lanes, polygons, args.cell_size, args.inflate_cells) + args.output.parent.mkdir(parents=True, exist_ok=True) + write_header(args.output, spec, grid, counts) + + total = spec.width * spec.height + covered = total - sum(row.count(".") for row in grid) + print( + f"wrote {args.output} cells={total} covered={covered} " + f"size={spec.width}x{spec.height} origin=({spec.min_x},{spec.min_y}) cell={spec.cell_size}" + ) + print("counts " + " ".join(f"{code}={counts[code]}" for code in ("H", "R", "G", "P", "."))) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())