diff --git a/notebooks/.gitignore b/notebooks/.gitignore index 4c49bd78f..10ddf953e 100644 --- a/notebooks/.gitignore +++ b/notebooks/.gitignore @@ -1 +1,5 @@ .env + +# raw GSHHG download for box_dimension_coastlines.py — multi-hundred MB, re-downloaded on demand +.data/ + diff --git a/notebooks/box_dimension_coastlines.py b/notebooks/box_dimension_coastlines.py new file mode 100644 index 000000000..39065a002 --- /dev/null +++ b/notebooks/box_dimension_coastlines.py @@ -0,0 +1,417 @@ +#!/usr/bin/env python3 +""" +Prepares the coastline data for the box-dimension blog widgets. + +Downloads GSHHG (public domain), clips it to two bounding boxes (Bretagne and +a Normandy stretch), lightly simplifies each outline, projects it into the +small local coordinate system the browser widgets use, and writes the result +as JSON. + +Run: + uv run python box_dimension_coastlines.py + +Re-running is safe and idempotent — the GSHHG download is cached under +`.data/gshhg/` (gitignored) and skipped if already present. The two bounding +boxes and the simplification tolerance are the reproducible inputs: change a +constant below and re-run to regenerate the output. + +The JSON this writes (`output/box_dimension_coasts.json`) is *not* consumed +directly by the website — `website/utils/coastsToTs.ts` turns it into the +committed `coasts.ts` module. Keeping the split this way means all the actual +geo-processing stays in Python (shapely has far more mature tooling for this +than anything in the Node ecosystem), while the artifact that actually ships +to the browser is a small, versioned, machine-generated TypeScript file. +""" + +import io +import json +import math +import zipfile +from dataclasses import dataclass +from pathlib import Path + +import requests +import shapefile # pyshp +from shapely.geometry import LineString, Polygon, box +from shapely.ops import unary_union + +GSHHG_VERSION = "2.3.7" +GSHHG_URL = f"https://www.soest.hawaii.edu/pwessel/gshhg/gshhg-shp-{GSHHG_VERSION}.zip" + +DATA_DIR = Path(__file__).parent / ".data" / "gshhg" +OUTPUT_PATH = Path(__file__).parent / "output" / "box_dimension_coasts.json" + +# GSHHS Level 1 = coastline (mainland + islands), highest ("f"ull) resolution — +# needed so the small-scale jaggedness the widgets measure survives at all. +LEVEL1_SHAPEFILE = "GSHHS_shp/f/GSHHS_f_L1.shp" + +WORLD_SIZE = 100 # must match website/components/blog/box-dimension/shapes.ts WORLD_SIZE +TARGET_POINT_BUDGET = 2500 # per region — keeps combined coasts.ts comfortably under 100KB + + +@dataclass +class BBox: + lon_min: float + lon_max: float + lat_min: float + lat_max: float + + def to_shapely(self) -> "box": + return box(self.lon_min, self.lat_min, self.lon_max, self.lat_max) + + +# Bounding boxes as pinned by the approved blog post plan (kuesten_dimension.plan.md). +REGIONS: dict[str, BBox] = { + "bretagne": BBox(lon_min=-5.2, lon_max=-1.0, lat_min=47.2, lat_max=48.9), + # Calvados D-Day beaches / Baie des Veys to Le Tréport. Deliberately stops + # short of the Cotentin peninsula proper (Cherbourg / Cap de la Hague) — + # that stretch is itself jagged and would muddy the "smooth contrast + # coast" comparison the post makes against Bretagne. Also deliberately + # doesn't extend past Le Tréport, which sits almost exactly on the + # Normandy/Picardy département border — going further east would mean + # showing non-Normandy coast under the "Normandie" label. + "normandie": BBox(lon_min=-1.3, lon_max=1.4, lat_min=49.1, lat_max=50.1), +} + +# Douglas-Peucker tolerance in degrees. Must stay well below the real-world +# size of the widget's smallest grid cell for either region, or the widget +# would measure the simplification artifact instead of the actual coastline. +# 0.0025 deg is ~200-280m at these latitudes, vs. a ~4km smallest cell (see +# the printed "Shared scale" line below) — a ~14-20x margin. Chosen mainly to +# hit the <100KB combined output budget; see step 7 (Validierung) of the blog +# plan for the check that this doesn't erase the jaggedness being measured. +SIMPLIFY_TOLERANCE_DEG = 0.0025 + +# Separate, coarser tolerance for the land/water fill polygon — it only needs +# to look right at widget scale, not defend a box-counting measurement, so it +# can be simplified much more aggressively to keep the payload small. +LAND_SIMPLIFY_TOLERANCE_DEG = 0.01 + +# Minimum land fragment area to keep, in km². A bbox like Bretagne's picks up +# hundreds of tiny offshore rocks/islets (GSHHG resolves them individually) — +# below this size they're sub-pixel at the widget's canvas scale anyway, so +# they're dropped rather than bloating the payload with invisible detail. +MIN_LAND_FRAGMENT_KM2 = 1.0 + + +def download_gshhg() -> Path: + shapefile_path = DATA_DIR / LEVEL1_SHAPEFILE + if shapefile_path.exists(): + print(f"Using cached GSHHG data at {DATA_DIR}") + return shapefile_path + + print(f"Downloading GSHHG {GSHHG_VERSION} from {GSHHG_URL} (~150MB)...") + DATA_DIR.mkdir(parents=True, exist_ok=True) + response = requests.get(GSHHG_URL, timeout=300) + response.raise_for_status() + + print("Extracting...") + with zipfile.ZipFile(io.BytesIO(response.content)) as zf: + zf.extractall(DATA_DIR) + + if not shapefile_path.exists(): + raise FileNotFoundError( + f"Expected {shapefile_path} after extraction — GSHHG layout may have changed." + ) + + return shapefile_path + + +def load_level1_polygons(shapefile_path: Path, bbox: BBox) -> list[Polygon]: + """Reads GSHHS Level 1 records whose bounding box overlaps the target bbox.""" + sf = shapefile.Reader(str(shapefile_path)) + target = bbox.to_shapely() + polygons: list[Polygon] = [] + + for shape_rec in sf.iterShapeRecords(): + shp = shape_rec.shape + rec_lon_min, rec_lat_min, rec_lon_max, rec_lat_max = shp.bbox + if rec_lon_max < bbox.lon_min or rec_lon_min > bbox.lon_max: + continue + if rec_lat_max < bbox.lat_min or rec_lat_min > bbox.lat_max: + continue + + points = shp.points + parts = list(shp.parts) + [len(points)] + for i in range(len(parts) - 1): + ring = points[parts[i] : parts[i + 1]] + if len(ring) < 4: + continue + poly = Polygon(ring) + if not poly.is_valid: + poly = poly.buffer(0) + if poly.intersects(target): + polygons.append(poly) + + return polygons + + +def extract_coastline(polygons: list[Polygon], bbox: BBox) -> LineString: + target = bbox.to_shapely() + merged = unary_union(polygons) + clipped = merged.intersection(target) + + boundary = clipped.boundary + candidates = list(boundary.geoms) if hasattr(boundary, "geoms") else [boundary] + + real_coastline_parts: list[LineString] = [] + for geom in candidates: + if not isinstance(geom, LineString): + continue + coords = list(geom.coords) + # Drop sub-segments that run entirely along the bbox frame (clip artifacts). + # A ring can still mix real coastline with a frame-hugging closing edge, + # so also drop maximal runs of frame-only points within a ring. + filtered = _drop_frame_runs(coords, bbox) + real_coastline_parts.extend(filtered) + + if not real_coastline_parts: + raise ValueError(f"No real coastline found for bbox {bbox} — check the bbox against a map.") + + # Keep the longest remaining stretch (excludes offshore islands/fragments). + longest = max(real_coastline_parts, key=lambda ls: ls.length) + return longest + + +def _drop_frame_runs( + coords: list[tuple[float, float]], bbox: BBox, eps: float = 1e-7 +) -> list[LineString]: + """Splits a ring's coordinates into runs, dropping runs glued to the bbox frame.""" + + def on_frame(pt: tuple[float, float]) -> bool: + x, y = pt + return ( + abs(x - bbox.lon_min) < eps + or abs(x - bbox.lon_max) < eps + or abs(y - bbox.lat_min) < eps + or abs(y - bbox.lat_max) < eps + ) + + runs: list[LineString] = [] + current: list[tuple[float, float]] = [] + for pt in coords: + if on_frame(pt): + if len(current) >= 2: + runs.append(LineString(current)) + current = [] + else: + current.append(pt) + if len(current) >= 2: + runs.append(LineString(current)) + return runs + + +KM_PER_DEG = 111.32 # rough, fine at these latitudes + + +def extract_land_polygons(polygons: list[Polygon], bbox: BBox) -> list[Polygon]: + """The clipped land area itself, for the water/land fill — unlike + extract_coastline, the bbox-frame edges are kept: they're the true edge of + the visible map here, not a measurement artifact. + + Tiny fragments (see MIN_LAND_FRAGMENT_KM2) are dropped: a bbox like + Bretagne's overlaps hundreds of individually-resolved offshore rocks that + are sub-pixel at the widget's canvas scale and would only bloat the payload. + """ + target = bbox.to_shapely() + merged = unary_union(polygons) + clipped = merged.intersection(target) + geoms = list(clipped.geoms) if hasattr(clipped, "geoms") else [clipped] + + lat_mean = (bbox.lat_min + bbox.lat_max) / 2 + km2_per_deg2 = KM_PER_DEG * KM_PER_DEG * math.cos(math.radians(lat_mean)) + + return [ + g + for g in geoms + if isinstance(g, Polygon) + and not g.is_empty + and g.area * km2_per_deg2 >= MIN_LAND_FRAGMENT_KM2 + ] + + +def make_projector(bbox: BBox): + """Equirectangular projection into real kilometres (not yet fit to WORLD_SIZE), + shared by every geometry (coastline *and* land polygons) of one region. + + Longitude is scaled by cos(mean latitude) so x/y are both in true km — a + single shared scale (computed later, across all regions) then converts km + into world units. Deferring that scale is what keeps the comparison fair: + if each region picked its own scale to fill the world box edge-to-edge, the + same slider cellSize would silently mean a different real-world distance + for each region. + + The reference point is the bbox corner, not a coordinate taken from + whichever geometry happens to be projected first — using two different + geometries' own coordinates as their reference would silently offset them + from each other, and the coastline and its land fill must stay aligned. + """ + lat_mean = (bbox.lat_min + bbox.lat_max) / 2 + cos_lat = math.cos(math.radians(lat_mean)) + lon0, lat0 = bbox.lon_min, bbox.lat_min + + def project(lon: float, lat: float) -> tuple[float, float]: + return ((lon - lon0) * cos_lat * KM_PER_DEG, -(lat - lat0) * KM_PER_DEG) + + return project + + +def project_coords_to_km(coords: list[tuple[float, float]], project) -> list[tuple[float, float]]: + return [project(lon, lat) for lon, lat in coords] + + +def normalize_with_shared_scale( + km_coords: list[tuple[float, float]], scale: float, offset_x: float = 0, offset_y: float = 0 +) -> list[list[float]]: + return [[round(x * scale + offset_x, 3), round(y * scale + offset_y, 3)] for x, y in km_coords] + + +def center_in_world(points: list[list[float]], world_size: float) -> tuple[float, float]: + """Returns the (offset_x, offset_y) that centers `points` (already scaled to + world units, anchored at the origin) within the world_size x world_size box. + + Both regions share one scale (see main()), so a physically smaller region + like Normandie doesn't fill the box and would otherwise sit jammed in a + corner instead of looking like a normal, centered map. + """ + xs = [p[0] for p in points] + ys = [p[1] for p in points] + width, height = max(xs) - min(xs), max(ys) - min(ys) + return (world_size - width) / 2 - min(xs), (world_size - height) / 2 - min(ys) + + +def _haversine_length_km(coords: list[tuple[float, float]]) -> float: + r_earth = 6371.0 + total = 0.0 + for (lon1, lat1), (lon2, lat2) in zip(coords, coords[1:]): + phi1, phi2 = math.radians(lat1), math.radians(lat2) + dphi = math.radians(lat2 - lat1) + dlambda = math.radians(lon2 - lon1) + a = math.sin(dphi / 2) ** 2 + math.cos(phi1) * math.cos(phi2) * math.sin(dlambda / 2) ** 2 + total += 2 * r_earth * math.asin(math.sqrt(a)) + return total + + +def process_region(name: str, bbox: BBox, shapefile_path: Path) -> dict: + print(f"\n--- {name} ---") + polygons = load_level1_polygons(shapefile_path, bbox) + print(f" {len(polygons)} candidate polygon(s) overlap the bounding box") + + coastline = extract_coastline(polygons, bbox) + raw_km = _haversine_length_km(list(coastline.coords)) + print(f" raw coastline: {len(coastline.coords)} points, {raw_km:.1f} km") + + simplified = coastline.simplify(SIMPLIFY_TOLERANCE_DEG, preserve_topology=True) + simplified_km = _haversine_length_km(list(simplified.coords)) + print( + f" simplified: {len(simplified.coords)} points, {simplified_km:.1f} km " + f"(tolerance={SIMPLIFY_TOLERANCE_DEG} deg)" + ) + + if len(simplified.coords) > TARGET_POINT_BUDGET: + print( + f" WARNING: {len(simplified.coords)} points exceeds the " + f"{TARGET_POINT_BUDGET} budget — consider a coarser SIMPLIFY_TOLERANCE_DEG." + ) + + project = make_projector(bbox) + + line_coords = list(simplified.coords) + lons = [c[0] for c in line_coords] + lats = [c[1] for c in line_coords] + bbox_meta = {"lonMin": min(lons), "lonMax": max(lons), "latMin": min(lats), "latMax": max(lats)} + + km_coords = project_coords_to_km(line_coords, project) + x_range = max(x for x, _ in km_coords) - min(x for x, _ in km_coords) + y_range = max(y for _, y in km_coords) - min(y for _, y in km_coords) + + land_polygons = extract_land_polygons(polygons, bbox) + land_rings_km = [] + for poly in land_polygons: + simplified_ring = poly.exterior.simplify( + LAND_SIMPLIFY_TOLERANCE_DEG, preserve_topology=True + ) + land_rings_km.append(project_coords_to_km(list(simplified_ring.coords), project)) + ring_points = sum(len(r) for r in land_rings_km) + print(f" land fill: {len(land_rings_km)} ring(s), {ring_points} points total") + + return { + "name": name, + "km_coords": km_coords, + "land_rings_km": land_rings_km, + "sourceLengthKm": simplified_km, + "boundingBox": bbox_meta, + "spanKm": max(x_range, y_range), + } + + +def main(): + shapefile_path = download_gshhg() + + regions_raw = { + name: process_region(name, bbox, shapefile_path) for name, bbox in REGIONS.items() + } + + # One shared scale (world-units per km) for all regions — the region with the + # largest physical span fills the WORLD_SIZE box; every other region uses the + # exact same km-to-world-unit ratio, so a given slider cellSize always means + # the same real-world distance no matter which region is showing. + reference_span_km = max(r["spanKm"] for r in regions_raw.values()) + shared_scale = WORLD_SIZE / reference_span_km + min_cell_size_world = 1.5625 # smallest step in KaestchenSpiel/KuestenSpiel's CELL_SIZE_STEPS + min_cell_size_real_km = min_cell_size_world / shared_scale + + print( + f"\nShared scale: {shared_scale:.4f} world-units/km " + f"(reference span {reference_span_km:.1f} km)" + ) + print( + f"Smallest slider cell size ({min_cell_size_world} world-units) = " + f"{min_cell_size_real_km:.2f} km real" + ) + + regions_out = {} + for name, raw in regions_raw.items(): + # Center in the shared world box first (based on the coastline's own extent), + # then apply the exact same scale+offset to the land rings so both stay aligned. + unscaled_points = normalize_with_shared_scale(raw["km_coords"], shared_scale) + offset_x, offset_y = center_in_world(unscaled_points, WORLD_SIZE) + points = normalize_with_shared_scale(raw["km_coords"], shared_scale, offset_x, offset_y) + land_rings = [ + normalize_with_shared_scale(ring, shared_scale, offset_x, offset_y) + for ring in raw["land_rings_km"] + ] + + meta = { + "sourceLengthKm": raw["sourceLengthKm"], + "simplificationToleranceDeg": SIMPLIFY_TOLERANCE_DEG, + "minCellSizeWorld": min_cell_size_world, + "minCellSizeRealKm": min_cell_size_real_km, + "boundingBox": raw["boundingBox"], + } + approx_bytes = len(json.dumps(points)) + len(json.dumps(land_rings)) + print( + f" {name}: {len(points)} line points + {sum(len(r) for r in land_rings)} land " + f"points, ~{approx_bytes / 1024:.1f} KB, span used " + f"{raw['spanKm'] * shared_scale:.1f}/{WORLD_SIZE} world-units" + ) + regions_out[name] = { + "name": name, + "points": points, + "landRings": land_rings, + "worldSize": WORLD_SIZE, + "meta": meta, + } + + OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True) + with open(OUTPUT_PATH, "w") as f: + json.dump(regions_out, f, indent=2) + + total_bytes = OUTPUT_PATH.stat().st_size + print(f"\nWrote {OUTPUT_PATH} ({total_bytes / 1024:.1f} KB total)") + if total_bytes > 100_000: + print("WARNING: exceeds the ~100KB combined budget from the blog plan.") + + +if __name__ == "__main__": + main() diff --git a/notebooks/output/box_dimension_coasts.json b/notebooks/output/box_dimension_coasts.json new file mode 100644 index 000000000..1757db414 --- /dev/null +++ b/notebooks/output/box_dimension_coasts.json @@ -0,0 +1,10172 @@ +{ + "bretagne": { + "name": "bretagne", + "points": [ + [ + 76.634, + 86.853 + ], + [ + 76.561, + 86.31 + ], + [ + 75.982, + 85.583 + ], + [ + 75.993, + 85.385 + ], + [ + 76.162, + 85.384 + ], + [ + 76.296, + 85.114 + ], + [ + 76.331, + 84.044 + ], + [ + 77.372, + 83.718 + ], + [ + 78.222, + 83.72 + ], + [ + 78.536, + 83.538 + ], + [ + 78.631, + 83.683 + ], + [ + 78.802, + 83.501 + ], + [ + 79.434, + 83.392 + ], + [ + 79.081, + 83.266 + ], + [ + 79.458, + 82.994 + ], + [ + 80.475, + 83.032 + ], + [ + 81.032, + 83.429 + ], + [ + 81.393, + 83.503 + ], + [ + 80.994, + 83.265 + ], + [ + 81.055, + 83.138 + ], + [ + 82.316, + 83.466 + ], + [ + 82.525, + 83.309 + ], + [ + 82.582, + 82.974 + ], + [ + 82.348, + 82.563 + ], + [ + 80.789, + 81.942 + ], + [ + 80.11, + 81.941 + ], + [ + 79.166, + 82.415 + ], + [ + 77.544, + 82.487 + ], + [ + 76.332, + 83.066 + ], + [ + 76.019, + 82.705 + ], + [ + 75.885, + 83.12 + ], + [ + 75.982, + 83.228 + ], + [ + 75.933, + 83.374 + ], + [ + 75.676, + 83.428 + ], + [ + 75.484, + 84.08 + ], + [ + 74.999, + 84.045 + ], + [ + 74.745, + 84.207 + ], + [ + 74.733, + 84.516 + ], + [ + 73.91, + 84.698 + ], + [ + 73.57, + 85.314 + ], + [ + 72.675, + 85.566 + ], + [ + 71.39, + 84.588 + ], + [ + 70.978, + 83.935 + ], + [ + 70.008, + 83.501 + ], + [ + 69.378, + 83.538 + ], + [ + 68.944, + 83.755 + ], + [ + 69.196, + 84.351 + ], + [ + 69.137, + 84.515 + ], + [ + 68.215, + 84.371 + ], + [ + 67.782, + 83.973 + ], + [ + 67.466, + 84.045 + ], + [ + 66.134, + 83.247 + ], + [ + 65.396, + 83.011 + ], + [ + 65.456, + 82.703 + ], + [ + 66.133, + 82.558 + ], + [ + 66.401, + 82.705 + ], + [ + 66.714, + 83.283 + ], + [ + 66.982, + 83.357 + ], + [ + 67.079, + 83.103 + ], + [ + 67.393, + 83.248 + ], + [ + 67.258, + 82.976 + ], + [ + 67.601, + 82.866 + ], + [ + 67.392, + 82.668 + ], + [ + 66.775, + 82.578 + ], + [ + 66.86, + 82.413 + ], + [ + 66.981, + 82.522 + ], + [ + 67.466, + 82.268 + ], + [ + 67.321, + 81.98 + ], + [ + 67.176, + 82.124 + ], + [ + 66.668, + 82.125 + ], + [ + 66.328, + 82.56 + ], + [ + 66.655, + 81.782 + ], + [ + 66.559, + 80.837 + ], + [ + 65.963, + 79.877 + ], + [ + 65.188, + 79.552 + ], + [ + 65.079, + 79.351 + ], + [ + 65.335, + 79.08 + ], + [ + 65.965, + 78.862 + ], + [ + 66.789, + 78.065 + ], + [ + 67.031, + 78.065 + ], + [ + 67.128, + 77.774 + ], + [ + 67.418, + 77.739 + ], + [ + 67.733, + 77.341 + ], + [ + 67.902, + 77.775 + ], + [ + 68.047, + 77.594 + ], + [ + 68.24, + 77.74 + ], + [ + 68.739, + 77.721 + ], + [ + 68.036, + 77.142 + ], + [ + 68.193, + 76.725 + ], + [ + 68.423, + 76.705 + ], + [ + 68.072, + 76.218 + ], + [ + 67.636, + 76.146 + ], + [ + 67.345, + 76.509 + ], + [ + 66.921, + 76.126 + ], + [ + 66.776, + 75.73 + ], + [ + 67.09, + 75.294 + ], + [ + 67.041, + 74.932 + ], + [ + 66.704, + 74.459 + ], + [ + 66.836, + 74.115 + ], + [ + 67.346, + 74.116 + ], + [ + 67.66, + 74.441 + ], + [ + 68.314, + 74.152 + ], + [ + 69.452, + 74.26 + ], + [ + 69.841, + 73.826 + ], + [ + 70.081, + 74.008 + ], + [ + 70.106, + 73.789 + ], + [ + 69.768, + 73.681 + ], + [ + 69.331, + 74.081 + ], + [ + 68.411, + 73.969 + ], + [ + 67.732, + 73.463 + ], + [ + 66.738, + 73.248 + ], + [ + 66.92, + 72.901 + ], + [ + 66.837, + 72.773 + ], + [ + 66.763, + 73.138 + ], + [ + 66.376, + 72.813 + ], + [ + 65.455, + 72.993 + ], + [ + 65.467, + 73.192 + ], + [ + 65.225, + 73.372 + ], + [ + 65.31, + 73.571 + ], + [ + 64.704, + 73.283 + ], + [ + 64.027, + 73.209 + ], + [ + 63.809, + 73.245 + ], + [ + 63.591, + 73.644 + ], + [ + 63.323, + 73.789 + ], + [ + 62.875, + 73.772 + ], + [ + 62.936, + 73.536 + ], + [ + 63.057, + 73.609 + ], + [ + 63.228, + 73.354 + ], + [ + 63.421, + 73.318 + ], + [ + 63.362, + 73.481 + ], + [ + 63.493, + 73.536 + ], + [ + 63.579, + 73.12 + ], + [ + 63.458, + 72.937 + ], + [ + 63.905, + 72.667 + ], + [ + 64.147, + 72.703 + ], + [ + 64.427, + 72.286 + ], + [ + 64.571, + 71.85 + ], + [ + 64.536, + 71.723 + ], + [ + 64.293, + 72.232 + ], + [ + 63.76, + 72.703 + ], + [ + 63.349, + 72.087 + ], + [ + 63.433, + 72.431 + ], + [ + 63.324, + 72.594 + ], + [ + 62.596, + 72.521 + ], + [ + 63.24, + 72.792 + ], + [ + 63.105, + 73.247 + ], + [ + 62.017, + 73.209 + ], + [ + 62.113, + 73.028 + ], + [ + 61.482, + 72.774 + ], + [ + 61.931, + 73.191 + ], + [ + 61.882, + 73.663 + ], + [ + 61.434, + 74.189 + ], + [ + 60.707, + 73.825 + ], + [ + 59.906, + 73.718 + ], + [ + 59.786, + 73.936 + ], + [ + 59.302, + 74.116 + ], + [ + 58.503, + 74.225 + ], + [ + 58.188, + 74.625 + ], + [ + 56.712, + 74.116 + ], + [ + 56.577, + 73.989 + ], + [ + 56.698, + 73.627 + ], + [ + 56.65, + 73.373 + ], + [ + 56.346, + 73.137 + ], + [ + 56.227, + 72.812 + ], + [ + 55.401, + 72.266 + ], + [ + 55.089, + 72.449 + ], + [ + 54.954, + 72.36 + ], + [ + 55.355, + 71.977 + ], + [ + 54.773, + 72.123 + ], + [ + 54.712, + 71.959 + ], + [ + 54.857, + 71.706 + ], + [ + 54.663, + 71.489 + ], + [ + 54.82, + 71.47 + ], + [ + 54.894, + 71.182 + ], + [ + 54.99, + 71.361 + ], + [ + 55.184, + 71.217 + ], + [ + 55.257, + 71.506 + ], + [ + 55.427, + 71.29 + ], + [ + 55.62, + 71.543 + ], + [ + 55.51, + 71.198 + ], + [ + 55.79, + 71.108 + ], + [ + 55.814, + 71.543 + ], + [ + 56.069, + 71.452 + ], + [ + 55.924, + 71.814 + ], + [ + 56.322, + 71.688 + ], + [ + 56.358, + 71.996 + ], + [ + 56.237, + 72.14 + ], + [ + 56.517, + 72.302 + ], + [ + 56.723, + 72.214 + ], + [ + 56.504, + 72.141 + ], + [ + 56.662, + 71.871 + ], + [ + 56.976, + 72.016 + ], + [ + 57.293, + 71.76 + ], + [ + 57.207, + 71.995 + ], + [ + 57.28, + 72.284 + ], + [ + 57.341, + 72.342 + ], + [ + 57.329, + 72.068 + ], + [ + 57.498, + 72.031 + ], + [ + 57.474, + 71.778 + ], + [ + 57.327, + 71.705 + ], + [ + 57.364, + 71.47 + ], + [ + 57.872, + 71.508 + ], + [ + 57.861, + 72.179 + ], + [ + 58.091, + 72.269 + ], + [ + 58.151, + 72.068 + ], + [ + 58.056, + 71.923 + ], + [ + 58.333, + 71.688 + ], + [ + 58.526, + 71.905 + ], + [ + 58.733, + 71.885 + ], + [ + 58.623, + 72.196 + ], + [ + 59.037, + 72.051 + ], + [ + 59.131, + 72.304 + ], + [ + 59.302, + 72.339 + ], + [ + 59.763, + 72.051 + ], + [ + 60.005, + 72.086 + ], + [ + 59.921, + 71.705 + ], + [ + 60.162, + 71.343 + ], + [ + 60.115, + 71.018 + ], + [ + 60.43, + 70.763 + ], + [ + 60.38, + 70.221 + ], + [ + 60.61, + 70.13 + ], + [ + 60.659, + 70.421 + ], + [ + 60.878, + 70.419 + ], + [ + 60.72, + 70.364 + ], + [ + 60.852, + 70.021 + ], + [ + 61.023, + 70.201 + ], + [ + 61.095, + 70.02 + ], + [ + 61.252, + 70.038 + ], + [ + 61.105, + 69.821 + ], + [ + 61.253, + 69.747 + ], + [ + 61.203, + 69.277 + ], + [ + 61.349, + 69.134 + ], + [ + 60.803, + 67.92 + ], + [ + 60.816, + 68.3 + ], + [ + 61.01, + 68.479 + ], + [ + 61.131, + 68.88 + ], + [ + 60.95, + 69.334 + ], + [ + 60.683, + 69.079 + ], + [ + 60.622, + 69.096 + ], + [ + 60.889, + 69.386 + ], + [ + 60.854, + 69.587 + ], + [ + 60.598, + 69.785 + ], + [ + 60.661, + 69.984 + ], + [ + 60.417, + 69.985 + ], + [ + 60.318, + 69.513 + ], + [ + 60.127, + 69.587 + ], + [ + 60.053, + 69.405 + ], + [ + 59.933, + 69.404 + ], + [ + 60.065, + 69.568 + ], + [ + 60.006, + 69.658 + ], + [ + 59.255, + 68.97 + ], + [ + 58.636, + 68.735 + ], + [ + 58.698, + 68.498 + ], + [ + 58.841, + 68.499 + ], + [ + 59.969, + 68.987 + ], + [ + 59.726, + 68.77 + ], + [ + 59.752, + 68.518 + ], + [ + 59.885, + 68.428 + ], + [ + 59.667, + 68.353 + ], + [ + 59.606, + 68.735 + ], + [ + 59.459, + 68.697 + ], + [ + 59.291, + 68.336 + ], + [ + 59.387, + 68.009 + ], + [ + 59.239, + 67.864 + ], + [ + 59.254, + 67.593 + ], + [ + 59.143, + 68.226 + ], + [ + 58.866, + 68.318 + ], + [ + 58.429, + 68.172 + ], + [ + 58.346, + 68.008 + ], + [ + 58.54, + 67.755 + ], + [ + 58.309, + 67.881 + ], + [ + 58.116, + 67.521 + ], + [ + 58.223, + 68.01 + ], + [ + 58.637, + 68.409 + ], + [ + 58.553, + 68.679 + ], + [ + 58.093, + 68.862 + ], + [ + 57.533, + 68.679 + ], + [ + 57.097, + 69.079 + ], + [ + 57.012, + 69.024 + ], + [ + 57.193, + 68.753 + ], + [ + 57.003, + 68.718 + ], + [ + 57.039, + 68.842 + ], + [ + 56.928, + 68.897 + ], + [ + 56.445, + 68.824 + ], + [ + 56.467, + 68.679 + ], + [ + 56.324, + 68.644 + ], + [ + 56.068, + 68.806 + ], + [ + 56.383, + 68.916 + ], + [ + 56.117, + 69.277 + ], + [ + 56.311, + 69.495 + ], + [ + 56.227, + 69.768 + ], + [ + 55.476, + 69.44 + ], + [ + 55.245, + 69.786 + ], + [ + 55.463, + 69.748 + ], + [ + 55.355, + 70.385 + ], + [ + 55.112, + 70.166 + ], + [ + 54.844, + 70.347 + ], + [ + 54.955, + 70.039 + ], + [ + 54.844, + 69.946 + ], + [ + 54.554, + 70.384 + ], + [ + 54.373, + 70.003 + ], + [ + 54.567, + 69.967 + ], + [ + 54.579, + 69.514 + ], + [ + 54.361, + 69.876 + ], + [ + 54.275, + 69.422 + ], + [ + 54.374, + 69.243 + ], + [ + 54.226, + 69.312 + ], + [ + 54.083, + 69.75 + ], + [ + 54.154, + 70.184 + ], + [ + 54.071, + 70.203 + ], + [ + 53.695, + 69.206 + ], + [ + 53.816, + 69.025 + ], + [ + 53.743, + 68.626 + ], + [ + 54.106, + 68.445 + ], + [ + 53.998, + 68.318 + ], + [ + 53.475, + 68.408 + ], + [ + 53.38, + 68.154 + ], + [ + 53.475, + 67.973 + ], + [ + 53.185, + 67.901 + ], + [ + 53.259, + 67.538 + ], + [ + 52.944, + 67.178 + ], + [ + 52.93, + 66.905 + ], + [ + 52.822, + 67.213 + ], + [ + 52.92, + 67.538 + ], + [ + 53.114, + 67.719 + ], + [ + 53.136, + 68.083 + ], + [ + 53.38, + 68.226 + ], + [ + 53.598, + 68.99 + ], + [ + 53.271, + 69.078 + ], + [ + 53.355, + 69.242 + ], + [ + 53.185, + 69.315 + ], + [ + 53.575, + 69.64 + ], + [ + 53.307, + 70.074 + ], + [ + 53.415, + 70.349 + ], + [ + 53.78, + 70.492 + ], + [ + 53.817, + 70.8 + ], + [ + 54.143, + 71.287 + ], + [ + 54.349, + 71.345 + ], + [ + 54.263, + 71.578 + ], + [ + 54.094, + 71.616 + ], + [ + 53.633, + 71.506 + ], + [ + 53.464, + 71.144 + ], + [ + 53.294, + 71.616 + ], + [ + 52.956, + 71.433 + ], + [ + 52.906, + 71.217 + ], + [ + 53.113, + 71.307 + ], + [ + 52.968, + 71.017 + ], + [ + 53.04, + 70.872 + ], + [ + 52.833, + 70.564 + ], + [ + 52.485, + 70.437 + ], + [ + 52.738, + 70.095 + ], + [ + 52.448, + 70.239 + ], + [ + 52.289, + 70.039 + ], + [ + 52.568, + 70.999 + ], + [ + 52.35, + 70.817 + ], + [ + 52.301, + 71.071 + ], + [ + 52.01, + 71.072 + ], + [ + 51.708, + 70.186 + ], + [ + 51.803, + 69.676 + ], + [ + 51.612, + 69.567 + ], + [ + 51.612, + 69.135 + ], + [ + 51.442, + 68.844 + ], + [ + 51.611, + 68.59 + ], + [ + 51.332, + 68.608 + ], + [ + 51.236, + 67.957 + ], + [ + 51.161, + 68.246 + ], + [ + 50.897, + 68.246 + ], + [ + 50.884, + 68.3 + ], + [ + 51.189, + 68.28 + ], + [ + 51.248, + 68.662 + ], + [ + 51.393, + 68.769 + ], + [ + 51.513, + 69.314 + ], + [ + 51.393, + 69.567 + ], + [ + 51.513, + 69.93 + ], + [ + 51.418, + 70.002 + ], + [ + 51.647, + 71.001 + ], + [ + 51.067, + 70.745 + ], + [ + 51.199, + 70.474 + ], + [ + 51.089, + 70.312 + ], + [ + 51.067, + 70.566 + ], + [ + 50.704, + 70.601 + ], + [ + 50.677, + 70.889 + ], + [ + 50.316, + 70.782 + ], + [ + 49.418, + 71.181 + ], + [ + 49.091, + 70.689 + ], + [ + 49.177, + 70.527 + ], + [ + 49.541, + 70.636 + ], + [ + 49.528, + 70.401 + ], + [ + 49.226, + 70.456 + ], + [ + 49.275, + 70.24 + ], + [ + 49.078, + 70.24 + ], + [ + 48.523, + 69.659 + ], + [ + 48.46, + 70.691 + ], + [ + 48.873, + 70.618 + ], + [ + 48.486, + 71.272 + ], + [ + 48.389, + 72.033 + ], + [ + 48.486, + 72.974 + ], + [ + 48.607, + 73.408 + ], + [ + 48.801, + 73.517 + ], + [ + 48.802, + 74.024 + ], + [ + 49.031, + 74.37 + ], + [ + 49.541, + 74.696 + ], + [ + 49.6, + 75.039 + ], + [ + 49.891, + 75.258 + ], + [ + 49.781, + 75.31 + ], + [ + 48.838, + 74.948 + ], + [ + 48.427, + 75.093 + ], + [ + 48.075, + 74.677 + ], + [ + 48.074, + 74.314 + ], + [ + 47.833, + 73.807 + ], + [ + 47.904, + 73.591 + ], + [ + 47.807, + 73.047 + ], + [ + 47.542, + 72.757 + ], + [ + 48.015, + 72.629 + ], + [ + 48.293, + 71.923 + ], + [ + 48.195, + 70.366 + ], + [ + 47.638, + 69.35 + ], + [ + 47.856, + 69.134 + ], + [ + 47.505, + 69.187 + ], + [ + 46.681, + 68.607 + ], + [ + 46.416, + 68.608 + ], + [ + 46.452, + 68.338 + ], + [ + 46.161, + 67.863 + ], + [ + 46.38, + 67.212 + ], + [ + 46.257, + 67.103 + ], + [ + 46.246, + 66.795 + ], + [ + 46.839, + 66.922 + ], + [ + 46.706, + 66.686 + ], + [ + 46.512, + 66.796 + ], + [ + 46.184, + 66.633 + ], + [ + 46.535, + 66.469 + ], + [ + 46.525, + 66.27 + ], + [ + 46.658, + 66.143 + ], + [ + 46.803, + 66.214 + ], + [ + 46.925, + 65.707 + ], + [ + 47.043, + 65.925 + ], + [ + 47.602, + 66.108 + ], + [ + 47.542, + 65.872 + ], + [ + 47.651, + 65.708 + ], + [ + 47.82, + 65.854 + ], + [ + 48.109, + 65.347 + ], + [ + 48.449, + 65.274 + ], + [ + 48.872, + 65.435 + ], + [ + 48.643, + 65.021 + ], + [ + 48.233, + 65.237 + ], + [ + 48.037, + 65.128 + ], + [ + 48.063, + 65.309 + ], + [ + 47.772, + 65.31 + ], + [ + 47.807, + 65.471 + ], + [ + 47.675, + 65.527 + ], + [ + 47.347, + 65.364 + ], + [ + 47.942, + 65.057 + ], + [ + 47.88, + 64.786 + ], + [ + 47.965, + 64.475 + ], + [ + 48.123, + 64.495 + ], + [ + 48.087, + 64.841 + ], + [ + 48.572, + 64.983 + ], + [ + 48.487, + 64.569 + ], + [ + 48.849, + 64.386 + ], + [ + 48.595, + 64.257 + ], + [ + 48.595, + 64.113 + ], + [ + 49.238, + 64.42 + ], + [ + 49.031, + 64.041 + ], + [ + 48.573, + 64.076 + ], + [ + 48.426, + 64.296 + ], + [ + 47.749, + 64.403 + ], + [ + 47.688, + 64.749 + ], + [ + 47.555, + 64.802 + ], + [ + 47.579, + 64.332 + ], + [ + 47.82, + 64.331 + ], + [ + 48.109, + 63.823 + ], + [ + 48.255, + 64.005 + ], + [ + 48.317, + 63.878 + ], + [ + 48.257, + 63.68 + ], + [ + 47.989, + 63.896 + ], + [ + 47.88, + 63.769 + ], + [ + 48.389, + 63.189 + ], + [ + 48.04, + 63.389 + ], + [ + 47.965, + 62.955 + ], + [ + 47.88, + 63.372 + ], + [ + 47.663, + 63.66 + ], + [ + 47.806, + 63.769 + ], + [ + 47.698, + 63.931 + ], + [ + 47.334, + 63.86 + ], + [ + 47.286, + 63.572 + ], + [ + 46.875, + 63.571 + ], + [ + 46.791, + 63.372 + ], + [ + 46.865, + 63.263 + ], + [ + 46.67, + 63.188 + ], + [ + 46.742, + 63.842 + ], + [ + 47.068, + 63.642 + ], + [ + 47.324, + 64.059 + ], + [ + 47.177, + 64.275 + ], + [ + 47.373, + 64.64 + ], + [ + 47.252, + 64.819 + ], + [ + 47.491, + 65.002 + ], + [ + 47.189, + 65.237 + ], + [ + 46.971, + 64.984 + ], + [ + 46.657, + 65.094 + ], + [ + 46.536, + 64.767 + ], + [ + 46.621, + 65.184 + ], + [ + 46.355, + 65.329 + ], + [ + 46.56, + 65.492 + ], + [ + 46.705, + 65.417 + ], + [ + 46.706, + 65.67 + ], + [ + 46.296, + 65.747 + ], + [ + 46.1, + 65.419 + ], + [ + 46.016, + 65.474 + ], + [ + 46.258, + 65.763 + ], + [ + 46.148, + 65.925 + ], + [ + 46.45, + 65.982 + ], + [ + 46.233, + 66.306 + ], + [ + 46.246, + 66.506 + ], + [ + 46.004, + 66.433 + ], + [ + 45.919, + 66.669 + ], + [ + 46.137, + 67.176 + ], + [ + 46.003, + 67.737 + ], + [ + 44.719, + 66.434 + ], + [ + 44.211, + 66.108 + ], + [ + 42.732, + 65.49 + ], + [ + 42.102, + 65.49 + ], + [ + 41.836, + 65.889 + ], + [ + 41.727, + 65.691 + ], + [ + 41.983, + 65.201 + ], + [ + 42.151, + 65.345 + ], + [ + 43.025, + 65.31 + ], + [ + 44.067, + 65.855 + ], + [ + 43.873, + 65.274 + ], + [ + 43.41, + 65.202 + ], + [ + 43.255, + 65.001 + ], + [ + 43.436, + 64.767 + ], + [ + 43.001, + 65.019 + ], + [ + 42.2, + 64.873 + ], + [ + 42.03, + 65.128 + ], + [ + 41.678, + 64.929 + ], + [ + 41.885, + 64.694 + ], + [ + 42.031, + 64.731 + ], + [ + 42.054, + 64.548 + ], + [ + 42.261, + 64.53 + ], + [ + 42.285, + 64.386 + ], + [ + 42.114, + 64.24 + ], + [ + 42.261, + 64.059 + ], + [ + 42.115, + 63.95 + ], + [ + 42.2, + 63.679 + ], + [ + 42.49, + 63.968 + ], + [ + 42.757, + 63.86 + ], + [ + 42.732, + 63.679 + ], + [ + 42.951, + 63.715 + ], + [ + 43.193, + 63.207 + ], + [ + 43.399, + 63.079 + ], + [ + 43.701, + 62.157 + ], + [ + 44.004, + 62.138 + ], + [ + 44.067, + 61.721 + ], + [ + 43.726, + 61.65 + ], + [ + 43.956, + 61.847 + ], + [ + 43.896, + 62.122 + ], + [ + 43.605, + 62.013 + ], + [ + 43.412, + 62.446 + ], + [ + 43.049, + 62.773 + ], + [ + 42.829, + 62.736 + ], + [ + 42.868, + 63.117 + ], + [ + 42.538, + 63.351 + ], + [ + 42.297, + 63.209 + ], + [ + 42.298, + 63.425 + ], + [ + 42.177, + 63.354 + ], + [ + 42.115, + 62.898 + ], + [ + 42.007, + 62.845 + ], + [ + 42.093, + 63.299 + ], + [ + 41.945, + 63.334 + ], + [ + 42.042, + 63.443 + ], + [ + 41.739, + 64.078 + ], + [ + 41.644, + 64.113 + ], + [ + 41.618, + 63.932 + ], + [ + 41.424, + 64.042 + ], + [ + 41.351, + 63.825 + ], + [ + 40.625, + 63.751 + ], + [ + 41.304, + 64.041 + ], + [ + 41.389, + 64.348 + ], + [ + 41.559, + 64.459 + ], + [ + 41.085, + 65.164 + ], + [ + 40.165, + 65.202 + ], + [ + 39.827, + 65.057 + ], + [ + 39.099, + 65.454 + ], + [ + 38.847, + 65.291 + ], + [ + 38.905, + 65.054 + ], + [ + 38.227, + 64.549 + ], + [ + 38.203, + 64.222 + ], + [ + 37.73, + 63.952 + ], + [ + 37.779, + 63.77 + ], + [ + 37.537, + 63.262 + ], + [ + 36.881, + 62.43 + ], + [ + 36.981, + 62.247 + ], + [ + 36.859, + 61.995 + ], + [ + 36.884, + 61.704 + ], + [ + 37.028, + 61.559 + ], + [ + 36.968, + 61.069 + ], + [ + 36.834, + 61.27 + ], + [ + 36.907, + 61.487 + ], + [ + 36.786, + 61.811 + ], + [ + 36.811, + 62.286 + ], + [ + 36.604, + 62.628 + ], + [ + 35.927, + 62.265 + ], + [ + 34.789, + 62.267 + ], + [ + 34.497, + 62.122 + ], + [ + 34.424, + 62.267 + ], + [ + 33.503, + 62.013 + ], + [ + 33.431, + 61.613 + ], + [ + 33.093, + 61.795 + ], + [ + 32.802, + 61.577 + ], + [ + 32.679, + 61.94 + ], + [ + 32.534, + 61.939 + ], + [ + 31.264, + 60.945 + ], + [ + 31.638, + 60.382 + ], + [ + 31.905, + 60.417 + ], + [ + 31.881, + 60.236 + ], + [ + 32.208, + 60.074 + ], + [ + 32.039, + 60.038 + ], + [ + 32.05, + 59.692 + ], + [ + 31.736, + 60.31 + ], + [ + 30.983, + 60.778 + ], + [ + 30.657, + 60.183 + ], + [ + 30.608, + 59.712 + ], + [ + 30.488, + 59.494 + ], + [ + 30.524, + 59.114 + ], + [ + 30.198, + 59.384 + ], + [ + 30.318, + 59.784 + ], + [ + 30.55, + 59.801 + ], + [ + 30.61, + 60.074 + ], + [ + 30.27, + 60.219 + ], + [ + 30.658, + 60.289 + ], + [ + 30.875, + 60.834 + ], + [ + 30.717, + 61.034 + ], + [ + 30.233, + 61.288 + ], + [ + 30.016, + 61.181 + ], + [ + 29.045, + 61.432 + ], + [ + 28.44, + 61.107 + ], + [ + 27.957, + 61.071 + ], + [ + 27.351, + 61.394 + ], + [ + 27.714, + 60.708 + ], + [ + 27.521, + 60.888 + ], + [ + 26.429, + 59.619 + ], + [ + 26.078, + 59.422 + ], + [ + 26.164, + 58.859 + ], + [ + 26.285, + 58.823 + ], + [ + 26.333, + 59.004 + ], + [ + 26.516, + 58.768 + ], + [ + 26.271, + 58.735 + ], + [ + 26.465, + 58.478 + ], + [ + 26.017, + 58.751 + ], + [ + 25.569, + 58.445 + ], + [ + 25.654, + 58.317 + ], + [ + 26.055, + 58.371 + ], + [ + 26.08, + 58.227 + ], + [ + 25.873, + 58.207 + ], + [ + 25.788, + 57.972 + ], + [ + 25.872, + 57.553 + ], + [ + 25.63, + 57.917 + ], + [ + 25.269, + 57.844 + ], + [ + 25.134, + 57.719 + ], + [ + 25.11, + 57.354 + ], + [ + 24.746, + 57.065 + ], + [ + 24.868, + 56.813 + ], + [ + 24.699, + 56.884 + ], + [ + 24.711, + 56.432 + ], + [ + 24.59, + 56.831 + ], + [ + 24.08, + 56.758 + ], + [ + 23.971, + 56.703 + ], + [ + 24.092, + 56.522 + ], + [ + 23.887, + 56.505 + ], + [ + 23.839, + 56.25 + ], + [ + 23.729, + 56.522 + ], + [ + 23.765, + 56.832 + ], + [ + 23.475, + 56.721 + ], + [ + 23.45, + 56.54 + ], + [ + 23.318, + 56.632 + ], + [ + 23.572, + 56.976 + ], + [ + 23.873, + 56.994 + ], + [ + 23.535, + 57.21 + ], + [ + 23.634, + 58.152 + ], + [ + 23.839, + 58.608 + ], + [ + 23.401, + 58.499 + ], + [ + 23.185, + 58.677 + ], + [ + 22.023, + 58.822 + ], + [ + 22.24, + 58.643 + ], + [ + 23.21, + 58.605 + ], + [ + 23.292, + 58.515 + ], + [ + 22.747, + 58.534 + ], + [ + 22.675, + 58.315 + ], + [ + 22.53, + 58.569 + ], + [ + 22.239, + 58.57 + ], + [ + 22.264, + 58.423 + ], + [ + 21.998, + 58.243 + ], + [ + 22.131, + 58.623 + ], + [ + 21.902, + 58.97 + ], + [ + 21.441, + 58.497 + ], + [ + 20.615, + 58.208 + ], + [ + 21.196, + 58.279 + ], + [ + 21.816, + 58.697 + ], + [ + 21.319, + 58.243 + ], + [ + 21.247, + 57.99 + ], + [ + 21.052, + 58.062 + ], + [ + 21.077, + 57.737 + ], + [ + 20.908, + 57.955 + ], + [ + 20.811, + 57.519 + ], + [ + 20.725, + 57.791 + ], + [ + 20.872, + 58.045 + ], + [ + 20.349, + 58.244 + ], + [ + 20.181, + 57.881 + ], + [ + 19.804, + 57.717 + ], + [ + 19.949, + 57.536 + ], + [ + 19.756, + 57.501 + ], + [ + 20.048, + 57.356 + ], + [ + 19.648, + 57.193 + ], + [ + 19.563, + 56.955 + ], + [ + 19.672, + 56.795 + ], + [ + 19.38, + 56.795 + ], + [ + 19.113, + 56.577 + ], + [ + 18.897, + 55.996 + ], + [ + 18.896, + 56.65 + ], + [ + 18.509, + 56.792 + ], + [ + 18.217, + 56.647 + ], + [ + 18.122, + 56.359 + ], + [ + 18.037, + 56.487 + ], + [ + 18.195, + 56.83 + ], + [ + 18.461, + 56.902 + ], + [ + 19.091, + 56.758 + ], + [ + 19.636, + 57.391 + ], + [ + 19.877, + 58.154 + ], + [ + 19.381, + 58.17 + ], + [ + 18.193, + 58.969 + ], + [ + 18.204, + 58.732 + ], + [ + 18.641, + 58.226 + ], + [ + 18.267, + 58.46 + ], + [ + 18.013, + 57.826 + ], + [ + 18.134, + 57.645 + ], + [ + 17.541, + 57.121 + ], + [ + 17.843, + 57.682 + ], + [ + 17.478, + 57.717 + ], + [ + 17.575, + 57.937 + ], + [ + 17.431, + 58.154 + ], + [ + 17.444, + 58.389 + ], + [ + 17.154, + 57.954 + ], + [ + 17.165, + 58.08 + ], + [ + 17.672, + 58.771 + ], + [ + 17.66, + 58.966 + ], + [ + 17.78, + 59.076 + ], + [ + 17.856, + 58.86 + ], + [ + 18.037, + 59.096 + ], + [ + 17.709, + 59.294 + ], + [ + 17.951, + 59.44 + ], + [ + 18.315, + 59.33 + ], + [ + 18.594, + 59.532 + ], + [ + 18.423, + 59.638 + ], + [ + 18.327, + 60.328 + ], + [ + 18.097, + 60.418 + ], + [ + 18.086, + 60.69 + ], + [ + 17.904, + 60.853 + ], + [ + 17.565, + 61.106 + ], + [ + 17.04, + 60.96 + ], + [ + 16.991, + 60.47 + ], + [ + 16.911, + 60.417 + ], + [ + 16.994, + 60.908 + ], + [ + 16.79, + 61.252 + ], + [ + 15.432, + 61.396 + ], + [ + 15.093, + 61.287 + ], + [ + 15.117, + 61.142 + ], + [ + 14.972, + 61.288 + ], + [ + 14.656, + 61.252 + ], + [ + 14.439, + 60.925 + ], + [ + 13.156, + 60.999 + ], + [ + 12.671, + 61.179 + ], + [ + 12.236, + 61.071 + ], + [ + 12.345, + 60.544 + ], + [ + 12.076, + 59.999 + ], + [ + 12.526, + 59.694 + ], + [ + 12.986, + 59.692 + ], + [ + 13.07, + 59.421 + ], + [ + 12.827, + 57.862 + ], + [ + 12.32, + 56.34 + ], + [ + 11.787, + 55.292 + ], + [ + 10.466, + 53.497 + ], + [ + 9.959, + 52.987 + ], + [ + 9.255, + 52.77 + ], + [ + 9.231, + 52.555 + ], + [ + 8.637, + 52.114 + ], + [ + 7.547, + 51.753 + ], + [ + 7.643, + 50.991 + ], + [ + 7.535, + 51.045 + ], + [ + 7.584, + 51.372 + ], + [ + 7.45, + 51.715 + ], + [ + 7.037, + 51.752 + ], + [ + 6.918, + 52.114 + ], + [ + 6.626, + 52.115 + ], + [ + 5.874, + 51.897 + ], + [ + 5.755, + 51.534 + ], + [ + 5.052, + 51.427 + ], + [ + 4.76, + 50.953 + ], + [ + 4.397, + 51.207 + ], + [ + 2.921, + 51.063 + ], + [ + 2.533, + 50.773 + ], + [ + 2.023, + 50.776 + ], + [ + 1.673, + 50.43 + ], + [ + 2.641, + 50.213 + ], + [ + 2.398, + 49.85 + ], + [ + 2.363, + 49.286 + ], + [ + 2.896, + 49.506 + ], + [ + 3.089, + 49.287 + ], + [ + 3.404, + 49.505 + ], + [ + 3.585, + 49.417 + ], + [ + 3.718, + 49.034 + ], + [ + 4.784, + 49.179 + ], + [ + 4.808, + 48.925 + ], + [ + 5.1, + 49.107 + ], + [ + 6.407, + 48.564 + ], + [ + 7.039, + 48.782 + ], + [ + 7.475, + 48.274 + ], + [ + 7.814, + 48.381 + ], + [ + 7.934, + 48.2 + ], + [ + 8.516, + 48.164 + ], + [ + 8.902, + 48.383 + ], + [ + 9.266, + 47.983 + ], + [ + 9.581, + 47.875 + ], + [ + 10.646, + 47.803 + ], + [ + 10.915, + 47.44 + ], + [ + 11.738, + 47.549 + ], + [ + 12.488, + 47.367 + ], + [ + 12.778, + 47.622 + ], + [ + 13.166, + 47.658 + ], + [ + 13.36, + 48.164 + ], + [ + 13.41, + 47.838 + ], + [ + 13.627, + 47.802 + ], + [ + 13.7, + 48.055 + ], + [ + 14.355, + 48.201 + ], + [ + 14.729, + 47.604 + ], + [ + 14.923, + 46.986 + ], + [ + 14.777, + 46.624 + ], + [ + 15.239, + 46.335 + ], + [ + 15.069, + 45.357 + ], + [ + 14.719, + 45.337 + ], + [ + 14.487, + 45.138 + ], + [ + 14.608, + 44.485 + ], + [ + 14.27, + 43.654 + ], + [ + 13.965, + 43.524 + ], + [ + 13.895, + 43.309 + ], + [ + 12.272, + 43.162 + ], + [ + 12.357, + 42.891 + ], + [ + 12.054, + 42.62 + ], + [ + 11.737, + 42.692 + ], + [ + 11.058, + 42.438 + ], + [ + 11.011, + 42.258 + ], + [ + 10.55, + 42.26 + ], + [ + 10.622, + 41.824 + ], + [ + 10.394, + 41.877 + ], + [ + 10.552, + 42.041 + ], + [ + 9.51, + 41.787 + ], + [ + 8.588, + 42.076 + ], + [ + 8.528, + 42.313 + ], + [ + 8.771, + 42.494 + ], + [ + 8.722, + 42.674 + ], + [ + 8.297, + 42.908 + ], + [ + 8.213, + 43.363 + ], + [ + 8.02, + 43.617 + ], + [ + 8.067, + 43.797 + ], + [ + 7.438, + 44.342 + ], + [ + 7.401, + 44.831 + ], + [ + 6.991, + 44.83 + ], + [ + 6.832, + 44.451 + ], + [ + 7.1, + 44.303 + ], + [ + 6.953, + 44.051 + ], + [ + 7.123, + 43.981 + ], + [ + 7.027, + 43.871 + ], + [ + 7.05, + 42.963 + ], + [ + 6.784, + 42.6 + ], + [ + 6.856, + 42.349 + ], + [ + 6.724, + 42.041 + ], + [ + 6.445, + 42.059 + ], + [ + 6.625, + 41.75 + ], + [ + 7.232, + 41.64 + ], + [ + 7.22, + 41.153 + ], + [ + 6.869, + 40.88 + ], + [ + 6.24, + 41.278 + ], + [ + 5.682, + 41.208 + ], + [ + 5.731, + 41.025 + ], + [ + 5.367, + 40.807 + ], + [ + 5.149, + 40.846 + ], + [ + 5.075, + 41.099 + ], + [ + 4.908, + 41.063 + ], + [ + 5.161, + 40.21 + ], + [ + 4.774, + 39.885 + ], + [ + 5.294, + 39.938 + ], + [ + 5.538, + 39.648 + ], + [ + 5.631, + 39.867 + ], + [ + 5.946, + 39.938 + ], + [ + 5.718, + 39.957 + ], + [ + 5.851, + 40.118 + ], + [ + 6.092, + 40.12 + ], + [ + 6.553, + 39.793 + ], + [ + 6.541, + 39.233 + ], + [ + 6.396, + 39.16 + ], + [ + 6.397, + 38.473 + ], + [ + 6.227, + 38.218 + ], + [ + 6.492, + 37.927 + ], + [ + 6.481, + 37.765 + ], + [ + 6.748, + 37.765 + ], + [ + 6.965, + 37.44 + ], + [ + 7.594, + 37.22 + ], + [ + 7.559, + 37.602 + ], + [ + 7.316, + 37.999 + ], + [ + 7.292, + 38.58 + ], + [ + 6.979, + 39.086 + ], + [ + 7.135, + 39.397 + ], + [ + 7.45, + 39.361 + ], + [ + 7.473, + 39.757 + ], + [ + 7.909, + 39.539 + ], + [ + 7.824, + 39.378 + ], + [ + 7.91, + 39.212 + ], + [ + 8.478, + 39.63 + ], + [ + 8.273, + 39.94 + ], + [ + 9.266, + 39.722 + ], + [ + 9.606, + 39.504 + ], + [ + 9.679, + 39.287 + ], + [ + 9.921, + 39.468 + ], + [ + 10.962, + 39.395 + ], + [ + 10.925, + 39.666 + ], + [ + 11.145, + 39.885 + ], + [ + 11.107, + 40.048 + ], + [ + 11.666, + 40.192 + ], + [ + 12.514, + 40.009 + ], + [ + 12.877, + 39.721 + ], + [ + 13.288, + 39.721 + ], + [ + 14.016, + 39.213 + ], + [ + 15.104, + 39.287 + ], + [ + 15.384, + 39.486 + ], + [ + 15.359, + 39.775 + ], + [ + 14.863, + 39.577 + ], + [ + 14.802, + 40.136 + ], + [ + 14.705, + 40.21 + ], + [ + 14.983, + 40.228 + ], + [ + 15.65, + 40.682 + ], + [ + 15.276, + 40.916 + ], + [ + 15.685, + 40.845 + ], + [ + 15.952, + 41.206 + ], + [ + 16.219, + 41.244 + ], + [ + 16.437, + 41.205 + ], + [ + 16.656, + 40.916 + ], + [ + 17.044, + 41.677 + ], + [ + 17.019, + 41.35 + ], + [ + 17.769, + 41.46 + ], + [ + 17.841, + 41.606 + ], + [ + 17.916, + 41.46 + ], + [ + 18.545, + 41.461 + ], + [ + 18.605, + 41.333 + ], + [ + 17.09, + 41.278 + ], + [ + 16.947, + 40.881 + ], + [ + 16.751, + 40.773 + ], + [ + 16.17, + 41.135 + ], + [ + 15.759, + 40.518 + ], + [ + 14.983, + 40.082 + ], + [ + 14.959, + 39.828 + ], + [ + 15.443, + 40.012 + ], + [ + 15.904, + 39.758 + ], + [ + 16.085, + 39.556 + ], + [ + 16.049, + 39.393 + ], + [ + 16.607, + 39.541 + ], + [ + 16.728, + 39.357 + ], + [ + 16.922, + 39.503 + ], + [ + 17.067, + 39.322 + ], + [ + 17.734, + 39.233 + ], + [ + 16.487, + 39.212 + ], + [ + 16.243, + 39.105 + ], + [ + 16.062, + 38.797 + ], + [ + 16.438, + 38.597 + ], + [ + 16.51, + 38.489 + ], + [ + 16.05, + 38.67 + ], + [ + 15.928, + 39.105 + ], + [ + 15.493, + 38.707 + ], + [ + 14.923, + 38.545 + ], + [ + 15.056, + 38.306 + ], + [ + 15.662, + 38.09 + ], + [ + 15.856, + 37.909 + ], + [ + 15.179, + 38.235 + ], + [ + 14.862, + 38.197 + ], + [ + 14.67, + 38.596 + ], + [ + 13.3, + 38.398 + ], + [ + 13.652, + 38.055 + ], + [ + 13.845, + 38.126 + ], + [ + 13.688, + 37.964 + ], + [ + 13.773, + 37.836 + ], + [ + 14.136, + 37.837 + ], + [ + 14.269, + 37.746 + ], + [ + 13.869, + 37.8 + ], + [ + 13.845, + 37.546 + ], + [ + 14.79, + 37.258 + ], + [ + 14.946, + 37.131 + ], + [ + 14.621, + 37.002 + ], + [ + 14.643, + 36.895 + ], + [ + 15.251, + 36.823 + ], + [ + 15.347, + 36.639 + ], + [ + 14.96, + 36.75 + ], + [ + 14.789, + 36.642 + ], + [ + 14.692, + 36.822 + ], + [ + 14.498, + 36.677 + ], + [ + 14.282, + 36.749 + ], + [ + 14.197, + 36.985 + ], + [ + 14.366, + 37.093 + ], + [ + 14.258, + 37.256 + ], + [ + 13.532, + 37.4 + ], + [ + 13.469, + 37.022 + ], + [ + 13.772, + 36.494 + ], + [ + 13.095, + 37.219 + ], + [ + 12.803, + 37.22 + ], + [ + 12.814, + 37.021 + ], + [ + 13.022, + 36.93 + ], + [ + 13.167, + 36.639 + ], + [ + 12.562, + 37.113 + ], + [ + 12.33, + 37.494 + ], + [ + 12.405, + 37.674 + ], + [ + 12.332, + 37.892 + ], + [ + 12.175, + 38.019 + ], + [ + 11.024, + 37.999 + ], + [ + 11.277, + 37.545 + ], + [ + 11.641, + 37.293 + ], + [ + 10.283, + 37.944 + ], + [ + 9.908, + 37.892 + ], + [ + 10.054, + 37.782 + ], + [ + 10.064, + 37.439 + ], + [ + 10.441, + 37.203 + ], + [ + 10.199, + 37.058 + ], + [ + 10.442, + 36.587 + ], + [ + 10.404, + 36.423 + ], + [ + 10.939, + 36.098 + ], + [ + 11.495, + 35.335 + ], + [ + 12.174, + 35.082 + ], + [ + 12.705, + 34.647 + ], + [ + 13.215, + 34.574 + ], + [ + 14.403, + 33.741 + ], + [ + 14.428, + 33.596 + ], + [ + 13.07, + 34.43 + ], + [ + 12.632, + 34.359 + ], + [ + 12.368, + 34.758 + ], + [ + 12.173, + 34.756 + ], + [ + 12.185, + 34.593 + ], + [ + 11.957, + 34.392 + ], + [ + 12.113, + 34.847 + ], + [ + 11.665, + 34.937 + ], + [ + 11.471, + 35.228 + ], + [ + 10.889, + 34.936 + ], + [ + 10.551, + 34.972 + ], + [ + 10.187, + 35.626 + ], + [ + 9.993, + 35.517 + ], + [ + 9.775, + 35.626 + ], + [ + 9.836, + 35.5 + ], + [ + 9.702, + 35.59 + ], + [ + 9.765, + 35.428 + ], + [ + 9.654, + 35.518 + ], + [ + 9.678, + 35.375 + ], + [ + 9.34, + 35.663 + ], + [ + 9.048, + 35.552 + ], + [ + 9.023, + 35.772 + ], + [ + 8.711, + 35.626 + ], + [ + 8.661, + 35.371 + ], + [ + 8.661, + 35.737 + ], + [ + 8.468, + 35.698 + ], + [ + 7.618, + 36.604 + ], + [ + 7.061, + 36.497 + ], + [ + 6.892, + 36.785 + ], + [ + 6.724, + 36.714 + ], + [ + 6.506, + 37.004 + ], + [ + 6.141, + 37.076 + ], + [ + 5.389, + 37.584 + ], + [ + 5.247, + 37.548 + ], + [ + 5.22, + 37.366 + ], + [ + 4.834, + 37.474 + ], + [ + 4.52, + 37.113 + ], + [ + 4.252, + 37.186 + ], + [ + 4.035, + 36.929 + ], + [ + 3.355, + 36.713 + ], + [ + 2.775, + 36.967 + ], + [ + 2.714, + 37.13 + ], + [ + 2.811, + 37.456 + ], + [ + 2.507, + 37.8 + ], + [ + 1.66, + 37.69 + ], + [ + 1.2, + 37.909 + ], + [ + 0.667, + 37.8 + ], + [ + 0.581, + 37.456 + ], + [ + 0.727, + 37.092 + ], + [ + 0.363, + 36.768 + ], + [ + 0.425, + 36.497 + ], + [ + 0.799, + 36.442 + ], + [ + 0.231, + 36.423 + ], + [ + 0.169, + 36.151 + ], + [ + 0.715, + 36.243 + ], + [ + 0.97, + 35.969 + ], + [ + 0.97, + 35.716 + ], + [ + 0.824, + 35.573 + ], + [ + 0.922, + 35.498 + ], + [ + 0.667, + 35.445 + ], + [ + 0.558, + 35.174 + ], + [ + 0.605, + 34.594 + ], + [ + 0.279, + 34.54 + ], + [ + 0.256, + 34.286 + ], + [ + -0.0, + 34.121 + ], + [ + 0.388, + 33.471 + ], + [ + 0.266, + 33.218 + ], + [ + 0.533, + 32.82 + ], + [ + 0.34, + 32.781 + ], + [ + 0.702, + 32.276 + ], + [ + 0.715, + 31.966 + ], + [ + 0.836, + 32.002 + ], + [ + 1.005, + 31.75 + ], + [ + 1.162, + 31.841 + ], + [ + 1.103, + 32.076 + ], + [ + 1.247, + 31.64 + ], + [ + 1.817, + 31.55 + ], + [ + 1.272, + 31.496 + ], + [ + 0.981, + 31.676 + ], + [ + 0.677, + 31.295 + ], + [ + 0.716, + 31.133 + ], + [ + 0.534, + 31.043 + ], + [ + 0.677, + 30.97 + ], + [ + 0.484, + 30.534 + ], + [ + 0.582, + 30.319 + ], + [ + 0.508, + 30.172 + ], + [ + 0.8, + 29.956 + ], + [ + 0.752, + 29.667 + ], + [ + 0.97, + 29.485 + ], + [ + 0.872, + 29.447 + ], + [ + 0.995, + 29.266 + ], + [ + 0.872, + 29.047 + ], + [ + 1.125, + 28.96 + ], + [ + 1.296, + 29.103 + ], + [ + 1.259, + 28.905 + ], + [ + 1.356, + 28.796 + ], + [ + 1.258, + 28.543 + ], + [ + 1.732, + 28.236 + ], + [ + 1.926, + 27.871 + ], + [ + 2.266, + 27.836 + ], + [ + 2.264, + 28.017 + ], + [ + 2.483, + 27.943 + ], + [ + 2.581, + 28.162 + ], + [ + 2.724, + 28.017 + ], + [ + 2.592, + 27.888 + ], + [ + 2.689, + 27.528 + ], + [ + 2.581, + 27.292 + ], + [ + 2.943, + 27.399 + ], + [ + 3.185, + 27.257 + ], + [ + 3.175, + 27.453 + ], + [ + 3.284, + 27.507 + ], + [ + 3.514, + 27.384 + ], + [ + 3.574, + 27.146 + ], + [ + 4.131, + 27.329 + ], + [ + 4.81, + 27.037 + ], + [ + 5.755, + 27.329 + ], + [ + 5.973, + 27.942 + ], + [ + 6.383, + 27.835 + ], + [ + 6.02, + 27.654 + ], + [ + 5.875, + 27.22 + ], + [ + 5.306, + 27.057 + ], + [ + 5.571, + 26.766 + ], + [ + 5.559, + 26.603 + ], + [ + 5.404, + 26.586 + ], + [ + 5.525, + 26.404 + ], + [ + 5.452, + 26.15 + ], + [ + 5.706, + 25.734 + ], + [ + 6.058, + 26.041 + ], + [ + 5.851, + 26.313 + ], + [ + 7.329, + 26.132 + ], + [ + 7.838, + 26.386 + ], + [ + 7.231, + 25.952 + ], + [ + 6.869, + 25.914 + ], + [ + 6.964, + 25.552 + ], + [ + 6.565, + 25.642 + ], + [ + 6.663, + 25.39 + ], + [ + 6.493, + 25.281 + ], + [ + 6.638, + 25.171 + ], + [ + 6.589, + 24.954 + ], + [ + 7.306, + 24.972 + ], + [ + 7.147, + 24.558 + ], + [ + 7.376, + 24.391 + ], + [ + 7.485, + 24.446 + ], + [ + 7.39, + 24.664 + ], + [ + 7.547, + 24.753 + ], + [ + 8.079, + 24.538 + ], + [ + 8.237, + 24.7 + ], + [ + 8.163, + 24.918 + ], + [ + 8.272, + 25.082 + ], + [ + 9.606, + 24.862 + ], + [ + 10.164, + 24.32 + ], + [ + 10.332, + 24.32 + ], + [ + 10.405, + 24.608 + ], + [ + 10.6, + 24.285 + ], + [ + 11.253, + 24.391 + ], + [ + 10.526, + 23.992 + ], + [ + 10.417, + 23.649 + ], + [ + 11.638, + 23.595 + ], + [ + 12.174, + 23.088 + ], + [ + 13.046, + 22.653 + ], + [ + 13.553, + 22.798 + ], + [ + 13.495, + 23.069 + ], + [ + 13.602, + 23.16 + ], + [ + 14.014, + 22.906 + ], + [ + 14.136, + 23.16 + ], + [ + 14.45, + 23.232 + ], + [ + 14.512, + 23.432 + ], + [ + 14.366, + 23.577 + ], + [ + 14.389, + 23.76 + ], + [ + 13.859, + 24.084 + ], + [ + 14.101, + 24.158 + ], + [ + 13.93, + 24.337 + ], + [ + 13.99, + 24.465 + ], + [ + 14.328, + 24.611 + ], + [ + 14.534, + 24.483 + ], + [ + 14.401, + 24.318 + ], + [ + 14.863, + 24.211 + ], + [ + 15.128, + 23.885 + ], + [ + 15.88, + 23.885 + ], + [ + 16.46, + 23.669 + ], + [ + 16.584, + 23.666 + ], + [ + 16.425, + 23.793 + ], + [ + 16.63, + 23.922 + ], + [ + 17.357, + 23.776 + ], + [ + 16.644, + 23.504 + ], + [ + 16.896, + 23.016 + ], + [ + 17.744, + 22.255 + ], + [ + 17.892, + 22.362 + ], + [ + 19.223, + 21.892 + ], + [ + 20.045, + 22.002 + ], + [ + 20.192, + 21.891 + ], + [ + 20.349, + 21.982 + ], + [ + 20.335, + 22.29 + ], + [ + 20.482, + 22.035 + ], + [ + 20.578, + 22.255 + ], + [ + 20.748, + 21.999 + ], + [ + 20.784, + 22.272 + ], + [ + 21.136, + 22.436 + ], + [ + 21.086, + 22.581 + ], + [ + 21.354, + 22.799 + ], + [ + 21.076, + 22.307 + ], + [ + 21.56, + 22.308 + ], + [ + 21.367, + 22.165 + ], + [ + 21.51, + 21.619 + ], + [ + 21.936, + 21.528 + ], + [ + 22.033, + 21.132 + ], + [ + 22.616, + 21.167 + ], + [ + 22.93, + 20.48 + ], + [ + 23.061, + 20.532 + ], + [ + 22.917, + 20.823 + ], + [ + 22.991, + 21.078 + ], + [ + 23.208, + 21.21 + ], + [ + 23.413, + 21.011 + ], + [ + 23.404, + 20.628 + ], + [ + 23.741, + 20.557 + ], + [ + 23.656, + 20.72 + ], + [ + 23.815, + 20.774 + ], + [ + 24.021, + 20.611 + ], + [ + 24.092, + 20.937 + ], + [ + 23.874, + 21.842 + ], + [ + 24.359, + 22.313 + ], + [ + 24.067, + 22.242 + ], + [ + 24.093, + 22.748 + ], + [ + 23.971, + 22.929 + ], + [ + 24.516, + 22.84 + ], + [ + 24.6, + 23.003 + ], + [ + 24.48, + 23.147 + ], + [ + 24.577, + 23.51 + ], + [ + 24.467, + 24.108 + ], + [ + 24.832, + 23.492 + ], + [ + 25.122, + 23.601 + ], + [ + 25.388, + 22.84 + ], + [ + 25.775, + 23.094 + ], + [ + 26.114, + 22.947 + ], + [ + 26.345, + 23.184 + ], + [ + 25.91, + 23.437 + ], + [ + 26.005, + 23.836 + ], + [ + 26.26, + 24.218 + ], + [ + 27.23, + 24.687 + ], + [ + 27.351, + 25.194 + ], + [ + 27.631, + 24.889 + ], + [ + 27.073, + 22.967 + ], + [ + 27.325, + 22.911 + ], + [ + 27.388, + 23.365 + ], + [ + 27.569, + 23.49 + ], + [ + 27.532, + 22.567 + ], + [ + 27.314, + 22.388 + ], + [ + 27.495, + 22.005 + ], + [ + 27.775, + 21.843 + ], + [ + 27.737, + 21.462 + ], + [ + 27.884, + 21.463 + ], + [ + 28.052, + 21.172 + ], + [ + 28.186, + 21.625 + ], + [ + 28.32, + 21.679 + ], + [ + 28.479, + 21.3 + ], + [ + 28.392, + 20.992 + ], + [ + 28.731, + 21.244 + ], + [ + 28.974, + 21.172 + ], + [ + 29.335, + 21.68 + ], + [ + 30.161, + 21.354 + ], + [ + 31.228, + 21.498 + ], + [ + 31.36, + 21.588 + ], + [ + 31.323, + 21.753 + ], + [ + 31.809, + 22.15 + ], + [ + 32.245, + 22.114 + ], + [ + 32.413, + 22.331 + ], + [ + 33.091, + 21.899 + ], + [ + 33.333, + 22.04 + ], + [ + 33.479, + 21.898 + ], + [ + 33.177, + 22.531 + ], + [ + 33.588, + 22.93 + ], + [ + 33.238, + 23.239 + ], + [ + 33.672, + 23.056 + ], + [ + 33.661, + 22.567 + ], + [ + 33.988, + 22.368 + ], + [ + 34.302, + 22.44 + ], + [ + 34.472, + 22.985 + ], + [ + 34.861, + 23.094 + ], + [ + 35.417, + 22.876 + ], + [ + 35.672, + 22.497 + ], + [ + 35.235, + 22.17 + ], + [ + 35.249, + 20.629 + ], + [ + 35.467, + 20.739 + ], + [ + 35.755, + 20.558 + ], + [ + 35.781, + 20.375 + ], + [ + 36.242, + 20.557 + ], + [ + 36.58, + 20.52 + ], + [ + 36.557, + 20.338 + ], + [ + 37.028, + 20.358 + ], + [ + 36.218, + 20.305 + ], + [ + 36.205, + 19.705 + ], + [ + 35.78, + 19.18 + ], + [ + 35.2, + 19.289 + ], + [ + 35.356, + 18.944 + ], + [ + 35.09, + 18.762 + ], + [ + 35.236, + 18.654 + ], + [ + 35.21, + 18.292 + ], + [ + 35.38, + 18.146 + ], + [ + 35.187, + 17.895 + ], + [ + 35.611, + 17.839 + ], + [ + 35.549, + 17.676 + ], + [ + 35.709, + 17.513 + ], + [ + 35.998, + 17.767 + ], + [ + 36.41, + 17.55 + ], + [ + 36.616, + 17.169 + ], + [ + 36.555, + 16.968 + ], + [ + 36.314, + 17.007 + ], + [ + 36.276, + 16.769 + ], + [ + 36.495, + 16.698 + ], + [ + 36.507, + 16.352 + ], + [ + 37.113, + 16.606 + ], + [ + 36.906, + 16.153 + ], + [ + 37.281, + 15.845 + ], + [ + 37.463, + 16.045 + ], + [ + 37.392, + 16.189 + ], + [ + 37.599, + 16.352 + ], + [ + 37.623, + 16.061 + ], + [ + 38.059, + 16.28 + ], + [ + 37.95, + 16.082 + ], + [ + 38.021, + 15.9 + ], + [ + 38.3, + 15.809 + ], + [ + 38.529, + 16.336 + ], + [ + 38.93, + 16.751 + ], + [ + 39.778, + 16.57 + ], + [ + 39.837, + 16.696 + ], + [ + 39.584, + 16.897 + ], + [ + 39.438, + 17.294 + ], + [ + 39.33, + 17.279 + ], + [ + 39.367, + 17.548 + ], + [ + 40.77, + 17.367 + ], + [ + 40.903, + 17.24 + ], + [ + 40.868, + 16.751 + ], + [ + 41.014, + 16.824 + ], + [ + 41.691, + 16.498 + ], + [ + 41.959, + 16.571 + ], + [ + 42.83, + 15.735 + ], + [ + 43.485, + 15.882 + ], + [ + 43.702, + 16.1 + ], + [ + 43.968, + 15.557 + ], + [ + 44.185, + 15.519 + ], + [ + 44.186, + 15.772 + ], + [ + 44.478, + 15.917 + ], + [ + 44.732, + 15.574 + ], + [ + 44.743, + 15.301 + ], + [ + 45.312, + 14.668 + ], + [ + 45.253, + 14.504 + ], + [ + 45.641, + 14.359 + ], + [ + 45.845, + 14.56 + ], + [ + 46.162, + 15.357 + ], + [ + 45.799, + 15.864 + ], + [ + 46.307, + 15.828 + ], + [ + 46.052, + 17.149 + ], + [ + 46.377, + 16.771 + ], + [ + 46.404, + 16.334 + ], + [ + 46.621, + 15.789 + ], + [ + 46.877, + 15.519 + ], + [ + 47.046, + 15.52 + ], + [ + 47.094, + 15.774 + ], + [ + 47.286, + 15.123 + ], + [ + 47.772, + 15.121 + ], + [ + 48.305, + 14.868 + ], + [ + 48.45, + 14.577 + ], + [ + 49.031, + 14.503 + ], + [ + 49.152, + 14.287 + ], + [ + 49.444, + 14.324 + ], + [ + 50.025, + 13.779 + ], + [ + 50.108, + 13.836 + ], + [ + 49.953, + 14.107 + ], + [ + 49.333, + 14.522 + ], + [ + 49.759, + 14.433 + ], + [ + 49.963, + 14.85 + ], + [ + 49.88, + 14.976 + ], + [ + 49.686, + 14.724 + ], + [ + 49.454, + 14.813 + ], + [ + 49.626, + 14.957 + ], + [ + 49.745, + 15.429 + ], + [ + 49.358, + 16.008 + ], + [ + 49.638, + 15.954 + ], + [ + 49.891, + 16.154 + ], + [ + 49.746, + 16.262 + ], + [ + 49.648, + 16.88 + ], + [ + 49.287, + 17.24 + ], + [ + 49.455, + 17.24 + ], + [ + 49.212, + 17.893 + ], + [ + 49.333, + 18.11 + ], + [ + 48.558, + 18.654 + ], + [ + 48.656, + 18.727 + ], + [ + 48.584, + 19.233 + ], + [ + 48.328, + 19.58 + ], + [ + 48.692, + 19.36 + ], + [ + 48.815, + 18.962 + ], + [ + 49.334, + 18.763 + ], + [ + 49.165, + 18.291 + ], + [ + 49.454, + 18.181 + ], + [ + 49.626, + 17.096 + ], + [ + 50.048, + 16.533 + ], + [ + 50.631, + 16.425 + ], + [ + 50.546, + 16.625 + ], + [ + 50.704, + 16.715 + ], + [ + 51.14, + 16.498 + ], + [ + 51.815, + 16.461 + ], + [ + 51.952, + 16.625 + ], + [ + 51.708, + 16.915 + ], + [ + 52.034, + 17.186 + ], + [ + 52.047, + 17.385 + ], + [ + 51.673, + 17.512 + ], + [ + 51.454, + 17.839 + ], + [ + 51.042, + 17.874 + ], + [ + 50.909, + 18.076 + ], + [ + 51.914, + 18.203 + ], + [ + 51.394, + 18.398 + ], + [ + 51.841, + 18.853 + ], + [ + 52.012, + 18.781 + ], + [ + 52.254, + 18.962 + ], + [ + 53.246, + 19.035 + ], + [ + 53.658, + 18.6 + ], + [ + 53.573, + 18.834 + ], + [ + 53.826, + 19.214 + ], + [ + 54.253, + 19.341 + ], + [ + 53.913, + 19.815 + ], + [ + 53.924, + 20.012 + ], + [ + 54.132, + 20.175 + ], + [ + 53.72, + 20.613 + ], + [ + 53.767, + 20.829 + ], + [ + 54.217, + 20.847 + ], + [ + 54.179, + 21.045 + ], + [ + 54.507, + 21.535 + ], + [ + 54.99, + 21.789 + ], + [ + 55.33, + 21.752 + ], + [ + 55.537, + 22.097 + ], + [ + 55.546, + 22.769 + ], + [ + 56.08, + 22.947 + ], + [ + 56.274, + 22.839 + ], + [ + 56.784, + 23.275 + ], + [ + 56.856, + 23.601 + ], + [ + 57.184, + 23.728 + ], + [ + 57.256, + 24.125 + ], + [ + 57.401, + 24.235 + ], + [ + 57.302, + 24.488 + ], + [ + 57.473, + 24.635 + ], + [ + 57.402, + 25.141 + ], + [ + 57.619, + 25.465 + ], + [ + 57.472, + 25.902 + ], + [ + 57.642, + 26.047 + ], + [ + 57.341, + 26.138 + ], + [ + 57.414, + 26.356 + ], + [ + 58.041, + 26.537 + ], + [ + 58.189, + 26.754 + ], + [ + 58.526, + 26.717 + ], + [ + 58.734, + 26.95 + ], + [ + 58.77, + 27.296 + ], + [ + 59.109, + 27.551 + ], + [ + 60.536, + 28.021 + ], + [ + 60.514, + 28.202 + ], + [ + 60.235, + 28.365 + ], + [ + 60.429, + 28.837 + ], + [ + 60.139, + 29.161 + ], + [ + 60.49, + 29.145 + ], + [ + 60.526, + 29.598 + ], + [ + 60.805, + 29.688 + ], + [ + 61.361, + 30.632 + ], + [ + 61.617, + 29.888 + ], + [ + 61.448, + 29.127 + ], + [ + 61.506, + 28.963 + ], + [ + 61.821, + 28.855 + ], + [ + 62.234, + 29.361 + ], + [ + 62.887, + 29.326 + ], + [ + 63.034, + 29.471 + ], + [ + 62.85, + 29.162 + ], + [ + 62.899, + 28.837 + ], + [ + 63.735, + 28.166 + ], + [ + 64.654, + 27.043 + ], + [ + 64.802, + 27.079 + ], + [ + 64.716, + 26.879 + ], + [ + 65.249, + 26.373 + ], + [ + 65.19, + 26.136 + ], + [ + 65.771, + 26.21 + ], + [ + 66.256, + 26.029 + ], + [ + 67.514, + 25.123 + ], + [ + 67.478, + 24.777 + ], + [ + 67.658, + 24.833 + ], + [ + 67.72, + 24.67 + ], + [ + 67.297, + 24.508 + ], + [ + 67.091, + 24.234 + ], + [ + 67.127, + 24.107 + ], + [ + 67.443, + 24.144 + ], + [ + 67.66, + 23.927 + ], + [ + 68.168, + 24.0 + ], + [ + 68.605, + 23.782 + ], + [ + 69.125, + 24.016 + ], + [ + 69.028, + 24.163 + ], + [ + 69.16, + 24.616 + ], + [ + 69.345, + 24.45 + ], + [ + 69.113, + 24.289 + ], + [ + 69.791, + 24.181 + ], + [ + 70.082, + 23.746 + ], + [ + 70.35, + 23.781 + ], + [ + 70.567, + 23.528 + ], + [ + 70.81, + 23.672 + ], + [ + 71.366, + 23.094 + ], + [ + 71.754, + 22.912 + ], + [ + 71.813, + 22.458 + ], + [ + 72.046, + 22.188 + ], + [ + 72.299, + 22.531 + ], + [ + 72.153, + 22.857 + ], + [ + 72.215, + 22.984 + ], + [ + 73.002, + 23.185 + ], + [ + 72.324, + 24.198 + ], + [ + 72.372, + 24.341 + ], + [ + 72.237, + 24.617 + ], + [ + 71.536, + 25.232 + ], + [ + 71.973, + 25.268 + ], + [ + 72.19, + 25.592 + ], + [ + 72.625, + 24.941 + ], + [ + 72.76, + 24.959 + ], + [ + 72.771, + 25.158 + ], + [ + 72.866, + 24.833 + ], + [ + 73.377, + 24.433 + ], + [ + 73.352, + 24.288 + ], + [ + 74.151, + 24.142 + ], + [ + 73.921, + 24.597 + ], + [ + 74.335, + 25.031 + ], + [ + 74.164, + 25.395 + ], + [ + 74.637, + 25.593 + ], + [ + 74.794, + 25.937 + ], + [ + 74.768, + 26.299 + ], + [ + 75.084, + 26.409 + ], + [ + 75.182, + 26.662 + ], + [ + 75.121, + 27.26 + ], + [ + 75.691, + 26.371 + ], + [ + 75.654, + 25.63 + ], + [ + 75.98, + 26.01 + ], + [ + 75.931, + 26.408 + ], + [ + 76.03, + 26.517 + ], + [ + 75.883, + 26.589 + ], + [ + 75.883, + 26.808 + ], + [ + 76.019, + 27.08 + ], + [ + 76.477, + 27.006 + ], + [ + 76.502, + 26.79 + ], + [ + 76.732, + 26.663 + ], + [ + 76.223, + 26.228 + ], + [ + 76.527, + 25.739 + ], + [ + 76.745, + 25.739 + ], + [ + 76.889, + 25.304 + ], + [ + 77.035, + 25.268 + ], + [ + 77.178, + 25.63 + ], + [ + 77.664, + 25.921 + ], + [ + 77.471, + 25.557 + ], + [ + 77.241, + 25.466 + ], + [ + 77.156, + 25.05 + ], + [ + 76.876, + 24.924 + ], + [ + 76.889, + 24.653 + ], + [ + 77.106, + 24.759 + ], + [ + 77.398, + 24.434 + ], + [ + 77.664, + 24.579 + ], + [ + 77.954, + 24.181 + ], + [ + 78.027, + 24.434 + ], + [ + 78.221, + 24.578 + ], + [ + 78.197, + 24.399 + ], + [ + 78.393, + 24.433 + ], + [ + 78.488, + 24.651 + ], + [ + 79.02, + 24.327 + ], + [ + 79.529, + 24.363 + ], + [ + 79.677, + 24.543 + ], + [ + 79.891, + 24.397 + ], + [ + 79.639, + 24.995 + ], + [ + 80.39, + 25.032 + ], + [ + 80.413, + 25.357 + ], + [ + 80.219, + 25.611 + ], + [ + 80.39, + 25.757 + ], + [ + 80.316, + 25.903 + ], + [ + 80.595, + 25.846 + ], + [ + 80.511, + 26.082 + ], + [ + 80.801, + 26.556 + ], + [ + 81.104, + 26.644 + ], + [ + 81.177, + 26.86 + ], + [ + 81.298, + 26.79 + ], + [ + 81.408, + 27.062 + ], + [ + 80.873, + 27.35 + ], + [ + 81.031, + 27.515 + ], + [ + 81.152, + 27.441 + ], + [ + 81.407, + 27.894 + ], + [ + 81.43, + 28.185 + ], + [ + 81.624, + 28.294 + ], + [ + 81.614, + 28.493 + ], + [ + 81.977, + 28.493 + ], + [ + 82.049, + 28.892 + ], + [ + 82.399, + 28.295 + ], + [ + 82.266, + 27.984 + ], + [ + 81.938, + 28.003 + ], + [ + 82.037, + 27.569 + ], + [ + 81.623, + 26.843 + ], + [ + 81.88, + 26.717 + ], + [ + 82.34, + 27.153 + ], + [ + 82.569, + 27.062 + ], + [ + 82.304, + 26.842 + ], + [ + 82.339, + 26.5 + ], + [ + 82.026, + 26.57 + ], + [ + 81.612, + 26.354 + ], + [ + 81.275, + 26.499 + ], + [ + 81.142, + 26.301 + ], + [ + 81.291, + 26.047 + ], + [ + 81.289, + 25.983 + ], + [ + 80.885, + 26.174 + ], + [ + 80.946, + 25.792 + ], + [ + 81.19, + 25.505 + ], + [ + 80.862, + 25.523 + ], + [ + 80.754, + 25.357 + ], + [ + 80.851, + 24.961 + ], + [ + 80.523, + 24.579 + ], + [ + 80.293, + 24.596 + ], + [ + 80.631, + 24.341 + ], + [ + 80.594, + 24.146 + ], + [ + 80.389, + 24.128 + ], + [ + 80.364, + 23.909 + ], + [ + 81.008, + 23.711 + ], + [ + 81.636, + 23.13 + ], + [ + 81.745, + 22.786 + ], + [ + 81.529, + 22.642 + ], + [ + 81.539, + 22.44 + ], + [ + 81.636, + 22.549 + ], + [ + 82.316, + 22.331 + ], + [ + 82.34, + 22.55 + ], + [ + 83.019, + 22.44 + ], + [ + 82.751, + 22.188 + ], + [ + 82.399, + 22.206 + ], + [ + 83.043, + 22.006 + ], + [ + 83.211, + 21.643 + ], + [ + 83.333, + 22.041 + ], + [ + 83.575, + 22.115 + ], + [ + 83.721, + 21.933 + ], + [ + 84.084, + 22.186 + ], + [ + 84.568, + 21.789 + ], + [ + 84.907, + 21.933 + ], + [ + 85.294, + 21.753 + ], + [ + 85.876, + 21.244 + ], + [ + 85.815, + 21.661 + ], + [ + 85.67, + 21.807 + ], + [ + 85.816, + 21.913 + ], + [ + 85.741, + 22.168 + ], + [ + 86.058, + 22.641 + ], + [ + 85.343, + 23.201 + ], + [ + 85.306, + 23.618 + ], + [ + 85.041, + 24.126 + ], + [ + 85.901, + 25.413 + ], + [ + 87.96, + 25.956 + ], + [ + 88.032, + 25.558 + ], + [ + 88.178, + 25.811 + ], + [ + 89.729, + 25.774 + ], + [ + 91.932, + 25.34 + ], + [ + 92.344, + 25.159 + ], + [ + 92.78, + 24.759 + ], + [ + 92.78, + 24.616 + ], + [ + 93.046, + 24.616 + ], + [ + 93.168, + 24.396 + ], + [ + 93.459, + 24.581 + ], + [ + 95.275, + 24.796 + ], + [ + 95.517, + 25.195 + ], + [ + 95.567, + 24.724 + ], + [ + 95.737, + 24.723 + ], + [ + 95.761, + 24.87 + ], + [ + 96.026, + 24.796 + ], + [ + 96.149, + 25.049 + ], + [ + 96.292, + 24.796 + ], + [ + 96.728, + 25.013 + ], + [ + 96.838, + 24.924 + ], + [ + 96.608, + 24.651 + ], + [ + 96.85, + 24.578 + ], + [ + 97.163, + 24.796 + ], + [ + 97.238, + 24.469 + ], + [ + 97.892, + 24.217 + ], + [ + 99.539, + 24.216 + ], + [ + 100.0, + 24.651 + ], + [ + 99.733, + 24.037 + ], + [ + 99.539, + 24.07 + ], + [ + 99.224, + 23.817 + ], + [ + 98.957, + 23.891 + ], + [ + 98.39, + 23.547 + ], + [ + 98.569, + 23.021 + ], + [ + 99.078, + 22.802 + ], + [ + 97.868, + 23.2 + ], + [ + 97.625, + 23.672 + ], + [ + 97.381, + 23.71 + ], + [ + 97.323, + 23.113 + ], + [ + 97.213, + 22.984 + ], + [ + 95.711, + 22.333 + ], + [ + 94.984, + 20.411 + ], + [ + 94.307, + 20.338 + ], + [ + 93.81, + 19.849 + ], + [ + 93.737, + 17.602 + ], + [ + 93.811, + 17.276 + ], + [ + 93.664, + 17.06 + ], + [ + 93.64, + 16.48 + ], + [ + 93.411, + 16.063 + ], + [ + 93.073, + 15.881 + ], + [ + 92.756, + 15.881 + ], + [ + 92.805, + 16.062 + ], + [ + 92.501, + 15.9 + ], + [ + 93.421, + 15.174 + ], + [ + 93.714, + 14.196 + ], + [ + 93.811, + 13.148 + ] + ], + "landRings": [ + [ + [ + -9.992, + 32.642 + ], + [ + -7.992, + 31.175 + ], + [ + -6.915, + 32.025 + ], + [ + -9.009, + 33.239 + ], + [ + -9.361, + 33.15 + ], + [ + -8.622, + 32.515 + ], + [ + -9.992, + 32.642 + ] + ], + [ + [ + 17.528, + 58.189 + ], + [ + 17.868, + 58.007 + ], + [ + 17.951, + 58.751 + ], + [ + 17.528, + 58.189 + ] + ], + [ + [ + 22.494, + 19.392 + ], + [ + 23.354, + 20.12 + ], + [ + 21.876, + 19.773 + ], + [ + 22.494, + 19.392 + ] + ], + [ + [ + 35.225, + 17.658 + ], + [ + 35.756, + 17.078 + ], + [ + 35.913, + 17.35 + ], + [ + 35.225, + 17.658 + ] + ], + [ + [ + 37.344, + 67.612 + ], + [ + 39.803, + 67.776 + ], + [ + 40.177, + 68.481 + ], + [ + 38.18, + 68.391 + ], + [ + 37.344, + 67.612 + ] + ], + [ + [ + 44.646, + 80.239 + ], + [ + 45.155, + 78.826 + ], + [ + 47.674, + 79.806 + ], + [ + 47.989, + 81.146 + ], + [ + 50.595, + 82.252 + ], + [ + 49.588, + 83.537 + ], + [ + 47.384, + 82.487 + ], + [ + 45.785, + 82.883 + ], + [ + 45.143, + 82.215 + ], + [ + 45.434, + 81.417 + ], + [ + 44.646, + 80.239 + ] + ], + [ + [ + 52.386, + 78.627 + ], + [ + 53.029, + 78.537 + ], + [ + 53.961, + 78.59 + ], + [ + 53.636, + 79.369 + ], + [ + 52.386, + 78.627 + ] + ], + [ + [ + 52.279, + 15.882 + ], + [ + 51.768, + 15.194 + ], + [ + 52.41, + 15.321 + ], + [ + 52.279, + 15.882 + ] + ], + [ + [ + 52.569, + 14.65 + ], + [ + 52.302, + 15.195 + ], + [ + 51.805, + 15.029 + ], + [ + 51.891, + 14.831 + ], + [ + 52.569, + 14.65 + ] + ], + [ + [ + 55.499, + 80.674 + ], + [ + 56.225, + 80.603 + ], + [ + 56.285, + 80.802 + ], + [ + 55.62, + 81.365 + ], + [ + 55.499, + 80.674 + ] + ], + [ + [ + 56.298, + 71.363 + ], + [ + 56.442, + 69.478 + ], + [ + 57.329, + 70.038 + ], + [ + 56.614, + 70.166 + ], + [ + 56.298, + 71.363 + ] + ], + [ + [ + 57.801, + 70.529 + ], + [ + 58.165, + 69.369 + ], + [ + 58.783, + 69.786 + ], + [ + 57.801, + 70.529 + ] + ], + [ + [ + 76.634, + 86.853 + ], + [ + 75.982, + 85.583 + ], + [ + 76.331, + 84.044 + ], + [ + 79.458, + 82.994 + ], + [ + 81.393, + 83.503 + ], + [ + 80.994, + 83.265 + ], + [ + 82.316, + 83.466 + ], + [ + 82.582, + 82.974 + ], + [ + 80.789, + 81.942 + ], + [ + 76.019, + 82.705 + ], + [ + 75.484, + 84.08 + ], + [ + 72.675, + 85.566 + ], + [ + 70.008, + 83.501 + ], + [ + 68.944, + 83.755 + ], + [ + 69.137, + 84.515 + ], + [ + 68.215, + 84.371 + ], + [ + 65.396, + 83.011 + ], + [ + 66.133, + 82.558 + ], + [ + 66.982, + 83.357 + ], + [ + 67.601, + 82.866 + ], + [ + 66.775, + 82.578 + ], + [ + 67.466, + 82.268 + ], + [ + 67.321, + 81.98 + ], + [ + 66.328, + 82.56 + ], + [ + 66.559, + 80.837 + ], + [ + 65.079, + 79.351 + ], + [ + 67.733, + 77.341 + ], + [ + 68.739, + 77.721 + ], + [ + 68.036, + 77.142 + ], + [ + 68.423, + 76.705 + ], + [ + 68.072, + 76.218 + ], + [ + 66.921, + 76.126 + ], + [ + 66.836, + 74.115 + ], + [ + 67.66, + 74.441 + ], + [ + 69.452, + 74.26 + ], + [ + 70.106, + 73.789 + ], + [ + 68.411, + 73.969 + ], + [ + 66.738, + 73.248 + ], + [ + 66.92, + 72.901 + ], + [ + 66.837, + 72.773 + ], + [ + 62.875, + 73.772 + ], + [ + 63.493, + 73.536 + ], + [ + 63.458, + 72.937 + ], + [ + 64.147, + 72.703 + ], + [ + 64.427, + 72.286 + ], + [ + 64.571, + 71.85 + ], + [ + 64.536, + 71.723 + ], + [ + 63.76, + 72.703 + ], + [ + 63.349, + 72.087 + ], + [ + 63.324, + 72.594 + ], + [ + 62.596, + 72.521 + ], + [ + 63.24, + 72.792 + ], + [ + 63.105, + 73.247 + ], + [ + 61.482, + 72.774 + ], + [ + 61.931, + 73.191 + ], + [ + 61.434, + 74.189 + ], + [ + 59.906, + 73.718 + ], + [ + 58.188, + 74.625 + ], + [ + 56.712, + 74.116 + ], + [ + 56.227, + 72.812 + ], + [ + 54.712, + 71.959 + ], + [ + 54.894, + 71.182 + ], + [ + 55.79, + 71.108 + ], + [ + 56.517, + 72.302 + ], + [ + 57.293, + 71.76 + ], + [ + 57.207, + 71.995 + ], + [ + 57.28, + 72.284 + ], + [ + 57.341, + 72.342 + ], + [ + 57.364, + 71.47 + ], + [ + 58.091, + 72.269 + ], + [ + 58.333, + 71.688 + ], + [ + 60.005, + 72.086 + ], + [ + 60.38, + 70.221 + ], + [ + 61.252, + 70.038 + ], + [ + 61.349, + 69.134 + ], + [ + 60.803, + 67.92 + ], + [ + 61.131, + 68.88 + ], + [ + 60.622, + 69.096 + ], + [ + 60.661, + 69.984 + ], + [ + 58.636, + 68.735 + ], + [ + 59.969, + 68.987 + ], + [ + 59.254, + 67.593 + ], + [ + 58.866, + 68.318 + ], + [ + 58.116, + 67.521 + ], + [ + 58.553, + 68.679 + ], + [ + 56.324, + 68.644 + ], + [ + 56.227, + 69.768 + ], + [ + 55.476, + 69.44 + ], + [ + 55.355, + 70.385 + ], + [ + 54.844, + 69.946 + ], + [ + 54.554, + 70.384 + ], + [ + 54.579, + 69.514 + ], + [ + 54.361, + 69.876 + ], + [ + 54.226, + 69.312 + ], + [ + 54.071, + 70.203 + ], + [ + 53.695, + 69.206 + ], + [ + 54.106, + 68.445 + ], + [ + 53.475, + 68.408 + ], + [ + 52.93, + 66.905 + ], + [ + 53.598, + 68.99 + ], + [ + 53.185, + 69.315 + ], + [ + 53.575, + 69.64 + ], + [ + 53.307, + 70.074 + ], + [ + 54.349, + 71.345 + ], + [ + 54.094, + 71.616 + ], + [ + 52.956, + 71.433 + ], + [ + 52.485, + 70.437 + ], + [ + 52.738, + 70.095 + ], + [ + 52.289, + 70.039 + ], + [ + 52.568, + 70.999 + ], + [ + 52.01, + 71.072 + ], + [ + 51.236, + 67.957 + ], + [ + 50.884, + 68.3 + ], + [ + 51.393, + 68.769 + ], + [ + 51.647, + 71.001 + ], + [ + 51.089, + 70.312 + ], + [ + 49.418, + 71.181 + ], + [ + 49.091, + 70.689 + ], + [ + 49.528, + 70.401 + ], + [ + 48.523, + 69.659 + ], + [ + 48.46, + 70.691 + ], + [ + 48.873, + 70.618 + ], + [ + 48.486, + 72.974 + ], + [ + 49.781, + 75.31 + ], + [ + 48.075, + 74.677 + ], + [ + 47.542, + 72.757 + ], + [ + 48.293, + 71.923 + ], + [ + 47.856, + 69.134 + ], + [ + 46.416, + 68.608 + ], + [ + 46.161, + 67.863 + ], + [ + 46.246, + 66.795 + ], + [ + 46.839, + 66.922 + ], + [ + 46.184, + 66.633 + ], + [ + 46.925, + 65.707 + ], + [ + 47.602, + 66.108 + ], + [ + 48.109, + 65.347 + ], + [ + 48.872, + 65.435 + ], + [ + 48.643, + 65.021 + ], + [ + 47.347, + 65.364 + ], + [ + 47.965, + 64.475 + ], + [ + 48.572, + 64.983 + ], + [ + 48.595, + 64.113 + ], + [ + 49.238, + 64.42 + ], + [ + 48.573, + 64.076 + ], + [ + 47.749, + 64.403 + ], + [ + 47.555, + 64.802 + ], + [ + 47.579, + 64.332 + ], + [ + 48.317, + 63.878 + ], + [ + 47.88, + 63.769 + ], + [ + 48.389, + 63.189 + ], + [ + 47.965, + 62.955 + ], + [ + 47.698, + 63.931 + ], + [ + 46.67, + 63.188 + ], + [ + 47.491, + 65.002 + ], + [ + 46.536, + 64.767 + ], + [ + 46.706, + 65.67 + ], + [ + 46.016, + 65.474 + ], + [ + 46.45, + 65.982 + ], + [ + 45.919, + 66.669 + ], + [ + 46.003, + 67.737 + ], + [ + 44.211, + 66.108 + ], + [ + 41.727, + 65.691 + ], + [ + 41.983, + 65.201 + ], + [ + 44.067, + 65.855 + ], + [ + 43.436, + 64.767 + ], + [ + 41.678, + 64.929 + ], + [ + 42.261, + 64.53 + ], + [ + 42.2, + 63.679 + ], + [ + 42.951, + 63.715 + ], + [ + 44.004, + 62.138 + ], + [ + 44.067, + 61.721 + ], + [ + 42.538, + 63.351 + ], + [ + 42.007, + 62.845 + ], + [ + 41.739, + 64.078 + ], + [ + 40.625, + 63.751 + ], + [ + 41.559, + 64.459 + ], + [ + 41.085, + 65.164 + ], + [ + 39.099, + 65.454 + ], + [ + 36.881, + 62.43 + ], + [ + 36.968, + 61.069 + ], + [ + 36.604, + 62.628 + ], + [ + 33.431, + 61.613 + ], + [ + 32.534, + 61.939 + ], + [ + 31.264, + 60.945 + ], + [ + 32.208, + 60.074 + ], + [ + 32.05, + 59.692 + ], + [ + 30.983, + 60.778 + ], + [ + 30.524, + 59.114 + ], + [ + 30.27, + 60.219 + ], + [ + 30.717, + 61.034 + ], + [ + 27.351, + 61.394 + ], + [ + 27.714, + 60.708 + ], + [ + 26.078, + 59.422 + ], + [ + 26.465, + 58.478 + ], + [ + 25.569, + 58.445 + ], + [ + 26.055, + 58.371 + ], + [ + 25.872, + 57.553 + ], + [ + 25.269, + 57.844 + ], + [ + 24.711, + 56.432 + ], + [ + 24.08, + 56.758 + ], + [ + 23.839, + 56.25 + ], + [ + 23.765, + 56.832 + ], + [ + 23.45, + 56.54 + ], + [ + 23.318, + 56.632 + ], + [ + 23.873, + 56.994 + ], + [ + 23.535, + 57.21 + ], + [ + 23.839, + 58.608 + ], + [ + 22.023, + 58.822 + ], + [ + 23.292, + 58.515 + ], + [ + 21.998, + 58.243 + ], + [ + 21.902, + 58.97 + ], + [ + 20.615, + 58.208 + ], + [ + 21.816, + 58.697 + ], + [ + 20.811, + 57.519 + ], + [ + 20.349, + 58.244 + ], + [ + 18.897, + 55.996 + ], + [ + 18.896, + 56.65 + ], + [ + 18.037, + 56.487 + ], + [ + 19.091, + 56.758 + ], + [ + 19.877, + 58.154 + ], + [ + 18.193, + 58.969 + ], + [ + 18.641, + 58.226 + ], + [ + 18.267, + 58.46 + ], + [ + 18.134, + 57.645 + ], + [ + 17.541, + 57.121 + ], + [ + 17.843, + 57.682 + ], + [ + 17.444, + 58.389 + ], + [ + 17.165, + 58.08 + ], + [ + 18.037, + 59.096 + ], + [ + 17.709, + 59.294 + ], + [ + 18.594, + 59.532 + ], + [ + 17.904, + 60.853 + ], + [ + 17.04, + 60.96 + ], + [ + 16.991, + 60.47 + ], + [ + 16.911, + 60.417 + ], + [ + 16.79, + 61.252 + ], + [ + 12.236, + 61.071 + ], + [ + 12.076, + 59.999 + ], + [ + 13.07, + 59.421 + ], + [ + 12.827, + 57.862 + ], + [ + 10.466, + 53.497 + ], + [ + 7.547, + 51.753 + ], + [ + 7.643, + 50.991 + ], + [ + 6.626, + 52.115 + ], + [ + 4.76, + 50.953 + ], + [ + 1.673, + 50.43 + ], + [ + 2.641, + 50.213 + ], + [ + 2.363, + 49.286 + ], + [ + 8.902, + 48.383 + ], + [ + 10.915, + 47.44 + ], + [ + 14.355, + 48.201 + ], + [ + 15.239, + 46.335 + ], + [ + 15.069, + 45.357 + ], + [ + 14.487, + 45.138 + ], + [ + 14.608, + 44.485 + ], + [ + 13.895, + 43.309 + ], + [ + 12.272, + 43.162 + ], + [ + 10.622, + 41.824 + ], + [ + 8.588, + 42.076 + ], + [ + 8.722, + 42.674 + ], + [ + 6.991, + 44.83 + ], + [ + 7.05, + 42.963 + ], + [ + 6.445, + 42.059 + ], + [ + 7.22, + 41.153 + ], + [ + 4.908, + 41.063 + ], + [ + 5.161, + 40.21 + ], + [ + 4.774, + 39.885 + ], + [ + 6.553, + 39.793 + ], + [ + 6.227, + 38.218 + ], + [ + 7.594, + 37.22 + ], + [ + 6.979, + 39.086 + ], + [ + 7.473, + 39.757 + ], + [ + 7.91, + 39.212 + ], + [ + 8.273, + 39.94 + ], + [ + 10.962, + 39.395 + ], + [ + 11.666, + 40.192 + ], + [ + 15.104, + 39.287 + ], + [ + 15.359, + 39.775 + ], + [ + 14.863, + 39.577 + ], + [ + 14.705, + 40.21 + ], + [ + 15.65, + 40.682 + ], + [ + 15.276, + 40.916 + ], + [ + 16.219, + 41.244 + ], + [ + 16.656, + 40.916 + ], + [ + 17.044, + 41.677 + ], + [ + 18.605, + 41.333 + ], + [ + 16.751, + 40.773 + ], + [ + 16.17, + 41.135 + ], + [ + 14.983, + 40.082 + ], + [ + 17.734, + 39.233 + ], + [ + 16.062, + 38.797 + ], + [ + 16.438, + 38.597 + ], + [ + 16.51, + 38.489 + ], + [ + 16.05, + 38.67 + ], + [ + 15.928, + 39.105 + ], + [ + 14.923, + 38.545 + ], + [ + 15.056, + 38.306 + ], + [ + 15.662, + 38.09 + ], + [ + 15.856, + 37.909 + ], + [ + 14.862, + 38.197 + ], + [ + 14.67, + 38.596 + ], + [ + 13.3, + 38.398 + ], + [ + 15.347, + 36.639 + ], + [ + 13.532, + 37.4 + ], + [ + 13.772, + 36.494 + ], + [ + 12.803, + 37.22 + ], + [ + 13.167, + 36.639 + ], + [ + 12.175, + 38.019 + ], + [ + 11.024, + 37.999 + ], + [ + 11.641, + 37.293 + ], + [ + 9.908, + 37.892 + ], + [ + 10.404, + 36.423 + ], + [ + 11.495, + 35.335 + ], + [ + 13.215, + 34.574 + ], + [ + 14.428, + 33.596 + ], + [ + 12.368, + 34.758 + ], + [ + 11.957, + 34.392 + ], + [ + 12.113, + 34.847 + ], + [ + 11.471, + 35.228 + ], + [ + 10.551, + 34.972 + ], + [ + 10.187, + 35.626 + ], + [ + 8.661, + 35.371 + ], + [ + 7.618, + 36.604 + ], + [ + 5.389, + 37.584 + ], + [ + 3.355, + 36.713 + ], + [ + 2.507, + 37.8 + ], + [ + 0.667, + 37.8 + ], + [ + 0.363, + 36.768 + ], + [ + 0.799, + 36.442 + ], + [ + 0.169, + 36.151 + ], + [ + 0.97, + 35.716 + ], + [ + -0.0, + 34.121 + ], + [ + 0.715, + 31.966 + ], + [ + 1.817, + 31.55 + ], + [ + 0.981, + 31.676 + ], + [ + 0.534, + 31.043 + ], + [ + 0.872, + 29.047 + ], + [ + 1.975, + 27.835 + ], + [ + 2.606, + 28.161 + ], + [ + 2.581, + 27.292 + ], + [ + 4.81, + 27.037 + ], + [ + 5.973, + 27.942 + ], + [ + 6.383, + 27.835 + ], + [ + 5.306, + 27.057 + ], + [ + 5.452, + 26.15 + ], + [ + 5.706, + 25.734 + ], + [ + 5.851, + 26.313 + ], + [ + 7.838, + 26.386 + ], + [ + 6.565, + 25.642 + ], + [ + 6.589, + 24.954 + ], + [ + 7.306, + 24.972 + ], + [ + 7.376, + 24.391 + ], + [ + 8.272, + 25.082 + ], + [ + 11.253, + 24.391 + ], + [ + 10.417, + 23.649 + ], + [ + 13.046, + 22.653 + ], + [ + 14.45, + 23.232 + ], + [ + 13.859, + 24.084 + ], + [ + 14.328, + 24.611 + ], + [ + 15.128, + 23.885 + ], + [ + 17.357, + 23.776 + ], + [ + 16.644, + 23.504 + ], + [ + 17.744, + 22.255 + ], + [ + 20.192, + 21.891 + ], + [ + 21.354, + 22.799 + ], + [ + 21.076, + 22.307 + ], + [ + 21.56, + 22.308 + ], + [ + 21.51, + 21.619 + ], + [ + 22.93, + 20.48 + ], + [ + 23.208, + 21.21 + ], + [ + 24.021, + 20.611 + ], + [ + 23.874, + 21.842 + ], + [ + 24.359, + 22.313 + ], + [ + 23.971, + 22.929 + ], + [ + 24.6, + 23.003 + ], + [ + 24.467, + 24.108 + ], + [ + 25.388, + 22.84 + ], + [ + 26.114, + 22.947 + ], + [ + 26.005, + 23.836 + ], + [ + 27.351, + 25.194 + ], + [ + 27.631, + 24.889 + ], + [ + 27.073, + 22.967 + ], + [ + 27.569, + 23.49 + ], + [ + 27.314, + 22.388 + ], + [ + 28.052, + 21.172 + ], + [ + 28.32, + 21.679 + ], + [ + 28.392, + 20.992 + ], + [ + 32.413, + 22.331 + ], + [ + 33.479, + 21.898 + ], + [ + 33.238, + 23.239 + ], + [ + 33.988, + 22.368 + ], + [ + 34.861, + 23.094 + ], + [ + 35.672, + 22.497 + ], + [ + 35.235, + 22.17 + ], + [ + 35.249, + 20.629 + ], + [ + 37.028, + 20.358 + ], + [ + 35.2, + 19.289 + ], + [ + 35.187, + 17.895 + ], + [ + 36.41, + 17.55 + ], + [ + 36.276, + 16.769 + ], + [ + 37.113, + 16.606 + ], + [ + 36.906, + 16.153 + ], + [ + 37.281, + 15.845 + ], + [ + 39.778, + 16.57 + ], + [ + 39.367, + 17.548 + ], + [ + 40.77, + 17.367 + ], + [ + 40.868, + 16.751 + ], + [ + 42.83, + 15.735 + ], + [ + 44.478, + 15.917 + ], + [ + 45.641, + 14.359 + ], + [ + 46.162, + 15.357 + ], + [ + 45.799, + 15.864 + ], + [ + 46.307, + 15.828 + ], + [ + 46.052, + 17.149 + ], + [ + 47.286, + 15.123 + ], + [ + 50.025, + 13.779 + ], + [ + 49.333, + 14.522 + ], + [ + 49.963, + 14.85 + ], + [ + 49.454, + 14.813 + ], + [ + 49.745, + 15.429 + ], + [ + 49.358, + 16.008 + ], + [ + 49.891, + 16.154 + ], + [ + 49.287, + 17.24 + ], + [ + 49.333, + 18.11 + ], + [ + 48.558, + 18.654 + ], + [ + 48.328, + 19.58 + ], + [ + 49.334, + 18.763 + ], + [ + 50.048, + 16.533 + ], + [ + 51.815, + 16.461 + ], + [ + 52.047, + 17.385 + ], + [ + 50.909, + 18.076 + ], + [ + 51.914, + 18.203 + ], + [ + 51.394, + 18.398 + ], + [ + 52.254, + 18.962 + ], + [ + 53.658, + 18.6 + ], + [ + 54.253, + 19.341 + ], + [ + 53.767, + 20.829 + ], + [ + 57.184, + 23.728 + ], + [ + 57.414, + 26.356 + ], + [ + 60.536, + 28.021 + ], + [ + 60.139, + 29.161 + ], + [ + 61.361, + 30.632 + ], + [ + 61.506, + 28.963 + ], + [ + 63.034, + 29.471 + ], + [ + 62.899, + 28.837 + ], + [ + 65.19, + 26.136 + ], + [ + 67.514, + 25.123 + ], + [ + 67.72, + 24.67 + ], + [ + 67.127, + 24.107 + ], + [ + 68.605, + 23.782 + ], + [ + 69.16, + 24.616 + ], + [ + 72.046, + 22.188 + ], + [ + 72.215, + 22.984 + ], + [ + 73.002, + 23.185 + ], + [ + 71.536, + 25.232 + ], + [ + 72.19, + 25.592 + ], + [ + 74.151, + 24.142 + ], + [ + 74.164, + 25.395 + ], + [ + 75.084, + 26.409 + ], + [ + 75.121, + 27.26 + ], + [ + 75.654, + 25.63 + ], + [ + 76.019, + 27.08 + ], + [ + 76.732, + 26.663 + ], + [ + 76.223, + 26.228 + ], + [ + 76.889, + 25.304 + ], + [ + 77.664, + 25.921 + ], + [ + 76.889, + 24.653 + ], + [ + 79.891, + 24.397 + ], + [ + 79.639, + 24.995 + ], + [ + 80.39, + 25.032 + ], + [ + 80.316, + 25.903 + ], + [ + 81.408, + 27.062 + ], + [ + 80.873, + 27.35 + ], + [ + 82.097, + 28.892 + ], + [ + 82.353, + 28.075 + ], + [ + 81.623, + 26.843 + ], + [ + 82.569, + 27.062 + ], + [ + 80.885, + 26.174 + ], + [ + 81.19, + 25.505 + ], + [ + 80.293, + 24.596 + ], + [ + 80.631, + 24.341 + ], + [ + 80.364, + 23.909 + ], + [ + 81.636, + 23.13 + ], + [ + 81.539, + 22.44 + ], + [ + 83.019, + 22.44 + ], + [ + 82.399, + 22.206 + ], + [ + 83.211, + 21.643 + ], + [ + 84.084, + 22.186 + ], + [ + 85.876, + 21.244 + ], + [ + 86.058, + 22.641 + ], + [ + 85.041, + 24.126 + ], + [ + 85.901, + 25.413 + ], + [ + 87.96, + 25.956 + ], + [ + 91.932, + 25.34 + ], + [ + 93.168, + 24.396 + ], + [ + 95.517, + 25.195 + ], + [ + 97.892, + 24.217 + ], + [ + 100.0, + 24.651 + ], + [ + 98.39, + 23.547 + ], + [ + 99.078, + 22.802 + ], + [ + 97.381, + 23.71 + ], + [ + 97.213, + 22.984 + ], + [ + 95.711, + 22.333 + ], + [ + 94.984, + 20.411 + ], + [ + 93.81, + 19.849 + ], + [ + 93.64, + 16.48 + ], + [ + 92.501, + 15.9 + ], + [ + 93.471, + 15.067 + ], + [ + 93.809, + 13.073 + ], + [ + 110.392, + 13.073 + ], + [ + 110.392, + 86.998 + ], + [ + 76.634, + 86.853 + ] + ] + ], + "worldSize": 100, + "meta": { + "sourceLengthKm": 1971.7732460448683, + "simplificationToleranceDeg": 0.0025, + "minCellSizeWorld": 1.5625, + "minCellSizeRealKm": 3.9999241458161254, + "boundingBox": { + "lonMin": -4.797583, + "lonMax": -1.3575, + "latMin": 47.203333, + "latMax": 48.898278 + } + } + }, + "normandie": { + "name": "normandie", + "points": [ + [ + 12.11, + 56.098 + ], + [ + 12.299, + 56.604 + ], + [ + 13.507, + 58.364 + ], + [ + 15.13, + 60.355 + ], + [ + 15.657, + 61.241 + ], + [ + 15.821, + 62.078 + ], + [ + 15.623, + 61.695 + ], + [ + 15.421, + 62.729 + ], + [ + 15.517, + 63.344 + ], + [ + 15.233, + 63.452 + ], + [ + 15.351, + 63.924 + ], + [ + 15.575, + 63.617 + ], + [ + 15.997, + 63.399 + ], + [ + 16.536, + 63.506 + ], + [ + 17.021, + 63.851 + ], + [ + 17.244, + 64.994 + ], + [ + 17.112, + 63.525 + ], + [ + 18.344, + 62.166 + ], + [ + 19.542, + 62.204 + ], + [ + 19.966, + 61.95 + ], + [ + 21.445, + 61.877 + ], + [ + 22.669, + 62.059 + ], + [ + 23.114, + 62.565 + ], + [ + 23.96, + 63.074 + ], + [ + 26.496, + 63.798 + ], + [ + 28.35, + 64.087 + ], + [ + 30.277, + 64.015 + ], + [ + 31.1, + 64.341 + ], + [ + 33.8, + 64.051 + ], + [ + 35.702, + 64.487 + ], + [ + 37.274, + 64.559 + ], + [ + 38.45, + 65.029 + ], + [ + 40.094, + 66.154 + ], + [ + 40.753, + 66.444 + ], + [ + 41.573, + 66.55 + ], + [ + 41.692, + 66.95 + ], + [ + 42.22, + 67.113 + ], + [ + 41.761, + 67.277 + ], + [ + 41.717, + 67.567 + ], + [ + 42.374, + 67.347 + ], + [ + 42.361, + 66.967 + ], + [ + 42.514, + 66.806 + ], + [ + 43.617, + 66.734 + ], + [ + 45.756, + 66.154 + ], + [ + 46.155, + 66.155 + ], + [ + 46.13, + 66.226 + ], + [ + 45.825, + 66.226 + ], + [ + 45.647, + 66.353 + ], + [ + 45.413, + 66.824 + ], + [ + 45.498, + 67.131 + ], + [ + 45.484, + 66.824 + ], + [ + 45.754, + 66.335 + ], + [ + 46.153, + 66.261 + ], + [ + 46.67, + 65.755 + ], + [ + 48.667, + 64.957 + ], + [ + 50.779, + 63.326 + ], + [ + 50.969, + 63.473 + ], + [ + 51.016, + 63.327 + ], + [ + 51.346, + 63.906 + ], + [ + 51.158, + 63.436 + ], + [ + 50.886, + 63.2 + ], + [ + 51.462, + 62.349 + ], + [ + 52.283, + 61.624 + ], + [ + 53.576, + 61.299 + ], + [ + 54.772, + 60.683 + ], + [ + 55.15, + 60.681 + ], + [ + 55.361, + 60.972 + ], + [ + 55.724, + 61.062 + ], + [ + 55.385, + 60.898 + ], + [ + 55.242, + 60.573 + ], + [ + 57.286, + 60.464 + ], + [ + 58.906, + 60.101 + ], + [ + 59.681, + 60.392 + ], + [ + 59.201, + 60.048 + ], + [ + 60.809, + 59.414 + ], + [ + 62.393, + 58.272 + ], + [ + 62.079, + 58.253 + ], + [ + 60.34, + 59.34 + ], + [ + 58.907, + 59.631 + ], + [ + 55.196, + 59.377 + ], + [ + 53.48, + 59.089 + ], + [ + 53.129, + 59.304 + ], + [ + 52.989, + 59.013 + ], + [ + 51.956, + 58.796 + ], + [ + 51.274, + 58.289 + ], + [ + 51.25, + 58.109 + ], + [ + 52.002, + 58.654 + ], + [ + 52.918, + 58.835 + ], + [ + 53.436, + 58.688 + ], + [ + 53.587, + 58.488 + ], + [ + 52.848, + 58.725 + ], + [ + 52.296, + 58.526 + ], + [ + 52.471, + 58.434 + ], + [ + 51.769, + 58.29 + ], + [ + 51.719, + 58.18 + ], + [ + 51.968, + 58.091 + ], + [ + 51.557, + 58.109 + ], + [ + 51.158, + 57.457 + ], + [ + 50.593, + 57.168 + ], + [ + 50.536, + 56.713 + ], + [ + 50.955, + 55.409 + ], + [ + 52.976, + 51.06 + ], + [ + 53.284, + 49.284 + ], + [ + 54.491, + 48.106 + ], + [ + 55.384, + 47.891 + ], + [ + 56.558, + 47.128 + ], + [ + 58.084, + 46.73 + ], + [ + 58.65, + 46.296 + ], + [ + 58.885, + 45.897 + ], + [ + 59.002, + 46.042 + ], + [ + 59.178, + 46.024 + ], + [ + 58.978, + 45.787 + ], + [ + 61.069, + 44.774 + ], + [ + 62.311, + 44.014 + ], + [ + 62.712, + 43.578 + ], + [ + 63.347, + 43.288 + ], + [ + 64.121, + 42.597 + ], + [ + 65.036, + 42.128 + ], + [ + 68.514, + 41.186 + ], + [ + 68.63, + 41.185 + ], + [ + 68.795, + 41.586 + ], + [ + 68.724, + 41.222 + ], + [ + 69.171, + 41.331 + ], + [ + 70.65, + 41.187 + ], + [ + 72.06, + 40.497 + ], + [ + 74.831, + 39.773 + ], + [ + 75.793, + 39.228 + ], + [ + 77.579, + 39.338 + ], + [ + 78.893, + 38.867 + ], + [ + 79.269, + 38.539 + ], + [ + 79.327, + 38.776 + ], + [ + 79.234, + 39.029 + ], + [ + 79.482, + 39.264 + ], + [ + 79.353, + 38.922 + ], + [ + 79.457, + 38.577 + ], + [ + 82.535, + 36.946 + ], + [ + 86.197, + 33.667 + ], + [ + 87.232, + 32.978 + ], + [ + 87.231, + 32.832 + ], + [ + 87.467, + 32.868 + ], + [ + 87.89, + 32.432 + ] + ], + "landRings": [ + [ + [ + 12.145, + 48.975 + ], + [ + 13.015, + 48.794 + ], + [ + 12.839, + 49.538 + ], + [ + 14.037, + 51.968 + ], + [ + 14.002, + 52.745 + ], + [ + 13.239, + 52.654 + ], + [ + 12.732, + 54.304 + ], + [ + 12.757, + 53.652 + ], + [ + 12.053, + 53.866 + ], + [ + 12.145, + 48.975 + ] + ], + [ + [ + 12.11, + 56.098 + ], + [ + 15.657, + 61.241 + ], + [ + 15.351, + 63.924 + ], + [ + 16.536, + 63.506 + ], + [ + 17.244, + 64.994 + ], + [ + 17.112, + 63.525 + ], + [ + 18.344, + 62.166 + ], + [ + 21.445, + 61.877 + ], + [ + 26.496, + 63.798 + ], + [ + 37.274, + 64.559 + ], + [ + 42.22, + 67.113 + ], + [ + 41.761, + 67.277 + ], + [ + 41.717, + 67.567 + ], + [ + 42.374, + 67.347 + ], + [ + 42.514, + 66.806 + ], + [ + 46.155, + 66.155 + ], + [ + 46.13, + 66.226 + ], + [ + 45.825, + 66.226 + ], + [ + 45.647, + 66.353 + ], + [ + 45.413, + 66.824 + ], + [ + 45.498, + 67.131 + ], + [ + 45.754, + 66.335 + ], + [ + 46.153, + 66.261 + ], + [ + 46.67, + 65.755 + ], + [ + 48.667, + 64.957 + ], + [ + 50.779, + 63.326 + ], + [ + 51.346, + 63.906 + ], + [ + 50.886, + 63.2 + ], + [ + 52.283, + 61.624 + ], + [ + 54.772, + 60.683 + ], + [ + 55.15, + 60.681 + ], + [ + 55.361, + 60.972 + ], + [ + 55.724, + 61.062 + ], + [ + 55.242, + 60.573 + ], + [ + 59.681, + 60.392 + ], + [ + 59.201, + 60.048 + ], + [ + 62.393, + 58.272 + ], + [ + 58.907, + 59.631 + ], + [ + 53.129, + 59.304 + ], + [ + 51.274, + 58.289 + ], + [ + 52.918, + 58.835 + ], + [ + 53.587, + 58.488 + ], + [ + 51.769, + 58.29 + ], + [ + 50.536, + 56.713 + ], + [ + 52.976, + 51.06 + ], + [ + 53.284, + 49.284 + ], + [ + 54.491, + 48.106 + ], + [ + 58.084, + 46.73 + ], + [ + 65.036, + 42.128 + ], + [ + 70.65, + 41.187 + ], + [ + 75.793, + 39.228 + ], + [ + 77.579, + 39.338 + ], + [ + 79.269, + 38.539 + ], + [ + 79.234, + 39.029 + ], + [ + 79.482, + 39.264 + ], + [ + 79.457, + 38.577 + ], + [ + 82.535, + 36.946 + ], + [ + 88.148, + 32.234 + ], + [ + 88.148, + 74.832 + ], + [ + 12.053, + 74.832 + ], + [ + 12.11, + 56.098 + ] + ] + ], + "worldSize": 100, + "meta": { + "sourceLengthKm": 367.17937853828636, + "simplificationToleranceDeg": 0.0025, + "minCellSizeWorld": 1.5625, + "minCellSizeRealKm": 3.9999241458161254, + "boundingBox": { + "lonMin": -1.297944, + "lonMax": 1.390833, + "latMin": 49.267056, + "latMax": 50.075028 + } + } + } +} \ No newline at end of file diff --git a/notebooks/pyproject.toml b/notebooks/pyproject.toml index ef2dac8ab..e45d5e922 100644 --- a/notebooks/pyproject.toml +++ b/notebooks/pyproject.toml @@ -16,6 +16,8 @@ dependencies = [ "requests>=2.33.0", "beautifulsoup4", "openpyxl", + "shapely>=2.0.0", + "pyshp>=2.3.1", ] [tool.uv] diff --git a/notebooks/uv.lock b/notebooks/uv.lock index 7698b7dcd..7f312656d 100644 --- a/notebooks/uv.lock +++ b/notebooks/uv.lock @@ -705,7 +705,7 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } wheels = [ @@ -780,7 +780,7 @@ resolution-markers = [ "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -1209,7 +1209,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -1509,17 +1509,17 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "decorator" }, - { name = "exceptiongroup" }, - { name = "jedi" }, - { name = "matplotlib-inline" }, - { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit" }, - { name = "pygments" }, - { name = "stack-data" }, - { name = "traitlets" }, - { name = "typing-extensions" }, + { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, + { name = "decorator", marker = "python_full_version < '3.11'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "jedi", marker = "python_full_version < '3.11'" }, + { name = "matplotlib-inline", marker = "python_full_version < '3.11'" }, + { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit", marker = "python_full_version < '3.11'" }, + { name = "pygments", marker = "python_full_version < '3.11'" }, + { name = "stack-data", marker = "python_full_version < '3.11'" }, + { name = "traitlets", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/40/18/f8598d287006885e7136451fdea0755af4ebcbfe342836f24deefaed1164/ipython-8.39.0.tar.gz", hash = "sha256:4110ae96012c379b8b6db898a07e186c40a2a1ef5d57a7fa83166047d9da7624", size = 5513971, upload-time = "2026-03-27T10:02:13.94Z" } wheels = [ @@ -1539,18 +1539,18 @@ resolution-markers = [ "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "decorator" }, - { name = "ipython-pygments-lexers" }, - { name = "jedi" }, - { name = "matplotlib-inline" }, - { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit" }, - { name = "psutil", marker = "sys_platform != 'emscripten'" }, - { name = "pygments" }, - { name = "stack-data" }, - { name = "traitlets" }, - { name = "typing-extensions", marker = "python_full_version < '3.12'" }, + { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, + { name = "decorator", marker = "python_full_version >= '3.11'" }, + { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.11'" }, + { name = "jedi", marker = "python_full_version >= '3.11'" }, + { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" }, + { name = "pexpect", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" }, + { name = "psutil", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten'" }, + { name = "pygments", marker = "python_full_version >= '3.11'" }, + { name = "stack-data", marker = "python_full_version >= '3.11'" }, + { name = "traitlets", marker = "python_full_version >= '3.11'" }, + { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e2/23/3a27530575643c8bb7bfc757a28e2e7ef80092afbf59a2bc5716320b6602/ipython-9.14.1.tar.gz", hash = "sha256:f913bf74df06d458e46ced84ca506c23797590d594b236fe60b14df213291e7b", size = 4433457, upload-time = "2026-06-05T08:12:34.921Z" } wheels = [ @@ -1562,7 +1562,7 @@ name = "ipython-pygments-lexers" version = "1.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pygments" }, + { name = "pygments", marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ @@ -2447,8 +2447,10 @@ dependencies = [ { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "pandas", version = "3.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pydantic" }, + { name = "pyshp" }, { name = "python-dotenv" }, { name = "requests" }, + { name = "shapely" }, { name = "web3" }, ] @@ -2470,8 +2472,10 @@ requires-dist = [ { name = "openpyxl" }, { name = "pandas", specifier = ">=2.0.0" }, { name = "pydantic", specifier = ">=2.11.7" }, + { name = "pyshp", specifier = ">=2.3.1" }, { name = "python-dotenv", specifier = ">=1.0" }, { name = "requests", specifier = ">=2.33.0" }, + { name = "shapely", specifier = ">=2.0.0" }, { name = "web3", specifier = ">=7.12.1" }, ] @@ -2672,10 +2676,10 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "python-dateutil", marker = "python_full_version < '3.11'" }, + { name = "pytz", marker = "python_full_version < '3.11'" }, + { name = "tzdata", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ @@ -2741,9 +2745,9 @@ resolution-markers = [ "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" } }, - { name = "python-dateutil" }, - { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, + { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" } wheels = [ @@ -2831,7 +2835,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess" }, + { name = "ptyprocess", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -3329,6 +3333,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, ] +[[package]] +name = "pyshp" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/6e/f6f241fcb57f09c856ae78249d70cf31c576840218226ba7d88eda5ceab8/pyshp-3.1.6.tar.gz", hash = "sha256:4c4b5a4138815c93defd6ebe50bae885b7e58984f431cdb7bb5d00718ac71daf", size = 2227945, upload-time = "2026-07-25T16:53:12.324Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/72/1f79dab76eb7651b5e3622a46b18a7f93f57c3a1317b712986c58810895e/pyshp-3.1.6-py3-none-any.whl", hash = "sha256:be8cd9436dcbde477c63ea789f7dcdea3af19f17ea84f2744bfc12efe9145d1e", size = 73744, upload-time = "2026-07-25T16:53:10.889Z" }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -4070,6 +4083,74 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/40/e1e72872c6354b306daef1703549e8e83b4d43cfea356311bf722a043752/setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3", size = 1008090, upload-time = "2026-07-04T15:31:20.885Z" }, ] +[[package]] +name = "shapely" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/bc/0989043118a27cccb4e906a46b7565ce36ca7b57f5a18b78f4f1b0f72d9d/shapely-2.1.2.tar.gz", hash = "sha256:2ed4ecb28320a433db18a5bf029986aa8afcfd740745e78847e330d5d94922a9", size = 315489, upload-time = "2025-09-24T13:51:41.432Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/89/c3548aa9b9812a5d143986764dededfa48d817714e947398bdda87c77a72/shapely-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7ae48c236c0324b4e139bea88a306a04ca630f49be66741b340729d380d8f52f", size = 1825959, upload-time = "2025-09-24T13:50:00.682Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8a/7ebc947080442edd614ceebe0ce2cdbd00c25e832c240e1d1de61d0e6b38/shapely-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eba6710407f1daa8e7602c347dfc94adc02205ec27ed956346190d66579eb9ea", size = 1629196, upload-time = "2025-09-24T13:50:03.447Z" }, + { url = "https://files.pythonhosted.org/packages/c8/86/c9c27881c20d00fc409e7e059de569d5ed0abfcec9c49548b124ebddea51/shapely-2.1.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef4a456cc8b7b3d50ccec29642aa4aeda959e9da2fe9540a92754770d5f0cf1f", size = 2951065, upload-time = "2025-09-24T13:50:05.266Z" }, + { url = "https://files.pythonhosted.org/packages/50/8a/0ab1f7433a2a85d9e9aea5b1fbb333f3b09b309e7817309250b4b7b2cc7a/shapely-2.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e38a190442aacc67ff9f75ce60aec04893041f16f97d242209106d502486a142", size = 3058666, upload-time = "2025-09-24T13:50:06.872Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c6/5a30ffac9c4f3ffd5b7113a7f5299ccec4713acd5ee44039778a7698224e/shapely-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:40d784101f5d06a1fd30b55fc11ea58a61be23f930d934d86f19a180909908a4", size = 3966905, upload-time = "2025-09-24T13:50:09.417Z" }, + { url = "https://files.pythonhosted.org/packages/9c/72/e92f3035ba43e53959007f928315a68fbcf2eeb4e5ededb6f0dc7ff1ecc3/shapely-2.1.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f6f6cd5819c50d9bcf921882784586aab34a4bd53e7553e175dece6db513a6f0", size = 4129260, upload-time = "2025-09-24T13:50:11.183Z" }, + { url = "https://files.pythonhosted.org/packages/42/24/605901b73a3d9f65fa958e63c9211f4be23d584da8a1a7487382fac7fdc5/shapely-2.1.2-cp310-cp310-win32.whl", hash = "sha256:fe9627c39c59e553c90f5bc3128252cb85dc3b3be8189710666d2f8bc3a5503e", size = 1544301, upload-time = "2025-09-24T13:50:12.521Z" }, + { url = "https://files.pythonhosted.org/packages/e1/89/6db795b8dd3919851856bd2ddd13ce434a748072f6fdee42ff30cbd3afa3/shapely-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:1d0bfb4b8f661b3b4ec3565fa36c340bfb1cda82087199711f86a88647d26b2f", size = 1722074, upload-time = "2025-09-24T13:50:13.909Z" }, + { url = "https://files.pythonhosted.org/packages/8f/8d/1ff672dea9ec6a7b5d422eb6d095ed886e2e523733329f75fdcb14ee1149/shapely-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:91121757b0a36c9aac3427a651a7e6567110a4a67c97edf04f8d55d4765f6618", size = 1820038, upload-time = "2025-09-24T13:50:15.628Z" }, + { url = "https://files.pythonhosted.org/packages/4f/ce/28fab8c772ce5db23a0d86bf0adaee0c4c79d5ad1db766055fa3dab442e2/shapely-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:16a9c722ba774cf50b5d4541242b4cce05aafd44a015290c82ba8a16931ff63d", size = 1626039, upload-time = "2025-09-24T13:50:16.881Z" }, + { url = "https://files.pythonhosted.org/packages/70/8b/868b7e3f4982f5006e9395c1e12343c66a8155c0374fdc07c0e6a1ab547d/shapely-2.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cc4f7397459b12c0b196c9efe1f9d7e92463cbba142632b4cc6d8bbbbd3e2b09", size = 3001519, upload-time = "2025-09-24T13:50:18.606Z" }, + { url = "https://files.pythonhosted.org/packages/13/02/58b0b8d9c17c93ab6340edd8b7308c0c5a5b81f94ce65705819b7416dba5/shapely-2.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:136ab87b17e733e22f0961504d05e77e7be8c9b5a8184f685b4a91a84efe3c26", size = 3110842, upload-time = "2025-09-24T13:50:21.77Z" }, + { url = "https://files.pythonhosted.org/packages/af/61/8e389c97994d5f331dcffb25e2fa761aeedfb52b3ad9bcdd7b8671f4810a/shapely-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:16c5d0fc45d3aa0a69074979f4f1928ca2734fb2e0dde8af9611e134e46774e7", size = 4021316, upload-time = "2025-09-24T13:50:23.626Z" }, + { url = "https://files.pythonhosted.org/packages/d3/d4/9b2a9fe6039f9e42ccf2cb3e84f219fd8364b0c3b8e7bbc857b5fbe9c14c/shapely-2.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6ddc759f72b5b2b0f54a7e7cde44acef680a55019eb52ac63a7af2cf17cb9cd2", size = 4178586, upload-time = "2025-09-24T13:50:25.443Z" }, + { url = "https://files.pythonhosted.org/packages/16/f6/9840f6963ed4decf76b08fd6d7fed14f8779fb7a62cb45c5617fa8ac6eab/shapely-2.1.2-cp311-cp311-win32.whl", hash = "sha256:2fa78b49485391224755a856ed3b3bd91c8455f6121fee0db0e71cefb07d0ef6", size = 1543961, upload-time = "2025-09-24T13:50:26.968Z" }, + { url = "https://files.pythonhosted.org/packages/38/1e/3f8ea46353c2a33c1669eb7327f9665103aa3a8dfe7f2e4ef714c210b2c2/shapely-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:c64d5c97b2f47e3cd9b712eaced3b061f2b71234b3fc263e0fcf7d889c6559dc", size = 1722856, upload-time = "2025-09-24T13:50:28.497Z" }, + { url = "https://files.pythonhosted.org/packages/24/c0/f3b6453cf2dfa99adc0ba6675f9aaff9e526d2224cbd7ff9c1a879238693/shapely-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fe2533caae6a91a543dec62e8360fe86ffcdc42a7c55f9dfd0128a977a896b94", size = 1833550, upload-time = "2025-09-24T13:50:30.019Z" }, + { url = "https://files.pythonhosted.org/packages/86/07/59dee0bc4b913b7ab59ab1086225baca5b8f19865e6101db9ebb7243e132/shapely-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ba4d1333cc0bc94381d6d4308d2e4e008e0bd128bdcff5573199742ee3634359", size = 1643556, upload-time = "2025-09-24T13:50:32.291Z" }, + { url = "https://files.pythonhosted.org/packages/26/29/a5397e75b435b9895cd53e165083faed5d12fd9626eadec15a83a2411f0f/shapely-2.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0bd308103340030feef6c111d3eb98d50dc13feea33affc8a6f9fa549e9458a3", size = 2988308, upload-time = "2025-09-24T13:50:33.862Z" }, + { url = "https://files.pythonhosted.org/packages/b9/37/e781683abac55dde9771e086b790e554811a71ed0b2b8a1e789b7430dd44/shapely-2.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e7d4d7ad262a48bb44277ca12c7c78cb1b0f56b32c10734ec9a1d30c0b0c54b", size = 3099844, upload-time = "2025-09-24T13:50:35.459Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f3/9876b64d4a5a321b9dc482c92bb6f061f2fa42131cba643c699f39317cb9/shapely-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e9eddfe513096a71896441a7c37db72da0687b34752c4e193577a145c71736fc", size = 3988842, upload-time = "2025-09-24T13:50:37.478Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/704c7292f7014c7e74ec84eddb7b109e1fbae74a16deae9c1504b1d15565/shapely-2.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:980c777c612514c0cf99bc8a9de6d286f5e186dcaf9091252fcd444e5638193d", size = 4152714, upload-time = "2025-09-24T13:50:39.9Z" }, + { url = "https://files.pythonhosted.org/packages/53/46/319c9dc788884ad0785242543cdffac0e6530e4d0deb6c4862bc4143dcf3/shapely-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9111274b88e4d7b54a95218e243282709b330ef52b7b86bc6aaf4f805306f454", size = 1542745, upload-time = "2025-09-24T13:50:41.414Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bf/cb6c1c505cb31e818e900b9312d514f381fbfa5c4363edfce0fcc4f8c1a4/shapely-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:743044b4cfb34f9a67205cee9279feaf60ba7d02e69febc2afc609047cb49179", size = 1722861, upload-time = "2025-09-24T13:50:43.35Z" }, + { url = "https://files.pythonhosted.org/packages/c3/90/98ef257c23c46425dc4d1d31005ad7c8d649fe423a38b917db02c30f1f5a/shapely-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b510dda1a3672d6879beb319bc7c5fd302c6c354584690973c838f46ec3e0fa8", size = 1832644, upload-time = "2025-09-24T13:50:44.886Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ab/0bee5a830d209adcd3a01f2d4b70e587cdd9fd7380d5198c064091005af8/shapely-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8cff473e81017594d20ec55d86b54bc635544897e13a7cfc12e36909c5309a2a", size = 1642887, upload-time = "2025-09-24T13:50:46.735Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5e/7d7f54ba960c13302584c73704d8c4d15404a51024631adb60b126a4ae88/shapely-2.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe7b77dc63d707c09726b7908f575fc04ff1d1ad0f3fb92aec212396bc6cfe5e", size = 2970931, upload-time = "2025-09-24T13:50:48.374Z" }, + { url = "https://files.pythonhosted.org/packages/f2/a2/83fc37e2a58090e3d2ff79175a95493c664bcd0b653dd75cb9134645a4e5/shapely-2.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ed1a5bbfb386ee8332713bf7508bc24e32d24b74fc9a7b9f8529a55db9f4ee6", size = 3082855, upload-time = "2025-09-24T13:50:50.037Z" }, + { url = "https://files.pythonhosted.org/packages/44/2b/578faf235a5b09f16b5f02833c53822294d7f21b242f8e2d0cf03fb64321/shapely-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a84e0582858d841d54355246ddfcbd1fce3179f185da7470f41ce39d001ee1af", size = 3979960, upload-time = "2025-09-24T13:50:51.74Z" }, + { url = "https://files.pythonhosted.org/packages/4d/04/167f096386120f692cc4ca02f75a17b961858997a95e67a3cb6a7bbd6b53/shapely-2.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc3487447a43d42adcdf52d7ac73804f2312cbfa5d433a7d2c506dcab0033dfd", size = 4142851, upload-time = "2025-09-24T13:50:53.49Z" }, + { url = "https://files.pythonhosted.org/packages/48/74/fb402c5a6235d1c65a97348b48cdedb75fb19eca2b1d66d04969fc1c6091/shapely-2.1.2-cp313-cp313-win32.whl", hash = "sha256:9c3a3c648aedc9f99c09263b39f2d8252f199cb3ac154fadc173283d7d111350", size = 1541890, upload-time = "2025-09-24T13:50:55.337Z" }, + { url = "https://files.pythonhosted.org/packages/41/47/3647fe7ad990af60ad98b889657a976042c9988c2807cf322a9d6685f462/shapely-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:ca2591bff6645c216695bdf1614fca9c82ea1144d4a7591a466fef64f28f0715", size = 1722151, upload-time = "2025-09-24T13:50:57.153Z" }, + { url = "https://files.pythonhosted.org/packages/3c/49/63953754faa51ffe7d8189bfbe9ca34def29f8c0e34c67cbe2a2795f269d/shapely-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2d93d23bdd2ed9dc157b46bc2f19b7da143ca8714464249bef6771c679d5ff40", size = 1834130, upload-time = "2025-09-24T13:50:58.49Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ee/dce001c1984052970ff60eb4727164892fb2d08052c575042a47f5a9e88f/shapely-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b", size = 1642802, upload-time = "2025-09-24T13:50:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/da/e7/fc4e9a19929522877fa602f705706b96e78376afb7fad09cad5b9af1553c/shapely-2.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8d8382dd120d64b03698b7298b89611a6ea6f55ada9d39942838b79c9bc89801", size = 3018460, upload-time = "2025-09-24T13:51:02.08Z" }, + { url = "https://files.pythonhosted.org/packages/a1/18/7519a25db21847b525696883ddc8e6a0ecaa36159ea88e0fef11466384d0/shapely-2.1.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:19efa3611eef966e776183e338b2d7ea43569ae99ab34f8d17c2c054d3205cc0", size = 3095223, upload-time = "2025-09-24T13:51:04.472Z" }, + { url = "https://files.pythonhosted.org/packages/48/de/b59a620b1f3a129c3fecc2737104a0a7e04e79335bd3b0a1f1609744cf17/shapely-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:346ec0c1a0fcd32f57f00e4134d1200e14bf3f5ae12af87ba83ca275c502498c", size = 4030760, upload-time = "2025-09-24T13:51:06.455Z" }, + { url = "https://files.pythonhosted.org/packages/96/b3/c6655ee7232b417562bae192ae0d3ceaadb1cc0ffc2088a2ddf415456cc2/shapely-2.1.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6305993a35989391bd3476ee538a5c9a845861462327efe00dd11a5c8c709a99", size = 4170078, upload-time = "2025-09-24T13:51:08.584Z" }, + { url = "https://files.pythonhosted.org/packages/a0/8e/605c76808d73503c9333af8f6cbe7e1354d2d238bda5f88eea36bfe0f42a/shapely-2.1.2-cp313-cp313t-win32.whl", hash = "sha256:c8876673449f3401f278c86eb33224c5764582f72b653a415d0e6672fde887bf", size = 1559178, upload-time = "2025-09-24T13:51:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/36/f7/d317eb232352a1f1444d11002d477e54514a4a6045536d49d0c59783c0da/shapely-2.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:4a44bc62a10d84c11a7a3d7c1c4fe857f7477c3506e24c9062da0db0ae0c449c", size = 1739756, upload-time = "2025-09-24T13:51:12.105Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c4/3ce4c2d9b6aabd27d26ec988f08cb877ba9e6e96086eff81bfea93e688c7/shapely-2.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:9a522f460d28e2bf4e12396240a5fc1518788b2fcd73535166d748399ef0c223", size = 1831290, upload-time = "2025-09-24T13:51:13.56Z" }, + { url = "https://files.pythonhosted.org/packages/17/b9/f6ab8918fc15429f79cb04afa9f9913546212d7fb5e5196132a2af46676b/shapely-2.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1ff629e00818033b8d71139565527ced7d776c269a49bd78c9df84e8f852190c", size = 1641463, upload-time = "2025-09-24T13:51:14.972Z" }, + { url = "https://files.pythonhosted.org/packages/a5/57/91d59ae525ca641e7ac5551c04c9503aee6f29b92b392f31790fcb1a4358/shapely-2.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f67b34271dedc3c653eba4e3d7111aa421d5be9b4c4c7d38d30907f796cb30df", size = 2970145, upload-time = "2025-09-24T13:51:16.961Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cb/4948be52ee1da6927831ab59e10d4c29baa2a714f599f1f0d1bc747f5777/shapely-2.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21952dc00df38a2c28375659b07a3979d22641aeb104751e769c3ee825aadecf", size = 3073806, upload-time = "2025-09-24T13:51:18.712Z" }, + { url = "https://files.pythonhosted.org/packages/03/83/f768a54af775eb41ef2e7bec8a0a0dbe7d2431c3e78c0a8bdba7ab17e446/shapely-2.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1f2f33f486777456586948e333a56ae21f35ae273be99255a191f5c1fa302eb4", size = 3980803, upload-time = "2025-09-24T13:51:20.37Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/559c7c195807c91c79d38a1f6901384a2878a76fbdf3f1048893a9b7534d/shapely-2.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cf831a13e0d5a7eb519e96f58ec26e049b1fad411fc6fc23b162a7ce04d9cffc", size = 4133301, upload-time = "2025-09-24T13:51:21.887Z" }, + { url = "https://files.pythonhosted.org/packages/80/cd/60d5ae203241c53ef3abd2ef27c6800e21afd6c94e39db5315ea0cbafb4a/shapely-2.1.2-cp314-cp314-win32.whl", hash = "sha256:61edcd8d0d17dd99075d320a1dd39c0cb9616f7572f10ef91b4b5b00c4aeb566", size = 1583247, upload-time = "2025-09-24T13:51:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/74/d4/135684f342e909330e50d31d441ace06bf83c7dc0777e11043f99167b123/shapely-2.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:a444e7afccdb0999e203b976adb37ea633725333e5b119ad40b1ca291ecf311c", size = 1773019, upload-time = "2025-09-24T13:51:24.873Z" }, + { url = "https://files.pythonhosted.org/packages/a3/05/a44f3f9f695fa3ada22786dc9da33c933da1cbc4bfe876fe3a100bafe263/shapely-2.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:5ebe3f84c6112ad3d4632b1fd2290665aa75d4cef5f6c5d77c4c95b324527c6a", size = 1834137, upload-time = "2025-09-24T13:51:26.665Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/4d57db45bf314573427b0a70dfca15d912d108e6023f623947fa69f39b72/shapely-2.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5860eb9f00a1d49ebb14e881f5caf6c2cf472c7fd38bd7f253bbd34f934eb076", size = 1642884, upload-time = "2025-09-24T13:51:28.029Z" }, + { url = "https://files.pythonhosted.org/packages/5a/27/4e29c0a55d6d14ad7422bf86995d7ff3f54af0eba59617eb95caf84b9680/shapely-2.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b705c99c76695702656327b819c9660768ec33f5ce01fa32b2af62b56ba400a1", size = 3018320, upload-time = "2025-09-24T13:51:29.903Z" }, + { url = "https://files.pythonhosted.org/packages/9f/bb/992e6a3c463f4d29d4cd6ab8963b75b1b1040199edbd72beada4af46bde5/shapely-2.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a1fd0ea855b2cf7c9cddaf25543e914dd75af9de08785f20ca3085f2c9ca60b0", size = 3094931, upload-time = "2025-09-24T13:51:32.699Z" }, + { url = "https://files.pythonhosted.org/packages/9c/16/82e65e21070e473f0ed6451224ed9fa0be85033d17e0c6e7213a12f59d12/shapely-2.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:df90e2db118c3671a0754f38e36802db75fe0920d211a27481daf50a711fdf26", size = 4030406, upload-time = "2025-09-24T13:51:34.189Z" }, + { url = "https://files.pythonhosted.org/packages/7c/75/c24ed871c576d7e2b64b04b1fe3d075157f6eb54e59670d3f5ffb36e25c7/shapely-2.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:361b6d45030b4ac64ddd0a26046906c8202eb60d0f9f53085f5179f1d23021a0", size = 4169511, upload-time = "2025-09-24T13:51:36.297Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f7/b3d1d6d18ebf55236eec1c681ce5e665742aab3c0b7b232720a7d43df7b6/shapely-2.1.2-cp314-cp314t-win32.whl", hash = "sha256:b54df60f1fbdecc8ebc2c5b11870461a6417b3d617f555e5033f1505d36e5735", size = 1602607, upload-time = "2025-09-24T13:51:37.757Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f6/f09272a71976dfc138129b8faf435d064a811ae2f708cb147dccdf7aacdb/shapely-2.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9", size = 1796682, upload-time = "2025-09-24T13:51:39.233Z" }, +] + [[package]] name = "six" version = "1.17.0" diff --git a/website/MDX_MIGRATION.md b/website/MDX_MIGRATION.md new file mode 100644 index 000000000..c46480e97 --- /dev/null +++ b/website/MDX_MIGRATION.md @@ -0,0 +1,298 @@ +# Blog-Stack: Migration nach MDX und Vike-nativem Rendering + +Arbeitsplan in drei Stufen. Jede Stufe ist einzeln lieferbar und einzeln wertvoll — +nach jeder kann abgebrochen werden, ohne dass ein halber Umbau liegen bleibt. + +--- + +## Ausgangslage + +Verifiziert am Stand `coast_post` (2026-08-23): + +| Fakt | Beleg | +|---|---| +| 29 MDX-Posts, 5 TSX-Posts im Blog | `ls blog/` | +| 33 MDX-Vorlesungen in 4 `quantum/`-Ordnern | `quantum/{amo,basics,hardware,qml}` | +| **34 von 36** prerenderten Seiten enthalten als Artikeltext nur `🔄 Lade interaktive Komponente...` | `grep -rl` über `build/blog/*/index.html` | +| Betroffen sind auch reine Prosa-Posts ohne jede Interaktivität | `blog/ipfs.mdx` (4.773 B Markdown, 0 Imports) → 477 Zeichen sichtbarer Text im HTML, davon der Großteil Navigation | +| `prerender: true` ist aktiv — Prerendering läuft, der Blog-Inhalt entwischt ihm | `pages/+config.ts:24` | +| Ursache: `ReactPostRenderer` lädt den Post in einem `useEffect`, der in Node nie feuert | `components/Post.tsx:41-85` | +| `vike-react` bietet `clientOnly()` und `` — im Repo **nirgends** benutzt | `node_modules/vike-react/dist/helpers/clientOnly.d.ts` | +| Vike akzeptiert `.mdx` als vollwertige `+Page`-Endung | `node_modules/vike/dist/utils/isScriptFile.js` → `extTemplates` enthält `'mdx'` | +| `stream: { require: true, disable: true }` — SSR per Stream, Ergebnis wird zu einem String zusammengefasst | `node_modules/vike-react/dist/types/Config.d.ts:158-182` | + +### Latenter Bug, unabhängig von allem anderen + +Die URL eines Posts ist sein **Index im nach `publishing_date` sortierten Array** +(`utils/blogLoader.ts:137-144`, `pages/blog/@id/+onBeforePrerenderStart.js`). Der Kommentar +im Code („oldest first to keep stable URLs") schützt nur davor, dass *neuere* Posts die +alten verschieben. Ein Post mit **rückdatiertem** `publishing_date` verschiebt jede URL +danach um eins — und bricht damit Links, Webmentions und die NFT-Zuordnung. + +Stufe 2.5 unten behebt das. Es lohnt sich auch dann, wenn Stufe 3 nie kommt. + +--- + +## Stufe 1 — TSX-Posts nach MDX konvertieren + +**Ziel:** Prosa wird Markdown, Widgets werden benannte Komponenten in `components/blog/`. +**Wert für sich allein:** Wartbarkeit, ein Dateiformat, ~60 Zeilen Sonderbehandlung weniger. +**Der eigentliche Wert:** ohne diese Trennung ist Stufe 2 unmöglich (siehe unten). + +### Warum das die Bedingung für Stufe 2 ist + +In `blog/prisoners_dilemma_interactive.tsx:17` läuft `ChartJS.register(...)` auf Modulebene. +Das Modul zu importieren zieht Chart.js in den Node-Build — und Chart.js braucht ein DOM. +Solange Prosa und Chart im selben Modul liegen, gibt es keine Granularität: entweder der +ganze Post rendert in Node oder gar keiner. Aktuell: gar keiner, für **alle** Posts. + +MDX zerlegt das. Vorbild ist `blog/etf_diversification_interactive.mdx` — Prosa als +Markdown, Widgets als Imports aus `components/blog/`. Das Muster existiert bereits und +funktioniert. + +### Reihenfolge + +Aufsteigend nach Schwierigkeit, nicht nach Größe. + +- [ ] **1.1 `budget_gridlock_interactive.tsx`** (669 Z., 262 Z. Prosa in Template-Strings, chart.js) + Pilot. Höchster Prosa-Anteil, der bereits als Markdown vorliegt. +- [ ] **1.2 `tragedy_of_commons_fishing.tsx`** (2025 Z., 140 Z. Markdown-Strings) +- [ ] **1.3 `prisoners_dilemma_interactive.tsx`** (1606 Z., 190 Z. Strings + 18 `

` in JSX, chart.js) +- [ ] **1.4 `merkle_ai_batching.tsx`** (381 Z., reine JSX-Prosa, 23 `

`, Mermaid) +- [ ] **1.5 `merkle_ai_batching_fundamentals.tsx`** (1243 Z., reine JSX-Prosa, 21 `

`, Mermaid) + +1.1–1.3 sind weitgehend mechanisch: die Prosa liegt dort schon als Markdown vor und wird +heute nur **zur Laufzeit im Browser** von `react-markdown` geparst statt zur Buildzeit von +MDX. Das ist eine echte Dopplung der Pipeline. + +1.4/1.5 sind Handarbeit: Prosa ist mit Panda-`css()` in JSX verwoben. + +### Pro Datei + +1. Widgets nach `components/blog/.tsx` extrahieren, Default-Export. +2. Prosa nach Markdown; `{\`...\`}` → Fließtext. +3. `export const meta = {…}` → Frontmatter. Mapping ist 1:1: + `title`, `publishing_date`, `tokenID`, `description`, `category`, `secondaryCategory`, `order`. +4. `publishing_date` **unverändert** übernehmen — davon hängt die URL ab. + +### Fallen + +- **`publishing_date` ändern verschiebt URLs.** Siehe latenter Bug oben. +- **Code-Blöcke laufen ab jetzt durch `MdxPre`** (`components/Post.tsx:143`). TSX-Posts + haben den `components`-Prop ignoriert, MDX nicht. Optische Änderung möglich, prüfen. +- **LaTeX:** MDX schützt `$$…$$` über `remark-math` (`vite.config.ts`). Der klassische + Bruch sind Unterstriche in Formeln, die sonst zu `` werden. Jede Formel nach der + Konvertierung im Browser ansehen. +- **Panda:** die inline-`css()`-Boxen aus 1.4/1.5 müssen entweder eigene Komponenten + werden oder in Markdown aufgehen. Kein `css()` mit JS-Variablen — siehe `CLAUDE.md` Regel 1. +- **Mermaid** (`components/MermaidDiagram.tsx`) wird in Stufe 2 ein `clientOnly()`-Kandidat. + +### Aufräumen, wenn alle fünf durch sind + +- [ ] `utils/blogLoader.ts:27,51-62,66-71` — TSX-Zweig und zweite Fallback-Titel-Regel entfernen +- [ ] `utils/globRegistry.ts` + `utils/lazyGlobRegistry.ts` — 10× `*.{tsx,mdx}` → `*.mdx` +- [ ] `types/BlogPost.ts:12-21` — `BlogPostMeta` löschen +- [ ] `types/BlogPost.ts` — `PostType` ist tot: `blogLoader.ts:77` setzt immer `"react"`, niemand liest es +- [ ] `components/MarkdownWithLatex.tsx` löschen (danach ungenutzt; `react-markdown` bleibt als Dependency für `AssistantChat.tsx`) +- [ ] Tests: `test/blogLoader.unit.test.ts:117,141`, `test/blogLoader.test.ts:128-133`, `test/blogLoader.integration.test.ts:29,50`, `test/blogLoader.nft.test.ts:29` + +### Abnahme + +``` +npm run build +``` + +Dann `build/blog/*/index.html` vorher/nachher vergleichen: **die Menge der URLs und die +Titel-zu-URL-Zuordnung muss identisch sein.** Alles andere ist ein Bug, kein Fortschritt. +Zusätzlich `npm test`, `npm run typecheck`, `npm run lint`. + +--- + +## Stufe 2 — Inhalt ins HTML bringen + +**Ziel:** Der Artikeltext steht in der Datei, nicht im JavaScript. +**Wert:** Bridgy Fed / Webmentions bekommen echten Inhalt statt `🔄 Lade interaktive +Komponente...` (siehe die Klage in `components/Post.tsx:136-140`), SEO, LCP, ToC ohne JS. +**Betrifft alle 36 Seiten**, nicht nur die fünf aus Stufe 1. + +### 2.0 Spike zuerst — das ist die entscheidende offene Frage + +Der naheliegende Weg ist `React.lazy` + `` statt `useEffect`, zusammen mit +`stream: { require: true, disable: true }` in `pages/+config.ts`. Streaming-SSR löst +`lazy` auf, und `disable: true` fasst den Stream zu einem vollständigen HTML-String +zusammen — genau das, was eine statische Datei braucht. + +**Das Risiko:** React liefert spät aufgelösten Suspense-Inhalt als `