@mostlyrightmd/core 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/discovery/index.cjs +563 -202
- package/dist/discovery/index.cjs.map +1 -1
- package/dist/discovery/index.mjs +563 -202
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/index.cjs +563 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +563 -202
- package/dist/index.global.js.map +1 -1
- package/dist/index.mjs +563 -202
- package/dist/index.mjs.map +1 -1
- package/dist/internal/cache/index.browser.cjs +563 -202
- package/dist/internal/cache/index.browser.cjs.map +1 -1
- package/dist/internal/cache/index.browser.mjs +1 -1
- package/dist/internal/cache/index.cjs +563 -202
- package/dist/internal/cache/index.cjs.map +1 -1
- package/dist/internal/cache/index.mjs +1 -1
- package/dist/internal/{chunk-QDQSYUFW.mjs → chunk-MLNV6B3L.mjs} +564 -203
- package/dist/internal/chunk-MLNV6B3L.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/internal/chunk-QDQSYUFW.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/discovery/index.ts","../../src/data/generated/stations.ts","../../src/discovery/availability.ts","../../src/discovery/international.ts","../../src/exceptions/index.ts","../../src/formats/toon.ts","../../src/discovery/snapshot.ts","../../src/discovery/data-version.ts","../../src/discovery/describe.ts"],"sourcesContent":["// Barrel for @mostlyrightmd/core/discovery — TS-W6.\n//\n// Five waves shipped at this subpath:\n//\n// Wave 1: availability(station, cache) reading from CacheStore.\n// Wave 2: internationalDailyExtremes(rows, opts) UTC→local rollup.\n// Wave 3: buildSnapshot(...) + DataSnapshot.toDict / .toToon.\n// Wave 4: dataVersionFromComponents / dataVersionForResearch via Web Crypto.\n// Wave 5: describe(schemaId) + featureCatalog() + climateGaps stub.\n//\n// Discovery lives at the subpath (NOT the root barrel) to keep the\n// @mostlyrightmd/core main bundle under its 25 KB size-limit gate\n// (TS-BUNDLE-01). Same pattern as transforms / temporal / formats / qc /\n// validator — see iter-4 H8 lesson in `packages-ts/core/src/index.ts`.\n//\n// Consumers import with:\n//\n// import {\n// availability,\n// internationalDailyExtremes,\n// buildSnapshot,\n// dataVersionFromComponents,\n// dataVersionForResearch,\n// describe,\n// featureCatalog,\n// climateGaps,\n// } from \"@mostlyrightmd/core/discovery\";\n// import type {\n// AvailabilityResult,\n// KeyEnumerableStore,\n// DailyExtreme,\n// InternationalDailyExtremesOptions,\n// InternationalRow,\n// DataSnapshot,\n// BuildSnapshotOptions,\n// DataVersion,\n// DataVersionComponents,\n// } from \"@mostlyrightmd/core/discovery\";\n\nexport { availability } from \"./availability.js\";\nexport type {\n AvailabilityOptions,\n AvailabilityResult,\n KeyEnumerableStore,\n} from \"./availability.js\";\n\nexport { internationalDailyExtremes } from \"./international.js\";\nexport type {\n DailyExtreme,\n InternationalDailyExtremesOptions,\n InternationalRow,\n} from \"./international.js\";\n\nexport { buildSnapshot } from \"./snapshot.js\";\nexport type { BuildSnapshotOptions, DataSnapshot } from \"./snapshot.js\";\n\nexport {\n dataVersionForResearch,\n dataVersionFromComponents,\n} from \"./data-version.js\";\nexport type { DataVersion, DataVersionComponents } from \"./data-version.js\";\n\nexport {\n ClimateGapsNotImplementedError,\n UnknownSchemaError,\n climateGaps,\n describe,\n featureCatalog,\n registerSchema,\n} from \"./describe.js\";\n","// AUTO-GENERATED by @mostlyrightmd/codegen from schemas/stations.json.\n// DO NOT EDIT — regenerate with: pnpm codegen\n// Last manifest SHA recorded in schemas/EXPORT_MANIFEST.json\n\nexport interface StationInfo {\n code: string | null;\n ghcnh_id: string | null;\n icao: string;\n name: string | null;\n tz: string;\n latitude: number | null;\n longitude: number | null;\n country: string | null;\n venues: ReadonlyArray<string>;\n}\n\nexport const STATIONS: ReadonlyArray<StationInfo> = [\n {\n code: \"EDDB\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDB\",\n latitude: 52.3667,\n longitude: 13.5033,\n name: \"Berlin Brandenburg\",\n tz: \"Europe/Berlin\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EDDF\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDF\",\n latitude: 50.0379,\n longitude: 8.5622,\n name: \"Frankfurt am Main\",\n tz: \"Europe/Berlin\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EDDM\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDM\",\n latitude: 48.3538,\n longitude: 11.7861,\n name: \"Munich Franz Josef Strauss\",\n tz: \"Europe/Berlin\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EFHK\",\n country: \"FI\",\n ghcnh_id: null,\n icao: \"EFHK\",\n latitude: 60.3172,\n longitude: 24.9633,\n name: \"Helsinki-Vantaa\",\n tz: \"Europe/Helsinki\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EGKK\",\n country: \"GB\",\n ghcnh_id: null,\n icao: \"EGKK\",\n latitude: 51.1481,\n longitude: -0.1903,\n name: \"London Gatwick\",\n tz: \"Europe/London\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EGLL\",\n country: \"GB\",\n ghcnh_id: null,\n icao: \"EGLL\",\n latitude: 51.4706,\n longitude: -0.4619,\n name: \"London Heathrow\",\n tz: \"Europe/London\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EHAM\",\n country: \"NL\",\n ghcnh_id: null,\n icao: \"EHAM\",\n latitude: 52.3086,\n longitude: 4.7639,\n name: \"Amsterdam Schiphol\",\n tz: \"Europe/Amsterdam\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EKCH\",\n country: \"DK\",\n ghcnh_id: null,\n icao: \"EKCH\",\n latitude: 55.6181,\n longitude: 12.6561,\n name: \"Copenhagen Kastrup\",\n tz: \"Europe/Copenhagen\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EPWA\",\n country: \"PL\",\n ghcnh_id: null,\n icao: \"EPWA\",\n latitude: 52.1657,\n longitude: 20.9671,\n name: \"Warsaw Chopin\",\n tz: \"Europe/Warsaw\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ESSA\",\n country: \"SE\",\n ghcnh_id: null,\n icao: \"ESSA\",\n latitude: 59.6519,\n longitude: 17.9186,\n name: \"Stockholm Arlanda\",\n tz: \"Europe/Stockholm\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ATL\",\n country: \"US\",\n ghcnh_id: \"USW00013874\",\n icao: \"KATL\",\n latitude: 33.6407,\n longitude: -84.4277,\n name: \"Hartsfield-Jackson Atlanta International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"AUS\",\n country: \"US\",\n ghcnh_id: \"USW00013904\",\n icao: \"KAUS\",\n latitude: 30.1975,\n longitude: -97.6664,\n name: \"Austin-Bergstrom International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"BNA\",\n country: \"US\",\n ghcnh_id: \"USW00013897\",\n icao: \"KBNA\",\n latitude: 36.1245,\n longitude: -86.6782,\n name: \"Nashville International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"BOS\",\n country: \"US\",\n ghcnh_id: \"USW00014739\",\n icao: \"KBOS\",\n latitude: 42.3656,\n longitude: -71.0096,\n name: \"Boston Logan International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"CVG\",\n country: \"US\",\n ghcnh_id: \"USW00093814\",\n icao: \"KCVG\",\n latitude: 39.0488,\n longitude: -84.6678,\n name: \"Cincinnati/Northern Kentucky International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"DCA\",\n country: \"US\",\n ghcnh_id: \"USW00013743\",\n icao: \"KDCA\",\n latitude: 38.8512,\n longitude: -77.0402,\n name: \"Washington Reagan National\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"DEN\",\n country: \"US\",\n ghcnh_id: \"USW00003017\",\n icao: \"KDEN\",\n latitude: 39.8561,\n longitude: -104.6737,\n name: \"Denver International\",\n tz: \"America/Denver\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"DFW\",\n country: \"US\",\n ghcnh_id: \"USW00003927\",\n icao: \"KDFW\",\n latitude: 32.8998,\n longitude: -97.0403,\n name: \"Dallas-Fort Worth International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"DTW\",\n country: \"US\",\n ghcnh_id: \"USW00094847\",\n icao: \"KDTW\",\n latitude: 42.2124,\n longitude: -83.3534,\n name: \"Detroit Metropolitan Wayne County\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"HOU\",\n country: \"US\",\n ghcnh_id: \"USW00012918\",\n icao: \"KHOU\",\n latitude: 29.6454,\n longitude: -95.2789,\n name: \"Houston Hobby\",\n tz: \"America/Chicago\",\n venues: [],\n },\n {\n code: \"IAH\",\n country: \"US\",\n ghcnh_id: \"USW00012960\",\n icao: \"KIAH\",\n latitude: 29.9844,\n longitude: -95.3414,\n name: \"Houston George Bush Intercontinental\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"LAS\",\n country: \"US\",\n ghcnh_id: \"USW00023169\",\n icao: \"KLAS\",\n latitude: 36.084,\n longitude: -115.1537,\n name: \"Harry Reid (McCarran) International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"LAX\",\n country: \"US\",\n ghcnh_id: \"USW00023174\",\n icao: \"KLAX\",\n latitude: 33.9425,\n longitude: -118.4081,\n name: \"Los Angeles International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"MDW\",\n country: \"US\",\n ghcnh_id: \"USW00014819\",\n icao: \"KMDW\",\n latitude: 41.7868,\n longitude: -87.7522,\n name: \"Chicago Midway International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"MIA\",\n country: \"US\",\n ghcnh_id: \"USW00012839\",\n icao: \"KMIA\",\n latitude: 25.7959,\n longitude: -80.287,\n name: \"Miami International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"MSP\",\n country: \"US\",\n ghcnh_id: \"USW00014922\",\n icao: \"KMSP\",\n latitude: 44.8848,\n longitude: -93.2223,\n name: \"Minneapolis-St Paul International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"MSY\",\n country: \"US\",\n ghcnh_id: \"USW00012916\",\n icao: \"KMSY\",\n latitude: 29.9934,\n longitude: -90.258,\n name: \"New Orleans Louis Armstrong International\",\n tz: \"America/Chicago\",\n venues: [],\n },\n {\n code: \"NYC\",\n country: \"US\",\n ghcnh_id: \"USW00094728\",\n icao: \"KNYC\",\n latitude: 40.7789,\n longitude: -73.9692,\n name: \"Central Park, New York\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"OKC\",\n country: \"US\",\n ghcnh_id: \"USW00013967\",\n icao: \"KOKC\",\n latitude: 35.3931,\n longitude: -97.6007,\n name: \"Oklahoma City Will Rogers World\",\n tz: \"America/Chicago\",\n venues: [],\n },\n {\n code: \"PHL\",\n country: \"US\",\n ghcnh_id: \"USW00013739\",\n icao: \"KPHL\",\n latitude: 39.8721,\n longitude: -75.2411,\n name: \"Philadelphia International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"PHX\",\n country: \"US\",\n ghcnh_id: \"USW00023183\",\n icao: \"KPHX\",\n latitude: 33.4373,\n longitude: -112.0078,\n name: \"Phoenix Sky Harbor International\",\n tz: \"America/Phoenix\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"SAT\",\n country: \"US\",\n ghcnh_id: \"USW00012921\",\n icao: \"KSAT\",\n latitude: 29.5337,\n longitude: -98.4698,\n name: \"San Antonio International\",\n tz: \"America/Chicago\",\n venues: [],\n },\n {\n code: \"SEA\",\n country: \"US\",\n ghcnh_id: \"USW00024233\",\n icao: \"KSEA\",\n latitude: 47.4502,\n longitude: -122.3088,\n name: \"Seattle-Tacoma International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"SFO\",\n country: \"US\",\n ghcnh_id: \"USW00023234\",\n icao: \"KSFO\",\n latitude: 37.6213,\n longitude: -122.379,\n name: \"San Francisco International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"SLC\",\n country: \"US\",\n ghcnh_id: \"USW00024127\",\n icao: \"KSLC\",\n latitude: 40.7884,\n longitude: -111.9778,\n name: \"Salt Lake City International\",\n tz: \"America/Denver\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"LEBL\",\n country: \"ES\",\n ghcnh_id: null,\n icao: \"LEBL\",\n latitude: 41.2974,\n longitude: 2.0833,\n name: \"Barcelona El Prat\",\n tz: \"Europe/Madrid\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LEMD\",\n country: \"ES\",\n ghcnh_id: null,\n icao: \"LEMD\",\n latitude: 40.4719,\n longitude: -3.5626,\n name: \"Madrid Barajas\",\n tz: \"Europe/Madrid\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LFPB\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPB\",\n latitude: 48.9694,\n longitude: 2.4414,\n name: \"Paris Le Bourget\",\n tz: \"Europe/Paris\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LFPG\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPG\",\n latitude: 49.0097,\n longitude: 2.5479,\n name: \"Paris Charles de Gaulle\",\n tz: \"Europe/Paris\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LFPO\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPO\",\n latitude: 48.7233,\n longitude: 2.3794,\n name: \"Paris Orly\",\n tz: \"Europe/Paris\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LIMC\",\n country: \"IT\",\n ghcnh_id: null,\n icao: \"LIMC\",\n latitude: 45.6306,\n longitude: 8.7281,\n name: \"Milan Malpensa\",\n tz: \"Europe/Rome\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LIRF\",\n country: \"IT\",\n ghcnh_id: null,\n icao: \"LIRF\",\n latitude: 41.8003,\n longitude: 12.2389,\n name: \"Rome Fiumicino\",\n tz: \"Europe/Rome\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LOWW\",\n country: \"AT\",\n ghcnh_id: null,\n icao: \"LOWW\",\n latitude: 48.1103,\n longitude: 16.5697,\n name: \"Vienna International\",\n tz: \"Europe/Vienna\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LSZH\",\n country: \"CH\",\n ghcnh_id: null,\n icao: \"LSZH\",\n latitude: 47.4647,\n longitude: 8.5492,\n name: \"Zurich\",\n tz: \"Europe/Zurich\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"NZAA\",\n country: \"NZ\",\n ghcnh_id: null,\n icao: \"NZAA\",\n latitude: -37.0081,\n longitude: 174.7917,\n name: \"Auckland\",\n tz: \"Pacific/Auckland\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"NZWN\",\n country: \"NZ\",\n ghcnh_id: null,\n icao: \"NZWN\",\n latitude: -41.3272,\n longitude: 174.8053,\n name: \"Wellington\",\n tz: \"Pacific/Auckland\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"OERK\",\n country: \"SA\",\n ghcnh_id: null,\n icao: \"OERK\",\n latitude: 24.9576,\n longitude: 46.6988,\n name: \"Riyadh King Khalid International\",\n tz: \"Asia/Riyadh\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"OMDB\",\n country: \"AE\",\n ghcnh_id: null,\n icao: \"OMDB\",\n latitude: 25.2532,\n longitude: 55.3657,\n name: \"Dubai International\",\n tz: \"Asia/Dubai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"OTHH\",\n country: \"QA\",\n ghcnh_id: null,\n icao: \"OTHH\",\n latitude: 25.2731,\n longitude: 51.608,\n name: \"Doha Hamad International\",\n tz: \"Asia/Qatar\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RCTP\",\n country: \"TW\",\n ghcnh_id: null,\n icao: \"RCTP\",\n latitude: 25.0777,\n longitude: 121.2328,\n name: \"Taipei Taoyuan\",\n tz: \"Asia/Taipei\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RJAA\",\n country: \"JP\",\n ghcnh_id: null,\n icao: \"RJAA\",\n latitude: 35.7647,\n longitude: 140.3864,\n name: \"Tokyo Narita\",\n tz: \"Asia/Tokyo\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RJTT\",\n country: \"JP\",\n ghcnh_id: null,\n icao: \"RJTT\",\n latitude: 35.5522,\n longitude: 139.78,\n name: \"Tokyo Haneda\",\n tz: \"Asia/Tokyo\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RKSI\",\n country: \"KR\",\n ghcnh_id: null,\n icao: \"RKSI\",\n latitude: 37.4691,\n longitude: 126.4505,\n name: \"Seoul Incheon\",\n tz: \"Asia/Seoul\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"SAEZ\",\n country: \"AR\",\n ghcnh_id: null,\n icao: \"SAEZ\",\n latitude: -34.8222,\n longitude: -58.5358,\n name: \"Buenos Aires Ezeiza\",\n tz: \"America/Argentina/Buenos_Aires\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"SBGR\",\n country: \"BR\",\n ghcnh_id: null,\n icao: \"SBGR\",\n latitude: -23.4356,\n longitude: -46.4731,\n name: \"São Paulo Guarulhos\",\n tz: \"America/Sao_Paulo\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"UUEE\",\n country: \"RU\",\n ghcnh_id: null,\n icao: \"UUEE\",\n latitude: 55.9728,\n longitude: 37.4147,\n name: \"Moscow Sheremetyevo\",\n tz: \"Europe/Moscow\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"VABB\",\n country: \"IN\",\n ghcnh_id: null,\n icao: \"VABB\",\n latitude: 19.0887,\n longitude: 72.8679,\n name: \"Mumbai Chhatrapati Shivaji\",\n tz: \"Asia/Kolkata\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"VHHH\",\n country: \"HK\",\n ghcnh_id: null,\n icao: \"VHHH\",\n latitude: 22.308,\n longitude: 113.9185,\n name: \"Hong Kong International\",\n tz: \"Asia/Hong_Kong\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"VIDP\",\n country: \"IN\",\n ghcnh_id: null,\n icao: \"VIDP\",\n latitude: 28.5562,\n longitude: 77.1,\n name: \"Delhi Indira Gandhi\",\n tz: \"Asia/Kolkata\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"VTBS\",\n country: \"TH\",\n ghcnh_id: null,\n icao: \"VTBS\",\n latitude: 13.69,\n longitude: 100.7501,\n name: \"Bangkok Suvarnabhumi\",\n tz: \"Asia/Bangkok\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"WSSS\",\n country: \"SG\",\n ghcnh_id: null,\n icao: \"WSSS\",\n latitude: 1.3644,\n longitude: 103.9915,\n name: \"Singapore Changi\",\n tz: \"Asia/Singapore\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"YBBN\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YBBN\",\n latitude: -27.3842,\n longitude: 153.1175,\n name: \"Brisbane\",\n tz: \"Australia/Brisbane\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"YMML\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YMML\",\n latitude: -37.6733,\n longitude: 144.8433,\n name: \"Melbourne Tullamarine\",\n tz: \"Australia/Melbourne\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"YSSY\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YSSY\",\n latitude: -33.9461,\n longitude: 151.1772,\n name: \"Sydney Kingsford Smith\",\n tz: \"Australia/Sydney\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZBAA\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZBAA\",\n latitude: 40.0801,\n longitude: 116.5846,\n name: \"Beijing Capital\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZSPD\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZSPD\",\n latitude: 31.1443,\n longitude: 121.8083,\n name: \"Shanghai Pudong\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n] as const;\n\nexport const STATION_BY_CODE: ReadonlyMap<string, StationInfo> = new Map<string, StationInfo>([\n [\"ATL\", STATIONS[10]!],\n [\"AUS\", STATIONS[11]!],\n [\"BNA\", STATIONS[12]!],\n [\"BOS\", STATIONS[13]!],\n [\"CVG\", STATIONS[14]!],\n [\"DCA\", STATIONS[15]!],\n [\"DEN\", STATIONS[16]!],\n [\"DFW\", STATIONS[17]!],\n [\"DTW\", STATIONS[18]!],\n [\"EDDB\", STATIONS[0]!],\n [\"EDDF\", STATIONS[1]!],\n [\"EDDM\", STATIONS[2]!],\n [\"EFHK\", STATIONS[3]!],\n [\"EGKK\", STATIONS[4]!],\n [\"EGLL\", STATIONS[5]!],\n [\"EHAM\", STATIONS[6]!],\n [\"EKCH\", STATIONS[7]!],\n [\"EPWA\", STATIONS[8]!],\n [\"ESSA\", STATIONS[9]!],\n [\"HOU\", STATIONS[19]!],\n [\"IAH\", STATIONS[20]!],\n [\"LAS\", STATIONS[21]!],\n [\"LAX\", STATIONS[22]!],\n [\"LEBL\", STATIONS[35]!],\n [\"LEMD\", STATIONS[36]!],\n [\"LFPB\", STATIONS[37]!],\n [\"LFPG\", STATIONS[38]!],\n [\"LFPO\", STATIONS[39]!],\n [\"LIMC\", STATIONS[40]!],\n [\"LIRF\", STATIONS[41]!],\n [\"LOWW\", STATIONS[42]!],\n [\"LSZH\", STATIONS[43]!],\n [\"MDW\", STATIONS[23]!],\n [\"MIA\", STATIONS[24]!],\n [\"MSP\", STATIONS[25]!],\n [\"MSY\", STATIONS[26]!],\n [\"NYC\", STATIONS[27]!],\n [\"NZAA\", STATIONS[44]!],\n [\"NZWN\", STATIONS[45]!],\n [\"OERK\", STATIONS[46]!],\n [\"OKC\", STATIONS[28]!],\n [\"OMDB\", STATIONS[47]!],\n [\"OTHH\", STATIONS[48]!],\n [\"PHL\", STATIONS[29]!],\n [\"PHX\", STATIONS[30]!],\n [\"RCTP\", STATIONS[49]!],\n [\"RJAA\", STATIONS[50]!],\n [\"RJTT\", STATIONS[51]!],\n [\"RKSI\", STATIONS[52]!],\n [\"SAEZ\", STATIONS[53]!],\n [\"SAT\", STATIONS[31]!],\n [\"SBGR\", STATIONS[54]!],\n [\"SEA\", STATIONS[32]!],\n [\"SFO\", STATIONS[33]!],\n [\"SLC\", STATIONS[34]!],\n [\"UUEE\", STATIONS[55]!],\n [\"VABB\", STATIONS[56]!],\n [\"VHHH\", STATIONS[57]!],\n [\"VIDP\", STATIONS[58]!],\n [\"VTBS\", STATIONS[59]!],\n [\"WSSS\", STATIONS[60]!],\n [\"YBBN\", STATIONS[61]!],\n [\"YMML\", STATIONS[62]!],\n [\"YSSY\", STATIONS[63]!],\n [\"ZBAA\", STATIONS[64]!],\n [\"ZSPD\", STATIONS[65]!],\n]);\n\nexport const STATION_BY_ICAO: ReadonlyMap<string, StationInfo> = new Map<string, StationInfo>([\n [\"EDDB\", STATIONS[0]!],\n [\"EDDF\", STATIONS[1]!],\n [\"EDDM\", STATIONS[2]!],\n [\"EFHK\", STATIONS[3]!],\n [\"EGKK\", STATIONS[4]!],\n [\"EGLL\", STATIONS[5]!],\n [\"EHAM\", STATIONS[6]!],\n [\"EKCH\", STATIONS[7]!],\n [\"EPWA\", STATIONS[8]!],\n [\"ESSA\", STATIONS[9]!],\n [\"KATL\", STATIONS[10]!],\n [\"KAUS\", STATIONS[11]!],\n [\"KBNA\", STATIONS[12]!],\n [\"KBOS\", STATIONS[13]!],\n [\"KCVG\", STATIONS[14]!],\n [\"KDCA\", STATIONS[15]!],\n [\"KDEN\", STATIONS[16]!],\n [\"KDFW\", STATIONS[17]!],\n [\"KDTW\", STATIONS[18]!],\n [\"KHOU\", STATIONS[19]!],\n [\"KIAH\", STATIONS[20]!],\n [\"KLAS\", STATIONS[21]!],\n [\"KLAX\", STATIONS[22]!],\n [\"KMDW\", STATIONS[23]!],\n [\"KMIA\", STATIONS[24]!],\n [\"KMSP\", STATIONS[25]!],\n [\"KMSY\", STATIONS[26]!],\n [\"KNYC\", STATIONS[27]!],\n [\"KOKC\", STATIONS[28]!],\n [\"KPHL\", STATIONS[29]!],\n [\"KPHX\", STATIONS[30]!],\n [\"KSAT\", STATIONS[31]!],\n [\"KSEA\", STATIONS[32]!],\n [\"KSFO\", STATIONS[33]!],\n [\"KSLC\", STATIONS[34]!],\n [\"LEBL\", STATIONS[35]!],\n [\"LEMD\", STATIONS[36]!],\n [\"LFPB\", STATIONS[37]!],\n [\"LFPG\", STATIONS[38]!],\n [\"LFPO\", STATIONS[39]!],\n [\"LIMC\", STATIONS[40]!],\n [\"LIRF\", STATIONS[41]!],\n [\"LOWW\", STATIONS[42]!],\n [\"LSZH\", STATIONS[43]!],\n [\"NZAA\", STATIONS[44]!],\n [\"NZWN\", STATIONS[45]!],\n [\"OERK\", STATIONS[46]!],\n [\"OMDB\", STATIONS[47]!],\n [\"OTHH\", STATIONS[48]!],\n [\"RCTP\", STATIONS[49]!],\n [\"RJAA\", STATIONS[50]!],\n [\"RJTT\", STATIONS[51]!],\n [\"RKSI\", STATIONS[52]!],\n [\"SAEZ\", STATIONS[53]!],\n [\"SBGR\", STATIONS[54]!],\n [\"UUEE\", STATIONS[55]!],\n [\"VABB\", STATIONS[56]!],\n [\"VHHH\", STATIONS[57]!],\n [\"VIDP\", STATIONS[58]!],\n [\"VTBS\", STATIONS[59]!],\n [\"WSSS\", STATIONS[60]!],\n [\"YBBN\", STATIONS[61]!],\n [\"YMML\", STATIONS[62]!],\n [\"YSSY\", STATIONS[63]!],\n [\"ZBAA\", STATIONS[64]!],\n [\"ZSPD\", STATIONS[65]!],\n]);\n","// TS-W6 Wave 1 — availability(station, cache) reading from CacheStore.\n//\n// Ports Python `mostlyright.discovery.availability` semantics. Python walks the\n// on-disk parquet hierarchy; TS uses the same canonical cache-key shape so the\n// CacheStore implementation (Memory / IndexedDB / Fs) is the persistence layer.\n//\n// The keys we scan match `cacheKeyForObservations(station, year, month, source?)`\n// and `cacheKeyForClimate(station, year)`. @mostlyrightmd/meta's `research()` writes\n// cache entries under the 3-letter NWS code (`resolved.code` from\n// STATION_BY_ICAO / STATION_BY_CODE) for US stations — e.g. `KNYC` resolves to\n// `NYC` and the cache key reads `...:observations:NYC:...`. Codex iter-2 P2:\n// availability resolves the input the same way so `availability(\"KNYC\", cache)`\n// finds entries written by `research(\"KNYC\", ...)`.\n\nimport { STATION_BY_CODE, STATION_BY_ICAO } from \"../data/generated/stations.js\";\nimport type { CacheStore } from \"../internal/cache/index.js\";\n\n/**\n * Cache-coverage summary for a station.\n *\n * Mirrors Python `availability()` return shape.\n */\nexport interface AvailabilityResult {\n station: string;\n /** Count of distinct (year, month) observation cache entries. */\n monthsCached: number;\n /** Earliest cached month as `\"YYYY-MM\"`, or null if none. */\n firstMonth: string | null;\n /** Latest cached month as `\"YYYY-MM\"`, or null if none. */\n lastMonth: string | null;\n /** Count of cached climate years. */\n climateYears: number;\n /** Earliest cached climate year as `\"YYYY\"`, or null if none. */\n firstClimateYear: string | null;\n /** Latest cached climate year as `\"YYYY\"`, or null if none. */\n lastClimateYear: string | null;\n}\n\n/**\n * Optional adapter that lets `availability()` enumerate keys from a store.\n *\n * CacheStore's mandatory contract is opaque key-value: get/set/delete/withLock.\n * Discovery needs to enumerate which keys exist for a station — this is\n * implementation-specific (Memory iterates its Map, IndexedDB uses\n * `getAllKeys`, Fs walks the directory tree). Stores that support enumeration\n * implement the optional `listKeys(prefix)` method and `availability()` uses\n * it; stores without it return zero-coverage but never throw.\n *\n * Listed keys may exceed the requested prefix in the result (callers filter);\n * `listKeys` is best-effort.\n */\nexport interface KeyEnumerableStore extends CacheStore {\n listKeys(prefix: string): Promise<ReadonlyArray<string>>;\n}\n\nfunction hasListKeys(store: CacheStore): store is KeyEnumerableStore {\n return typeof (store as KeyEnumerableStore).listKeys === \"function\";\n}\n\nconst STATION_RE = /^[A-Z0-9]{3,5}$/;\n\n/**\n * Resolve `station` to the canonical CACHE-KEY station code.\n *\n * - For known stations: returns the 3-letter NWS `code` (e.g. `KNYC` → `NYC`)\n * if one exists, falling back to the 4-letter ICAO. This matches the cache\n * key that `research()` writes for US stations via `resolved.code` and\n * international stations via `resolved.icao` (no NWS code exists).\n * - For unknown inputs that still satisfy the 3-5 char alphanumeric format:\n * returns the upper-cased input. This lets bespoke callers query custom\n * keys without coupling availability to the station registry.\n */\nfunction normalizeStation(station: string): string {\n const upper = station.toUpperCase();\n if (!STATION_RE.test(upper)) {\n throw new RangeError(\n `availability: station must be a 3-5 char alphanumeric code; got ${JSON.stringify(station)}`,\n );\n }\n const byIcao = STATION_BY_ICAO.get(upper);\n if (byIcao !== undefined) {\n // US stations: NWS code is the cache-key form. International stations:\n // no NWS code, ICAO is the cache-key form.\n return byIcao.code ?? byIcao.icao;\n }\n const byCode = STATION_BY_CODE.get(upper);\n if (byCode !== undefined) {\n return byCode.code ?? byCode.icao;\n }\n // Bespoke / unknown codes — pass through. availability() returns\n // zero-coverage if the cache doesn't have entries under this exact key.\n return upper;\n}\n\nconst OBS_KEY_RE = /^mostlyright:v1:observations:([A-Z0-9]+):(\\d{4}):(\\d{2})(?::[a-z0-9_-]+)?$/;\nconst CLIMATE_KEY_RE = /^mostlyright:v1:climate:([A-Z0-9]+):(\\d{4})$/;\n\n/**\n * Options for `availability()`.\n */\nexport interface AvailabilityOptions {\n /**\n * If true, confirm each candidate key with `cache.get()` before counting.\n * Eliminates the small overcount possible on stores whose `listKeys()` can\n * return keys with already-expired TTL entries (FsStore and IndexedDBStore\n * lazy-evict on `get`, not on `listKeys` — codex iter-3 P2). Off by default\n * because the v0.1.0 `research()` flow never writes with `ttlMs`, so the\n * overcount window is empty; turn on only if you populate the cache with\n * explicit TTLs.\n *\n * Cost: one `get()` per matching key. On warm caches this is cheap\n * (MemoryStore + IndexedDBStore in-memory). On FsStore it reads each\n * candidate's file.\n */\n readonly validate?: boolean;\n}\n\n/**\n * Return a summary of cached coverage for `station`.\n *\n * Stores without enumeration support return a zero-coverage result with the\n * station name populated (counts all zero, dates null).\n *\n * Pass `{ validate: true }` to confirm each candidate key via `cache.get()`\n * — needed if your callers populate the cache with `ttlMs` and might query\n * after expiry. The v0.1.0 `research()` flow does not use `ttlMs`, so the\n * default (fast scan, no validation) is correct for the canonical path.\n */\nexport async function availability(\n station: string,\n cache: CacheStore,\n opts: AvailabilityOptions = {},\n): Promise<AvailabilityResult> {\n const stationCode = normalizeStation(station);\n const empty: AvailabilityResult = Object.freeze({\n station: stationCode,\n monthsCached: 0,\n firstMonth: null,\n lastMonth: null,\n climateYears: 0,\n firstClimateYear: null,\n lastClimateYear: null,\n });\n\n if (!hasListKeys(cache)) {\n return empty;\n }\n\n // Scan both the canonical cache-key form AND the original upper-cased\n // input (when they differ — e.g. user passed \"KNYC\" → normalized \"NYC\";\n // scan \":NYC:\" AND \":KNYC:\"). Codex iter-5 P2: a caller using the\n // documented `cacheKeyForObservations(\"KNYC\", ...)` helper writes under\n // :KNYC:, which the normalized prefix would miss.\n const upperInput = station.toUpperCase();\n const scanCodes = upperInput === stationCode ? [stationCode] : [stationCode, upperInput];\n\n const obsPrefixes = scanCodes.map((c) => `mostlyright:v1:observations:${c}:`);\n const climatePrefixes = scanCodes.map((c) => `mostlyright:v1:climate:${c}:`);\n\n const obsKeySets = await Promise.all(obsPrefixes.map((p) => cache.listKeys(p)));\n const climateKeySets = await Promise.all(climatePrefixes.map((p) => cache.listKeys(p)));\n const obsKeys = obsKeySets.flat();\n const climateKeys = climateKeySets.flat();\n\n // Collect the matching keys grouped by (year-month) / year so we can both\n // dedupe (e.g. per-source observation keys for the same month) and run a\n // single validation get() per group.\n const monthCandidates = new Map<string, string[]>();\n for (const key of obsKeys) {\n const m = OBS_KEY_RE.exec(key);\n if (m === null) continue;\n const keyStation = m[1] as string;\n if (!scanCodes.includes(keyStation)) continue;\n const ym = `${m[2]}-${m[3]}`;\n const arr = monthCandidates.get(ym) ?? [];\n arr.push(key);\n monthCandidates.set(ym, arr);\n }\n\n const yearCandidates = new Map<string, string[]>();\n for (const key of climateKeys) {\n const m = CLIMATE_KEY_RE.exec(key);\n if (m === null) continue;\n const keyStation = m[1] as string;\n if (!scanCodes.includes(keyStation)) continue;\n const y = m[2] as string;\n const arr = yearCandidates.get(y) ?? [];\n arr.push(key);\n yearCandidates.set(y, arr);\n }\n\n let months: string[];\n let years: string[];\n\n if (opts.validate === true) {\n // For each candidate group, confirm at least one key still resolves.\n // Stores lazy-evict expired entries inside get() — calling it discards\n // stale TTLs from the on-disk / on-IDB state and gives us a correct\n // overall count.\n const monthChecks = await Promise.all(\n [...monthCandidates.entries()].map(async ([ym, keys]) => {\n for (const k of keys) {\n if ((await cache.get(k)) !== null) return ym;\n }\n return null;\n }),\n );\n months = monthChecks.filter((v): v is string => v !== null).sort();\n const yearChecks = await Promise.all(\n [...yearCandidates.entries()].map(async ([y, keys]) => {\n for (const k of keys) {\n if ((await cache.get(k)) !== null) return y;\n }\n return null;\n }),\n );\n years = yearChecks.filter((v): v is string => v !== null).sort();\n } else {\n months = [...monthCandidates.keys()].sort();\n years = [...yearCandidates.keys()].sort();\n }\n\n return Object.freeze({\n station: stationCode,\n monthsCached: months.length,\n firstMonth: months[0] ?? null,\n lastMonth: months.at(-1) ?? null,\n climateYears: years.length,\n firstClimateYear: years[0] ?? null,\n lastClimateYear: years.at(-1) ?? null,\n });\n}\n","// TS-W6 Wave 2 — internationalDailyExtremes rollup.\n//\n// Ports Python `mostlyright.international.daily_extremes` semantics:\n//\n// - For each row, parse `observed_at` as UTC, convert to the station's IANA\n// local calendar date via `Intl.DateTimeFormat` (the only universally-\n// available tz-aware extractor in JS), bucket per `(localDate)`.\n// - For each bucketed day:\n// * n_obs < 12 → tmin/tmax/tmean null (low coverage; matches Python\n// `_LOW_COVERAGE_THRESHOLD`).\n// * Otherwise: tmin = min(temp_c), tmax = max(temp_c), tmean = mean.\n// Round HALF_UP — to 1 decimal for US stations, whole °C for intl.\n// - precip_mm summed across rows that report it (mm — matches the\n// observation schema field name; Python uses `precip_inches` because its\n// historical units are inches, but the TS schema is mm).\n//\n// `stationTz` is required because the input rows are raw observations (no\n// station registry lookup here); callers supply the IANA tz string for the\n// station they're rolling up.\n\nconst LOW_COVERAGE_THRESHOLD = 12;\n\n/** Minimal row shape consumed by `internationalDailyExtremes`. */\nexport interface InternationalRow {\n /** ISO 8601 UTC instant. Must end with `Z` or include an offset. */\n observed_at?: string | null;\n /** Air temperature in degrees Celsius. */\n temp_c?: number | null;\n /** 1-hour precipitation total in millimeters. */\n precip_mm_1h?: number | null;\n /** Source identifier (preserved on the tmin/tmax aggregate). */\n source?: string | null;\n}\n\nexport interface DailyExtreme {\n /** Station-local calendar date as `YYYY-MM-DD`. */\n localDate: string;\n /** Count of rows with a parseable temp_c. */\n nObs: number;\n /** Min temperature in °C, or null on low coverage. */\n tempMinC: number | null;\n /** Max temperature in °C, or null on low coverage. */\n tempMaxC: number | null;\n /** Mean temperature in °C, or null on low coverage. */\n tempMeanC: number | null;\n /** Min temperature in °F, or null on low coverage. */\n tempMinF: number | null;\n /** Max temperature in °F, or null on low coverage. */\n tempMaxF: number | null;\n /** Total 1-hour precipitation across the local day, in mm. */\n precipMm: number;\n /** Source identifier of the row that produced tmin (or null on low coverage). */\n sourceTmin: string | null;\n /** Source identifier of the row that produced tmax (or null on low coverage). */\n sourceTmax: string | null;\n}\n\nexport interface InternationalDailyExtremesOptions {\n /** IANA timezone identifier for the station, e.g. `\"Asia/Tokyo\"`. Required. */\n stationTz: string;\n /**\n * Decimal places for HALF_UP rounding. Defaults to 0 (whole °C) — the\n * international convention. Pass `1` for US-station tenths.\n */\n precision?: number;\n /**\n * Minimum number of observations required for tmin/tmax/tmean to be\n * populated. Defaults to 12 (the Python threshold). Tests can override.\n */\n minObs?: number;\n}\n\nconst PARTS_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nfunction getDateFormatter(tz: string): Intl.DateTimeFormat {\n let f = PARTS_CACHE.get(tz);\n if (f === undefined) {\n // `formatToParts` with these options yields `{year, month, day}` parts\n // for the given UTC instant in the requested tz. The result is the\n // local calendar date even across DST and arbitrary UTC offsets.\n f = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: tz,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n });\n PARTS_CACHE.set(tz, f);\n }\n return f;\n}\n\nfunction localDateFor(instant: Date, tz: string): string {\n const parts = getDateFormatter(tz).formatToParts(instant);\n let y = \"\";\n let m = \"\";\n let d = \"\";\n for (const p of parts) {\n if (p.type === \"year\") y = p.value;\n else if (p.type === \"month\") m = p.value;\n else if (p.type === \"day\") d = p.value;\n }\n return `${y}-${m}-${d}`;\n}\n\nfunction parseInstant(observed: string | null | undefined): Date | null {\n if (observed === undefined || observed === null || observed.length === 0) {\n return null;\n }\n const ms = Date.parse(observed);\n if (Number.isNaN(ms)) return null;\n return new Date(ms);\n}\n\nfunction roundHalfUp(value: number, places: number): number {\n if (!Number.isFinite(value)) return value;\n // HALF_UP rounding: tie-breaks always round away from zero for positives,\n // toward +∞ for negatives. JS `Math.round` rounds half toward +∞, which\n // disagrees with HALF_UP on negative .5 boundaries; replicate the Python\n // Decimal behavior by adjusting positives only and mirroring negatives.\n const scale = 10 ** places;\n const sign = value < 0 ? -1 : 1;\n const abs = Math.abs(value);\n // Add a tiny epsilon scaled to the magnitude to defeat IEEE-754 errors that\n // make `2.675 * 100` come out as `267.49999...`. The epsilon is small\n // enough (relative-1e-12) not to affect legitimate non-tie values.\n const rounded = Math.floor(abs * scale + 0.5 + abs * 1e-12) / scale;\n return sign * rounded;\n}\n\nfunction cToF(c: number): number {\n return c * 1.8 + 32;\n}\n\n/**\n * Roll up observation rows to per-local-calendar-day temperature extremes.\n *\n * @param rows raw observation rows (any source). Rows without a parseable\n * `observed_at` are dropped.\n * @param opts `stationTz` is required. Optional `precision` (default 0;\n * pass 1 for US-station tenths) and `minObs` (default 12).\n *\n * @returns one entry per local calendar day with at least one row. Days\n * with fewer than `minObs` rows have temps set to null.\n */\nexport function internationalDailyExtremes(\n rows: ReadonlyArray<InternationalRow>,\n opts: InternationalDailyExtremesOptions,\n): DailyExtreme[] {\n const tz = opts.stationTz;\n if (typeof tz !== \"string\" || tz.length === 0) {\n throw new RangeError(\"internationalDailyExtremes: stationTz is required (non-empty string)\");\n }\n // Phase 18: integer-°F lattice rationale.\n // For US stations (ASOS), constituent observations carry temp_c values\n // recovered from Tgroup tenths-°C (e.g. 10.0, 11.1, 12.2 from integer °F\n // 50, 52, 54 — Phase 18 PREC-01/PREC-02). tmin/tmax = min/max of those\n // values are themselves on the integer-°F lattice, and 0.1°C HALF_UP\n // rounding is a no-op. tmean IS a non-lattice average and benefits from\n // 0.1°C rounding. For international stations (no Tgroup), constituent\n // values are derived floats and rounding to whole °C (`precision = 0`) is\n // the convention.\n //\n // Callers pass `precision: 1` for US ASOS data and `precision: 0` (the\n // default) for international. See\n // .planning/phases/18-precision-fix-asos-integer-fahrenheit/18-CONTEXT.md.\n const precision = opts.precision ?? 0;\n const minObs = opts.minObs ?? LOW_COVERAGE_THRESHOLD;\n\n // Validate tz up front so we get a clean error rather than per-row failures.\n try {\n getDateFormatter(tz);\n } catch (e) {\n throw new RangeError(\n `internationalDailyExtremes: invalid stationTz ${JSON.stringify(tz)}: ${(e as Error).message}`,\n );\n }\n\n type Bucket = {\n temps: { value: number; source: string | null }[];\n precipMm: number;\n };\n const byLocalDate = new Map<string, Bucket>();\n\n for (const row of rows) {\n const instant = parseInstant(row.observed_at);\n if (instant === null) continue;\n const localDate = localDateFor(instant, tz);\n let bucket = byLocalDate.get(localDate);\n if (bucket === undefined) {\n bucket = { temps: [], precipMm: 0 };\n byLocalDate.set(localDate, bucket);\n }\n const t = row.temp_c;\n if (typeof t === \"number\" && Number.isFinite(t)) {\n bucket.temps.push({ value: t, source: row.source ?? null });\n }\n const p = row.precip_mm_1h;\n if (typeof p === \"number\" && Number.isFinite(p)) {\n bucket.precipMm += p;\n }\n }\n\n const out: DailyExtreme[] = [];\n const sortedDates = [...byLocalDate.keys()].sort();\n for (const localDate of sortedDates) {\n const bucket = byLocalDate.get(localDate);\n if (bucket === undefined) continue;\n const nObs = bucket.temps.length;\n let tempMinC: number | null = null;\n let tempMaxC: number | null = null;\n let tempMeanC: number | null = null;\n let sourceTmin: string | null = null;\n let sourceTmax: string | null = null;\n\n // Codex iter-4 P2: `nObs >= minObs` alone is not enough when minObs=0,\n // because a day with a parseable timestamp but no finite temp_c reaches\n // this branch with nObs === 0 and then dereferences bucket.temps[0].\n // Always require at least one temperature row before computing extremes.\n if (nObs > 0 && nObs >= minObs) {\n let minIdx = 0;\n let maxIdx = 0;\n let sum = 0;\n for (let i = 0; i < bucket.temps.length; i += 1) {\n const v = bucket.temps[i] as { value: number; source: string | null };\n sum += v.value;\n const minRow = bucket.temps[minIdx] as { value: number };\n const maxRow = bucket.temps[maxIdx] as { value: number };\n if (v.value < minRow.value) minIdx = i;\n if (v.value > maxRow.value) maxIdx = i;\n }\n const mean = sum / nObs;\n const minRow = bucket.temps[minIdx] as { value: number; source: string | null };\n const maxRow = bucket.temps[maxIdx] as { value: number; source: string | null };\n tempMinC = roundHalfUp(minRow.value, precision);\n tempMaxC = roundHalfUp(maxRow.value, precision);\n tempMeanC = roundHalfUp(mean, precision);\n sourceTmin = minRow.source;\n sourceTmax = maxRow.source;\n }\n\n out.push(\n Object.freeze({\n localDate,\n nObs,\n tempMinC,\n tempMaxC,\n tempMeanC,\n tempMinF: tempMinC === null ? null : roundHalfUp(cToF(tempMinC), precision),\n tempMaxF: tempMaxC === null ? null : roundHalfUp(cToF(tempMaxC), precision),\n precipMm: roundHalfUp(bucket.precipMm, 4),\n sourceTmin,\n sourceTmax,\n }),\n );\n }\n\n return out;\n}\n","// Structured exception hierarchy for the mostlyright TS SDK.\n//\n// Mirrors the Python design in `packages/core/src/mostlyright/core/exceptions.py`\n// and `packages/core/src/mostlyright/_internal/exceptions.py`. Every error\n// subclasses `MostlyRightError` and exposes a `toDict()` method that returns a\n// JSON-safe payload suitable for MCP `error.data` / extension messaging.\n//\n// Role-name vocabulary for SourceMismatchError matches Python:\n// \"observations\" / \"forecasts\" / \"settlement\" (long form, NOT the col prefixes)\n\n// ---------------------------------------------------------------------------\n// JSON-safe coercion (mirrors `mostlyright.core._json_safe.to_json_safe`)\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively coerce `value` into a JSON-serializable structure.\n *\n * Coercion rules (mirrors Python's `to_json_safe`):\n * - `null` / `undefined` / `NaN` / `Infinity` / `-Infinity` → `null`\n * - `Date` → ISO 8601 UTC string ending in `Z`\n * - Numeric / boolean / string scalars pass through (non-finite numbers → null)\n * - Arrays + plain objects → recursive (cycles → `{ _cycle: true, value: String(obj) }`)\n * - Dict keys MUST be strings; non-string keys throw `TypeError`.\n * - Anything else (Symbol, function, class instance without `toJSON`) →\n * `{ _repr_only: true, value: String(value) }`.\n */\nexport function toJsonSafe(value: unknown, seen?: WeakSet<object>): unknown {\n const visited = seen ?? new WeakSet<object>();\n\n // null / undefined → null\n if (value === null || value === undefined) {\n return null;\n }\n\n // Booleans pass through.\n if (typeof value === \"boolean\") {\n return value;\n }\n\n // Strings pass through.\n if (typeof value === \"string\") {\n return value;\n }\n\n // Numbers — non-finite (NaN, +/-Infinity) coerce to null.\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n\n // bigint → number when safe, else stringify (JSON can't natively encode bigint).\n if (typeof value === \"bigint\") {\n // Match Python: integers pass through as native numeric. Safe-range only.\n if (value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER)) {\n return Number(value);\n }\n return { _repr_only: true, value: value.toString() };\n }\n\n // Date → ISO 8601 UTC string (always ending in \"Z\").\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n return null;\n }\n return value.toISOString();\n }\n\n // Arrays — recurse, track cycles.\n if (Array.isArray(value)) {\n if (visited.has(value)) {\n return { _cycle: true, value: String(value) };\n }\n visited.add(value);\n try {\n return value.map((item) => toJsonSafe(item, visited));\n } finally {\n visited.delete(value);\n }\n }\n\n // Plain objects — recurse, track cycles, enforce string keys.\n if (typeof value === \"object\") {\n if (visited.has(value as object)) {\n return { _cycle: true, value: String(value) };\n }\n visited.add(value as object);\n try {\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value as Record<string, unknown>)) {\n if (typeof key !== \"string\") {\n throw new TypeError(`toJsonSafe dict keys must be string; got ${typeof key}`);\n }\n out[key] = toJsonSafe((value as Record<string, unknown>)[key], visited);\n }\n return out;\n } finally {\n visited.delete(value as object);\n }\n }\n\n // Symbols, functions, etc. — repr-only marker.\n return { _repr_only: true, value: String(value) };\n}\n\n// ---------------------------------------------------------------------------\n// Base class\n// ---------------------------------------------------------------------------\n\nexport interface MostlyRightErrorOptions {\n errorCode?: string;\n source?: string | null;\n requestId?: string | null;\n}\n\n/**\n * Base class for all mostlyright structured errors.\n *\n * `errorCode` is a stable enum (e.g. \"SOURCE_UNAVAILABLE\") used by callers /\n * agents to branch on without parsing message text. `source` is the source id\n * involved (e.g. \"iem.archive\") when applicable, and `requestId` correlates a\n * JSON-RPC / MCP request id when applicable.\n */\nexport class MostlyRightError extends Error {\n /** Subclass override — the stable string enum surfaced via `errorCode`. */\n static defaultErrorCode = \"MOSTLYRIGHT_ERROR\";\n\n readonly errorCode: string;\n readonly source: string | null;\n readonly requestId: string | null;\n\n constructor(message = \"\", options: MostlyRightErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n const ctor = this.constructor as typeof MostlyRightError;\n this.errorCode = options.errorCode ?? ctor.defaultErrorCode;\n this.source = options.source ?? null;\n this.requestId = options.requestId ?? null;\n // Restore prototype chain after `Error` (needed for `instanceof` across\n // transpilation / ES5 targets).\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * Subclass hook returning the structured attributes for `toDict`.\n * Values are passed through `toJsonSafe` by `toDict()`, so subclasses\n * don't need to coerce values themselves.\n */\n protected payload(): Record<string, unknown> {\n return {\n error_code: this.errorCode,\n message: this.message,\n source: this.source,\n request_id: this.requestId,\n };\n }\n\n /** Return a JSON-safe dict suitable for MCP `error.data`. */\n toDict(): Record<string, unknown> {\n const safe = toJsonSafe(this.payload());\n return safe as Record<string, unknown>;\n }\n}\n\n// ---------------------------------------------------------------------------\n// SourceUnavailableError\n// ---------------------------------------------------------------------------\n\nexport interface SourceUnavailableErrorOptions extends MostlyRightErrorOptions {\n httpStatus?: number | null;\n retryable?: boolean;\n retryAfterS?: number | null;\n underlying?: string;\n url?: string | null;\n}\n\nexport class SourceUnavailableError extends MostlyRightError {\n static override defaultErrorCode = \"SOURCE_UNAVAILABLE\";\n\n readonly httpStatus: number | null;\n readonly retryable: boolean;\n readonly retryAfterS: number | null;\n readonly underlying: string;\n readonly url: string | null;\n\n constructor(message = \"\", options: SourceUnavailableErrorOptions = {}) {\n super(message, options);\n this.httpStatus = options.httpStatus ?? null;\n this.retryable = options.retryable ?? false;\n this.retryAfterS = options.retryAfterS ?? null;\n this.underlying = options.underlying ?? \"\";\n this.url = options.url ?? null;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n http_status: this.httpStatus,\n retryable: this.retryable,\n retry_after_s: this.retryAfterS,\n underlying: this.underlying,\n url: this.url,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// DataAvailabilityError (Phase 21 21-09)\n// ---------------------------------------------------------------------------\n//\n// Typed exception for \"I tried to fetch and got nothing usable\" — replaces\n// 3+ overloaded SourceUnavailableError sites where consumers had to parse\n// message strings to differentiate (rate-limit retry vs model-unavailable\n// hard-fail vs cache-miss re-fetch). The reason enum is shared lockstep\n// with Python (`mostlyright.core.exceptions.DataAvailabilityError`); drift\n// is the load-bearing risk.\n\n/** Shared reason enum — MUST match Python EXACTLY (Phase 21 D-04). */\nexport const DATA_AVAILABILITY_REASONS = [\n \"model_unavailable\",\n \"out_of_window\",\n \"cache_miss\",\n \"source_404\",\n \"source_5xx\",\n \"rate_limited\",\n] as const;\n\nexport type DataAvailabilityReason = (typeof DATA_AVAILABILITY_REASONS)[number];\n\nexport interface DataAvailabilityErrorOptions extends MostlyRightErrorOptions {\n reason: DataAvailabilityReason;\n hint: string;\n}\n\nexport class DataAvailabilityError extends MostlyRightError {\n static override defaultErrorCode = \"DATA_AVAILABILITY\";\n\n readonly reason: DataAvailabilityReason;\n readonly hint: string;\n\n constructor(options: DataAvailabilityErrorOptions) {\n if (!DATA_AVAILABILITY_REASONS.includes(options.reason)) {\n throw new RangeError(\n `DataAvailabilityError: unknown reason \"${String(options.reason)}\". ` +\n `Valid reasons: ${DATA_AVAILABILITY_REASONS.join(\", \")}`,\n );\n }\n if (typeof options.hint !== \"string\" || options.hint.length === 0) {\n throw new TypeError(\"DataAvailabilityError: hint is required and must be a non-empty string\");\n }\n const message = `[${options.reason}] ${options.hint}`;\n super(message, options);\n this.reason = options.reason;\n this.hint = options.hint;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n reason: this.reason,\n hint: this.hint,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// NwpNotAvailableError (Post-21-07 follow-up)\n// ---------------------------------------------------------------------------\n//\n// Subclass of DataAvailabilityError raised when the TS `forecastNwp()` stub\n// is called. Phase 21 21-07 routes the generic stub error through\n// DataAvailabilityError; this dedicated subclass adds:\n//\n// 1. instanceof-based dispatch — `catch (e) { if (e instanceof\n// NwpNotAvailableError) ... }` is cleaner than `e.reason ===\n// \"model_unavailable\" && e.source === \"nwp-stub\"`.\n// 2. IDE autocomplete on `.model` + `.station` — narrows the payload so\n// consumers don't have to parse `e.hint` to retrieve them.\n// 3. A typed compile-time signal: `forecastNwp()` returns\n// `Promise<never>`, but the throw site declares `@throws\n// NwpNotAvailableError` so JSDoc tooling surfaces the deferral up-front.\n//\n// Back-compat: NwpNotAvailableError IS-A DataAvailabilityError with\n// reason=\"model_unavailable\", so existing `catch (e) { if (e instanceof\n// DataAvailabilityError && e.reason === \"model_unavailable\") ... }` paths\n// continue to work unchanged.\n\nexport interface NwpNotAvailableErrorOptions extends MostlyRightErrorOptions {\n /** Station the caller asked for (echoed back for log/error attribution). */\n station: string;\n /** NWP model the caller asked for (e.g. `\"gfs\"`, `\"hrrr\"`). */\n model: string;\n /** Operator-actionable hint. Required (matches DataAvailabilityError contract). */\n hint: string;\n}\n\n/**\n * Raised when the TS `forecastNwp()` stub is called.\n *\n * **Why this exists:** no production-ready browser GRIB2 decoder ships in\n * v1.x (eccodes / cfgrib are C/Python only; WASM compile-time + bundle\n * size make a browser port impractical today). The function signature is\n * stable so callers can write code today; v2.0+ lands the execution body.\n *\n * **Recommended catch pattern:**\n *\n * ```ts\n * import { forecastNwp } from '@mostlyrightmd/weather';\n * import { NwpNotAvailableError } from '@mostlyrightmd/core';\n *\n * try {\n * const grid = await forecastNwp('KNYC', 'gfs');\n * } catch (e) {\n * if (e instanceof NwpNotAvailableError) {\n * console.warn(`NWP deferred to v2.0+; ${e.hint}`);\n * // Fall back to iemMosForecasts() when available, else Python SDK.\n * } else {\n * throw e;\n * }\n * }\n * ```\n *\n * See [docs/nwp-forecasts.md](https://mostlyright.md/docs/sdk/typescript/nwp-forecasts/)\n * for the full architectural rationale and the v2.0+ roadmap.\n */\nexport class NwpNotAvailableError extends DataAvailabilityError {\n static override defaultErrorCode = \"NWP_NOT_AVAILABLE\";\n\n readonly station: string;\n readonly model: string;\n\n constructor(options: NwpNotAvailableErrorOptions) {\n // exactOptionalPropertyTypes: true — only include requestId when the\n // caller passed a non-undefined value. Passing `requestId: undefined`\n // explicitly would type-error against the parent's narrower contract.\n const parentOpts: DataAvailabilityErrorOptions = {\n reason: \"model_unavailable\",\n hint: options.hint,\n source: options.source ?? `nwp.${options.model}`,\n };\n if (options.requestId !== undefined && options.requestId !== null) {\n parentOpts.requestId = options.requestId;\n }\n super(parentOpts);\n this.station = options.station;\n this.model = options.model;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n station: this.station,\n model: this.model,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// SchemaValidationError\n// ---------------------------------------------------------------------------\n\nexport interface SchemaValidationErrorOptions extends MostlyRightErrorOptions {\n schemaId: string;\n violations?: Array<Record<string, unknown>>;\n quarantineCount?: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\nexport class SchemaValidationError extends MostlyRightError {\n static override defaultErrorCode = \"SCHEMA_VALIDATION_FAILED\";\n\n readonly schemaId: string;\n readonly violations: Array<Record<string, unknown>>;\n readonly quarantineCount: number;\n readonly sampleViolations: Array<Record<string, unknown>>;\n\n constructor(message: string, options: SchemaValidationErrorOptions) {\n super(message, options);\n this.schemaId = options.schemaId;\n this.violations = [...(options.violations ?? [])];\n this.quarantineCount = options.quarantineCount ?? 0;\n this.sampleViolations = [...(options.sampleViolations ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n schema_id: this.schemaId,\n violations: this.violations,\n quarantine_count: this.quarantineCount,\n sample_violations: this.sampleViolations,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// SourceMismatchError\n// ---------------------------------------------------------------------------\n\nexport type SourceMismatchRole = \"observations\" | \"forecasts\" | \"settlement\";\n\nexport interface SourceMismatchErrorOptions extends MostlyRightErrorOptions {\n schemaSource: string;\n dataSource: string;\n role?: SourceMismatchRole | null;\n catalogWarning?: string | null;\n}\n\nexport class SourceMismatchError extends MostlyRightError {\n static override defaultErrorCode = \"SOURCE_MISMATCH\";\n\n /** Canonical role-name vocabulary (design.md §R). */\n static readonly VALID_ROLES: ReadonlySet<SourceMismatchRole> = new Set([\n \"observations\",\n \"forecasts\",\n \"settlement\",\n ]);\n\n readonly schemaSource: string;\n readonly dataSource: string;\n readonly role: SourceMismatchRole | null;\n readonly catalogWarning: string | null;\n\n constructor(message: string, options: SourceMismatchErrorOptions) {\n super(message, options);\n this.schemaSource = options.schemaSource;\n this.dataSource = options.dataSource;\n this.role = options.role ?? null;\n this.catalogWarning = options.catalogWarning ?? null;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n schema_source: this.schemaSource,\n data_source: this.dataSource,\n role: this.role,\n catalog_warning: this.catalogWarning,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// LeakageError\n// ---------------------------------------------------------------------------\n\nexport interface LeakageErrorOptions extends MostlyRightErrorOptions {\n asOf: string;\n violatingCount: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\nexport class LeakageError extends MostlyRightError {\n static override defaultErrorCode = \"LEAKAGE_DETECTED\";\n\n readonly asOf: string;\n readonly violatingCount: number;\n readonly sampleViolations: Array<Record<string, unknown>>;\n\n constructor(message: string, options: LeakageErrorOptions) {\n super(message, options);\n this.asOf = options.asOf;\n this.violatingCount = options.violatingCount;\n this.sampleViolations = [...(options.sampleViolations ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n as_of: this.asOf,\n violating_count: this.violatingCount,\n sample_violations: this.sampleViolations,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// IssuedAtMissingError (Phase 20 OM-04)\n// ---------------------------------------------------------------------------\n\nexport interface IssuedAtMissingErrorOptions extends MostlyRightErrorOptions {\n violatingCount?: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\n/**\n * A forecast row would land with `issuedAt = null`.\n *\n * Phase 20 OM-04. Origin: Tarabcak/mostlyright#70 — the legacy\n * seamless-feed bug where `/forecast_series` proxied Open-Meteo's\n * seamless endpoint without preserving `issued_at`, silently using\n * post-snapshot model runs in training data.\n */\nexport class IssuedAtMissingError extends SchemaValidationError {\n static override defaultErrorCode = \"ISSUED_AT_MISSING\";\n\n readonly violatingCountRows: number;\n\n constructor(message: string, options: IssuedAtMissingErrorOptions = {}) {\n super(message, {\n ...options,\n schemaId: \"schema.forecast.station.v1\",\n violations: [{ column: \"issued_at\", rule: \"non_null\" }],\n });\n this.violatingCountRows = options.violatingCount ?? 0;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n name: \"IssuedAtMissingError\",\n violating_count: this.violatingCountRows,\n origin_issue: \"Tarabcak/mostlyright#70\",\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// OpenMeteoSeamlessLeakageError (Phase 20 OM-04)\n// ---------------------------------------------------------------------------\n\nexport interface OpenMeteoSeamlessLeakageErrorOptions extends MostlyRightErrorOptions {\n model: string;\n endpointUrl: string;\n asOf?: string | null;\n}\n\n/**\n * The Open-Meteo Historical Forecast (seamless) endpoint was used\n * without `allowLeakage: true`.\n *\n * Phase 20 D-01 (locked decision): the seamless endpoint silently\n * stitches forecasts from multiple model cycles into a continuous\n * timeseries; the cycle that produced each value is unrecoverable from\n * the response. `LeakageDetector` rejects rows tagged\n * `source=\"open_meteo.seamless\"` whenever `as_of` is asserted.\n *\n * Origin: Tarabcak/mostlyright#70.\n */\nexport class OpenMeteoSeamlessLeakageError extends LeakageError {\n static override defaultErrorCode = \"OPEN_METEO_SEAMLESS_LEAKAGE\";\n\n readonly model: string;\n readonly endpointUrl: string;\n\n constructor(message: string, options: OpenMeteoSeamlessLeakageErrorOptions) {\n super(message, {\n ...options,\n asOf: options.asOf ?? \"(seamless-endpoint-refused-before-fetch)\",\n violatingCount: 0,\n });\n this.model = options.model;\n this.endpointUrl = options.endpointUrl;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n name: \"OpenMeteoSeamlessLeakageError\",\n model: this.model,\n endpoint_url: this.endpointUrl,\n origin_issue: \"Tarabcak/mostlyright#70\",\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// TemporalDriftError\n// ---------------------------------------------------------------------------\n\nexport interface TemporalDriftErrorOptions extends MostlyRightErrorOptions {\n schemaId: string;\n assertedRange: [string, string];\n violatingRows: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\nexport class TemporalDriftError extends MostlyRightError {\n static override defaultErrorCode = \"TEMPORAL_DRIFT\";\n\n readonly schemaId: string;\n readonly assertedRange: [string, string];\n readonly violatingRows: number;\n readonly sampleViolations: Array<Record<string, unknown>>;\n\n constructor(message: string, options: TemporalDriftErrorOptions) {\n super(message, options);\n this.schemaId = options.schemaId;\n this.assertedRange = [options.assertedRange[0], options.assertedRange[1]];\n this.violatingRows = options.violatingRows;\n this.sampleViolations = [...(options.sampleViolations ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n schema_id: this.schemaId,\n asserted_range: [this.assertedRange[0], this.assertedRange[1]],\n violating_rows: this.violatingRows,\n sample_violations: this.sampleViolations,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// PayloadTooLargeError\n// ---------------------------------------------------------------------------\n\nexport interface PayloadTooLargeErrorOptions extends MostlyRightErrorOptions {\n declaredSize: number;\n limit: number;\n acceptedModes?: string[];\n}\n\nexport class PayloadTooLargeError extends MostlyRightError {\n static override defaultErrorCode = \"PAYLOAD_TOO_LARGE\";\n\n readonly declaredSize: number;\n readonly limit: number;\n readonly acceptedModes: string[];\n\n constructor(message: string, options: PayloadTooLargeErrorOptions) {\n super(message, options);\n this.declaredSize = options.declaredSize;\n this.limit = options.limit;\n this.acceptedModes = [...(options.acceptedModes ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n declared_size: this.declaredSize,\n limit: this.limit,\n accepted_modes: this.acceptedModes,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// DeferredMarketError (TS-W6 placeholder; mirrors mostlyright.international)\n// ---------------------------------------------------------------------------\n\nexport class DeferredMarketError extends MostlyRightError {\n static override defaultErrorCode = \"DEFERRED_MARKET\";\n}\n\n// ---------------------------------------------------------------------------\n// PolymarketEventError (TS-W5 placeholder; mirrors mostlyright.markets.polymarket)\n// ---------------------------------------------------------------------------\n\nexport class PolymarketEventError extends MostlyRightError {\n static override defaultErrorCode = \"POLYMARKET_EVENT_INVALID\";\n}\n\n// ---------------------------------------------------------------------------\n// HTTP-layer hierarchy (mirrors mostlyright._internal.exceptions)\n// ---------------------------------------------------------------------------\n\nexport interface TherminalErrorOptions extends MostlyRightErrorOptions {\n statusCode?: number | null;\n retryAfter?: number | null;\n}\n\n/**\n * Base HTTP-layer marker. Subclass of `MostlyRightError` so callers that\n * catch `MostlyRightError` also catch transport errors.\n */\nexport class TherminalError extends MostlyRightError {\n static override defaultErrorCode = \"HTTP_ERROR\";\n\n readonly statusCode: number | null;\n\n constructor(message: string, options: TherminalErrorOptions = {}) {\n super(message, options);\n this.statusCode = options.statusCode ?? null;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n status_code: this.statusCode,\n };\n }\n}\n\nexport class NotFoundError extends TherminalError {\n static override defaultErrorCode = \"HTTP_NOT_FOUND\";\n\n constructor(message = \"Resource not found\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 404 });\n }\n}\n\nexport interface RateLimitErrorOptions extends TherminalErrorOptions {\n retryAfter?: number | null;\n}\n\nexport class RateLimitError extends TherminalError {\n static override defaultErrorCode = \"HTTP_RATE_LIMITED\";\n\n readonly retryAfter: number | null;\n\n constructor(retryAfter: number | null = 1, options: RateLimitErrorOptions = {}) {\n const msg = `Rate limit exceeded. Retry after ${retryAfter ?? \"?\"}s`;\n super(msg, { ...options, statusCode: options.statusCode ?? 429 });\n this.retryAfter = retryAfter;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n retry_after: this.retryAfter,\n };\n }\n}\n\nexport class ValidationError extends TherminalError {\n static override defaultErrorCode = \"HTTP_BAD_REQUEST\";\n\n constructor(message = \"Invalid request\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 400 });\n }\n}\n\nexport class AuthenticationError extends TherminalError {\n static override defaultErrorCode = \"HTTP_UNAUTHORIZED\";\n\n constructor(message = \"Authentication required\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 401 });\n }\n}\n\nexport class ForbiddenError extends TherminalError {\n static override defaultErrorCode = \"HTTP_FORBIDDEN\";\n\n constructor(message = \"Access denied\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 403 });\n }\n}\n\nexport class ServerError extends TherminalError {\n static override defaultErrorCode = \"HTTP_SERVER_ERROR\";\n\n constructor(message = \"Server error\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 500 });\n }\n}\n\n// ---------------------------------------------------------------------------\n// LiveStreamError + NoLiveDataError (Phase 11)\n// ---------------------------------------------------------------------------\n\n/**\n * Base class for `mostlyright.live.stream` / `live.latest` failures.\n *\n * Mirrors Python `LiveStreamError`. Live-streaming errors are a separate\n * sub-tree from `SourceUnavailableError` because the recovery path differs —\n * `stream()` swallows empty-tick errors and waits for the next polite-floor\n * cycle. Only `latest()` raises `NoLiveDataError` on empty responses.\n */\nexport class LiveStreamError extends MostlyRightError {\n static override defaultErrorCode = \"LIVE_STREAM_ERROR\";\n}\n\nexport interface NoLiveDataErrorOptions extends MostlyRightErrorOptions {\n station: string;\n source: string;\n}\n\n/**\n * `mostlyright.live.latest` returned no observations for the station.\n *\n * Carries the resolved ICAO `station` and the canonical source identity\n * tag (`\"awc.live\"` / `\"iem.live\"`) so caller logs can branch by source\n * without re-parsing the message.\n */\nexport class NoLiveDataError extends LiveStreamError {\n static override defaultErrorCode = \"NO_LIVE_DATA\";\n\n readonly station: string;\n\n constructor(message: string, options: NoLiveDataErrorOptions) {\n super(message, { ...options, source: options.source });\n this.station = options.station;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n station: this.station,\n };\n }\n}\n","// TOON v3.0 tabular format — byte-equivalent to Python `encode_tabular`.\n//\n// Ports the encoder portions of\n// `packages/core/src/mostlyright/core/formats/_toon.py` and the tabular\n// loader from `packages/core/src/mostlyright/core/formats/toon.py`.\n//\n// Wire shape (single tabular block):\n//\n// rows[N]{col1,col2,col3}:\n// v1a,v2a,v3a\n// v1b,v2b,v3b\n//\n// Where N is the row count, `{...}` is the column list, each subsequent line\n// is one row's values. Column order comes from the first row's keys.\n//\n// TOON loss matrix (matches Python `toon.py`):\n// - dict/object cells stringify deterministically via canonical JSON\n// (sorted keys + JSON.stringify of nested values).\n// - null + undefined both encode as the bare literal `null`.\n// - NaN / +Infinity / -Infinity encode as `null` (per `_format_number`).\n// - Integer-valued floats serialize without a fractional part (1.0 → \"1\").\n// - Strings that look numeric, start with - / + / digit, are\n// `true`/`false`/`null`, or contain commas/quotes/control chars are\n// quoted. Otherwise emitted bare.\n\n// ---------------------------------------------------------------------------\n// Encoder regex set (mirrors Python `_toon.py`)\n// ---------------------------------------------------------------------------\n\nconst SAFE_KEY_RE = /^[A-Za-z_][A-Za-z0-9_.]*$/;\nconst NUMERIC_LIKE_RE = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n// Quote triggers per TOON spec: colon, quote, backslash, brackets, braces,\n// ASCII control chars, NEL, LSEP, PSEP. Constructed via RegExp(...) to avoid\n// embedding literal LSEP/PSEP bytes (esbuild rejects those in regex literals).\n// biome-ignore lint/suspicious/noControlCharactersInRegex: TOON spec parity\nconst NEEDS_QUOTE_CHARS_RE = /[:\\\\\\\"'\\[\\]{}\\x00-\\x1f\\x7f\\x85\\u2028\\u2029]/;\n// Control chars without a defined TOON escape — stripped on quote.\n// biome-ignore lint/suspicious/noControlCharactersInRegex: TOON spec parity\nconst UNSUPPORTED_CTRL_RE = /[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f\\x85\\u2028\\u2029]/g;\n\n// ---------------------------------------------------------------------------\n// Scalar encoding\n// ---------------------------------------------------------------------------\n\nfunction formatNumber(n: number): string {\n if (!Number.isFinite(n)) return \"null\";\n if (n === 0) return \"0\"; // collapses -0 to \"0\"\n if (Number.isInteger(n) && Math.abs(n) <= 2 ** 53) return String(n);\n let s = String(n);\n // Expand scientific notation to plain decimal. Python uses Decimal —\n // we use toFixed where possible, falling back to toPrecision-based logic.\n if (/[eE]/.test(s)) {\n // toFixed/toPrecision don't fully match Python's Decimal expansion at\n // extreme values, but for the values realistically in weather data\n // (temperatures, lat/lng) String(n) returns plain decimal already.\n // For extreme cases, fall back to a manual expansion.\n s = expandExponent(s);\n }\n return s;\n}\n\nfunction expandExponent(s: string): string {\n const m = /^(-?)(\\d+(?:\\.\\d+)?)[eE]([+-]?\\d+)$/.exec(s);\n if (!m) return s;\n const sign = m[1] ?? \"\";\n const mantissa = m[2] ?? \"\";\n const exp = Number(m[3]);\n const [intPart, fracPart = \"\"] = mantissa.split(\".\");\n const digits = (intPart ?? \"\") + fracPart;\n const pointPos = (intPart ?? \"\").length + exp;\n let out: string;\n if (pointPos <= 0) {\n out = `0.${\"0\".repeat(-pointPos)}${digits}`.replace(/0+$/, \"\");\n if (out.endsWith(\".\")) out = out.slice(0, -1);\n } else if (pointPos >= digits.length) {\n out = digits + \"0\".repeat(pointPos - digits.length);\n } else {\n out = `${digits.slice(0, pointPos)}.${digits.slice(pointPos)}`.replace(/0+$/, \"\");\n if (out.endsWith(\".\")) out = out.slice(0, -1);\n }\n return sign + out;\n}\n\nfunction needsQuoting(s: string, delimiter: string): boolean {\n if (s.length === 0) return true;\n const first = s.charAt(0);\n const last = s.charAt(s.length - 1);\n if (first === \" \" || first === \"\\t\") return true;\n if (last === \" \" || last === \"\\t\") return true;\n if (s === \"true\" || s === \"false\" || s === \"null\") return true;\n if (first === \"-\" || first === \"+\") return true;\n if (first >= \"0\" && first <= \"9\") return true;\n if (NUMERIC_LIKE_RE.test(s)) return true;\n if (s.includes(delimiter)) return true;\n if (NEEDS_QUOTE_CHARS_RE.test(s)) return true;\n return false;\n}\n\nfunction quoteString(s: string): string {\n // Strip unsupported control chars first (matches Python — no escape\n // sequence exists for them).\n let out = s.replace(UNSUPPORTED_CTRL_RE, \"\");\n out = out.replace(/\\\\/g, \"\\\\\\\\\");\n out = out.replace(/\"/g, '\\\\\"');\n out = out.replace(/\\n/g, \"\\\\n\");\n out = out.replace(/\\r/g, \"\\\\r\");\n out = out.replace(/\\t/g, \"\\\\t\");\n return `\"${out}\"`;\n}\n\nfunction formatKey(key: string): string {\n if (typeof key !== \"string\") {\n throw new TypeError(`TOON keys must be strings; got ${typeof key}`);\n }\n if (SAFE_KEY_RE.test(key)) return key;\n return quoteString(key);\n}\n\nfunction encodeScalar(value: unknown, delimiter: string): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"number\") return formatNumber(value);\n if (typeof value === \"string\") {\n if (needsQuoting(value, delimiter)) return quoteString(value);\n return value;\n }\n // Objects / arrays / etc. — canonical JSON (sorted keys) for parity with\n // Python `_coerce_cell` dict-handling, otherwise String(value).\n if (typeof value === \"object\") {\n if (Array.isArray(value)) {\n return quoteString(JSON.stringify(value));\n }\n // Sorted-key JSON for determinism (matches Python json.dumps sort_keys).\n const sorted = sortedJson(value as Record<string, unknown>);\n return quoteString(sorted);\n }\n return quoteString(String(value));\n}\n\nfunction sortedJson(obj: Record<string, unknown>): string {\n const keys = Object.keys(obj).sort();\n const parts = keys.map((k) => `${JSON.stringify(k)}:${JSON.stringify(obj[k])}`);\n return `{${parts.join(\",\")}}`;\n}\n\n// ---------------------------------------------------------------------------\n// Tabular validation (mirrors Python `_is_tabular`)\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when {@link toonDumps} receives rows that aren't valid tabular\n * input. Mirrors the Python `encode_tabular` `ValueError` — the encoder\n * MUST refuse non-uniform rows or non-primitive values rather than\n * silently dropping columns or stringifying nested structures.\n *\n * Iter-1 C3: the previous TS encoder used `Object.keys(rows[0])` and\n * encoded every subsequent row through that column list — meaning rows\n * with extra keys had them dropped, rows missing a first-row key got a\n * silent `null`, and rows with object/array values stringified via\n * `JSON.stringify` (also silent). All three are data corruption when the\n * caller didn't realize their rows weren't uniform.\n */\nexport class ToonTabularError extends RangeError {\n override name = \"ToonTabularError\";\n}\n\nfunction isToonPrimitive(v: unknown): boolean {\n // Python `_is_tabular` accepts None / str / int / float / bool. The TS\n // analog: null/undefined (both encode as `null`), string, finite or\n // non-finite number (NaN/Inf encode as `null` via formatNumber),\n // boolean. Anything else (object, array, function, symbol, bigint) is\n // non-tabular.\n if (v === null || v === undefined) return true;\n const t = typeof v;\n return t === \"string\" || t === \"number\" || t === \"boolean\";\n}\n\nfunction assertTabular(rows: ReadonlyArray<Record<string, unknown>>): void {\n if (rows.length === 0) return;\n const first = rows[0] as Record<string, unknown>;\n const expectedKeys = Object.keys(first);\n if (expectedKeys.length === 0) {\n throw new ToonTabularError(\n \"toonDumps requires non-empty rows; first row has no keys (Python parity: encode_tabular rejects empty key set)\",\n );\n }\n const expectedKeySet = new Set(expectedKeys);\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i] as Record<string, unknown>;\n const rowKeys = Object.keys(row);\n // (a) Key-set equality. Python compares `set(item.keys()) != key_set`.\n if (rowKeys.length !== expectedKeySet.size) {\n throw new ToonTabularError(\n `toonDumps requires uniform rows; row ${i} has ${rowKeys.length} key(s) vs row 0's ${expectedKeySet.size}. Python encode_tabular rejects rows whose key sets differ.`,\n );\n }\n for (const k of rowKeys) {\n if (!expectedKeySet.has(k)) {\n throw new ToonTabularError(\n `toonDumps requires uniform rows; row ${i} has key ${JSON.stringify(k)} not present in row 0. Python encode_tabular rejects rows whose key sets differ.`,\n );\n }\n }\n // (b) Value primitivity. Python check: `v is None or isinstance(v, str|int|float|bool)`.\n for (const k of expectedKeys) {\n const v = row[k];\n if (!isToonPrimitive(v)) {\n throw new ToonTabularError(\n `toonDumps requires primitive cell values; row ${i} column ${JSON.stringify(k)} has non-primitive value of type ${typeof v}. Python encode_tabular rejects nested objects/arrays at the cell level.`,\n );\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public encoder\n// ---------------------------------------------------------------------------\n\n/**\n * Encode rows as a TOON v3.0 tabular block.\n *\n * Header is `rows[N]{c1,c2,...}:`; data lines are 2-space indented and\n * comma-separated. Empty rows emits `rows[0]:` (header-only, no columns\n * region; matches Python `_encode_array_field` empty-list path).\n *\n * Note: empty-row encoding differs from `dumps()` in `toon.py` (which\n * carries column names through `rows[0]{...}:`). The TS encoder accepts\n * a `columns` second arg in the empty case for parity with that\n * pandas-aware wrapper.\n *\n * @throws {ToonTabularError} when rows are non-uniform (differing key\n * sets across rows) or when any cell value is non-primitive\n * (object/array/bigint/etc.). Mirrors Python `encode_tabular`'s\n * `ValueError`. Iter-1 C3 fix.\n */\nexport function toonDumps(\n rows: ReadonlyArray<Record<string, unknown>>,\n columns?: ReadonlyArray<string>,\n): string {\n if (rows.length === 0) {\n // Empty-frame: carry column names if provided (matches the Python\n // DataFrame wrapper's `rows[0]{...}:` empty form). Otherwise emit the\n // bare encoder form.\n if (columns !== undefined) {\n const cols = columns.map((c) => formatKey(String(c))).join(\",\");\n return `rows[0]{${cols}}:`;\n }\n return \"rows[0]:\";\n }\n // C3 hard gate: refuse non-uniform rows BEFORE looking at row 0's keys\n // for the column header. Otherwise we'd silently drop extra columns or\n // null-fill missing ones.\n assertTabular(rows);\n const cols = Object.keys(rows[0] as Record<string, unknown>);\n const colHeader = cols.map((c) => formatKey(c)).join(\",\");\n const header = `rows[${rows.length}]{${colHeader}}:`;\n const dataLines = rows.map((r) => {\n const vals = cols.map((c) => encodeScalar((r as Record<string, unknown>)[c], \",\"));\n return ` ${vals.join(\",\")}`;\n });\n return `${header}\\n${dataLines.join(\"\\n\")}`;\n}\n\n// ---------------------------------------------------------------------------\n// Decoder\n// ---------------------------------------------------------------------------\n\nconst HEADER_PREFIX_RE = /^(?<key>[A-Za-z_][A-Za-z0-9_.]*)\\[(?<count>\\d+)\\]/;\n\nfunction parseHeaderLine(line: string): { count: number; cols: string } {\n const prefix = HEADER_PREFIX_RE.exec(line);\n if (prefix == null) {\n throw new RangeError(`TOON payload missing tabular header; got: ${JSON.stringify(line)}`);\n }\n const declared = Number(prefix.groups?.count ?? \"\");\n let i = prefix[0].length;\n const n = line.length;\n // Handle the header-only empty form: `rows[0]:` (no `{cols}` region).\n if (i < n && line[i] === \":\" && declared === 0) {\n const rest = line.slice(i + 1).trim();\n if (rest === \"\") return { count: 0, cols: \"\" };\n throw new RangeError(`TOON header has trailing junk: ${JSON.stringify(line)}`);\n }\n if (i >= n || line[i] !== \"{\") {\n throw new RangeError(`TOON header missing column region: ${JSON.stringify(line)}`);\n }\n i++; // consume `{`\n // Walk to matching `}` honoring quoted strings.\n while (i < n) {\n const ch = line[i];\n if (ch === '\"') {\n let j = i + 1;\n while (j < n) {\n if (line[j] === \"\\\\\" && j + 1 < n) {\n j += 2;\n continue;\n }\n if (line[j] === '\"') break;\n j++;\n }\n if (j >= n) {\n throw new RangeError(\n `TOON header has unterminated quoted column name: ${JSON.stringify(line)}`,\n );\n }\n i = j + 1;\n continue;\n }\n if (ch === \"}\") break;\n i++;\n }\n if (i >= n || line[i] !== \"}\") {\n throw new RangeError(`TOON header missing closing brace: ${JSON.stringify(line)}`);\n }\n const cols = line.slice(prefix[0].length + 1, i);\n const rest = line.slice(i + 1).trim();\n if (rest !== \":\") {\n throw new RangeError(`TOON header missing colon terminator: ${JSON.stringify(line)}`);\n }\n return { count: declared, cols };\n}\n\nfunction splitCsvRow(line: string): string[] {\n const tokens: string[] = [];\n const n = line.length;\n if (n === 0) return tokens;\n let i = 0;\n while (true) {\n // Skip leading whitespace (defensive — encoder never emits padding).\n while (i < n && line[i] === \" \") i++;\n if (i >= n) {\n tokens.push(\"\");\n break;\n }\n if (line[i] === '\"') {\n let j = i + 1;\n while (j < n) {\n if (line[j] === \"\\\\\" && j + 1 < n) {\n j += 2;\n continue;\n }\n if (line[j] === '\"') break;\n j++;\n }\n tokens.push(line.slice(i, j + 1));\n i = j + 1;\n if (i >= n) break;\n if (line[i] === \",\") {\n i++;\n continue;\n }\n while (i < n && line[i] !== \",\") i++;\n if (i >= n) break;\n i++;\n } else {\n let j = i;\n while (j < n && line[j] !== \",\") j++;\n tokens.push(line.slice(i, j));\n i = j;\n if (i >= n) break;\n i++; // consume comma\n }\n }\n return tokens;\n}\n\nfunction decodeQuoted(token: string): string {\n const inner = token.slice(1, -1);\n let out = \"\";\n let i = 0;\n while (i < inner.length) {\n const ch = inner[i];\n if (ch === \"\\\\\" && i + 1 < inner.length) {\n const nxt = inner.charAt(i + 1);\n if (nxt === \"\\\\\") out += \"\\\\\";\n else if (nxt === '\"') out += '\"';\n else if (nxt === \"n\") out += \"\\n\";\n else if (nxt === \"r\") out += \"\\r\";\n else if (nxt === \"t\") out += \"\\t\";\n else out += nxt;\n i += 2;\n continue;\n }\n out += ch;\n i++;\n }\n return out;\n}\n\nfunction unquoteIfQuoted(token: string): string {\n if (token.length >= 2 && token[0] === '\"' && token[token.length - 1] === '\"') {\n return decodeQuoted(token);\n }\n return token;\n}\n\nfunction decodeValue(token: string): unknown {\n if (token.length === 0) return null;\n if (token[0] === '\"' && token[token.length - 1] === '\"' && token.length >= 2) {\n return decodeQuoted(token);\n }\n if (token === \"null\") return null;\n if (token === \"true\") return true;\n if (token === \"false\") return false;\n // Numeric attempt.\n if (NUMERIC_LIKE_RE.test(token)) {\n if (!token.includes(\".\") && !/[eE]/.test(token)) {\n const n = Number.parseInt(token, 10);\n if (!Number.isNaN(n)) return n;\n }\n const f = Number.parseFloat(token);\n if (!Number.isNaN(f)) return f;\n }\n // Bare unquoted string — TOON allows it when no quote-triggers fire.\n return token;\n}\n\n/**\n * Parse a TOON v3.0 tabular block back into rows + columns.\n *\n * Accepts ONLY the tabular shape that `toonDumps` produces; nested objects\n * / expanded lists are out of scope for the formats module.\n */\nexport function toonLoads(data: string): {\n rows: Array<Record<string, unknown>>;\n columns: string[];\n} {\n const lines = data.split(/\\r?\\n/);\n let idx = 0;\n while (idx < lines.length && lines[idx]?.trim() === \"\") idx++;\n if (idx >= lines.length) throw new RangeError(\"empty TOON payload\");\n\n const { count: declared, cols: colsRegion } = parseHeaderLine(lines[idx] ?? \"\");\n const columns = colsRegion === \"\" ? [] : splitCsvRow(colsRegion).map((t) => unquoteIfQuoted(t));\n\n const rawRows: unknown[][] = [];\n for (const raw of lines.slice(idx + 1)) {\n const line = raw.replace(/\\s+$/u, \"\");\n if (line.trim() === \"\") continue;\n const stripped = line.replace(/^ +/u, \"\");\n const tokens = splitCsvRow(stripped);\n if (columns.length > 0 && tokens.length !== columns.length) {\n throw new RangeError(\n `TOON row column count mismatch: expected ${columns.length}, got ${tokens.length}: ${JSON.stringify(stripped)}`,\n );\n }\n rawRows.push(tokens.map((t) => decodeValue(t)));\n }\n if (declared !== rawRows.length) {\n throw new RangeError(`TOON declared row count ${declared} != actual ${rawRows.length}`);\n }\n const rows = rawRows.map((row) => {\n const r: Record<string, unknown> = {};\n for (let i = 0; i < columns.length; i++) {\n r[columns[i] as string] = row[i];\n }\n return r;\n });\n return { rows, columns };\n}\n","// TS-W6 Wave 3 — DataSnapshot + buildSnapshot.\n//\n// Frozen, JSON-safe immutable record of a research() result with provenance.\n// `toDict()` returns the JSON-safe payload (cycles + non-finite numbers\n// handled by `toJsonSafe`); `toToon()` serializes as a TOON tabular block\n// via the existing `toonDumps` encoder.\n\nimport { toJsonSafe } from \"../exceptions/index.js\";\nimport { toonDumps } from \"../formats/toon.js\";\n\nimport type { DataVersion } from \"./data-version.js\";\n\n/** Frozen snapshot wrapper around row data + provenance. */\nexport interface DataSnapshot {\n /** ISO 8601 UTC instant when the snapshot was built (always ends with Z). */\n readonly knowledgeTime: string;\n /** Schema id the rows conform to. */\n readonly schemaId: string;\n /** Source identifier (e.g. `iem.archive`, `awc.live`). Snapshot-scoped. */\n readonly source: string;\n /** Row payload — opaque to this layer. Frozen. */\n readonly rows: ReadonlyArray<Readonly<Record<string, unknown>>>;\n /** Optional reproducibility token. */\n readonly dataVersion: DataVersion | null;\n /** Optional arbitrary metadata. JSON-safe-coerced on `toDict`. */\n readonly metadata: Readonly<Record<string, unknown>>;\n /** JSON-safe dict form. */\n toDict(): Record<string, unknown>;\n /** TOON-v3 tabular form (rows only — provenance lives in the dict form). */\n toToon(): string;\n}\n\nexport interface BuildSnapshotOptions {\n schemaId: string;\n source: string;\n rows: ReadonlyArray<Record<string, unknown>>;\n knowledgeTime?: Date | string;\n dataVersion?: DataVersion | null;\n metadata?: Record<string, unknown>;\n}\n\nfunction normalizeKnowledgeTime(value: Date | string | undefined): string {\n if (value === undefined) {\n return new Date().toISOString();\n }\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n throw new RangeError(\"buildSnapshot: knowledgeTime is an invalid Date\");\n }\n return value.toISOString();\n }\n // String: parse + re-emit so the result is always canonical ISO with Z.\n const ms = Date.parse(value);\n if (Number.isNaN(ms)) {\n throw new RangeError(\n `buildSnapshot: knowledgeTime ${JSON.stringify(value)} is not a parseable ISO 8601 timestamp`,\n );\n }\n return new Date(ms).toISOString();\n}\n\nfunction freezeRows(\n rows: ReadonlyArray<Record<string, unknown>>,\n): ReadonlyArray<Readonly<Record<string, unknown>>> {\n const out: Readonly<Record<string, unknown>>[] = [];\n for (const r of rows) {\n out.push(Object.freeze({ ...r }));\n }\n return Object.freeze(out);\n}\n\n/**\n * Build a frozen DataSnapshot.\n *\n * Throws RangeError on invalid `knowledgeTime`. Row payloads are shallow-\n * cloned and frozen so callers can't mutate snapshot state post-build.\n */\nexport function buildSnapshot(opts: BuildSnapshotOptions): DataSnapshot {\n if (typeof opts.schemaId !== \"string\" || opts.schemaId.length === 0) {\n throw new RangeError(\"buildSnapshot: schemaId must be a non-empty string\");\n }\n if (typeof opts.source !== \"string\" || opts.source.length === 0) {\n throw new RangeError(\"buildSnapshot: source must be a non-empty string\");\n }\n if (!Array.isArray(opts.rows)) {\n throw new RangeError(\"buildSnapshot: rows must be an array\");\n }\n\n // Capture every component into local consts so the returned snapshot's\n // closures never read from the mutable `opts` argument. Codex iter-1\n // P2: a caller that did `const s = buildSnapshot({...}); opts.schemaId = \"x\"`\n // would have seen `s.toDict()` emit the mutated schemaId while\n // `s.schemaId` still showed the original — provenance drift on an API\n // that promises immutability.\n const knowledgeTime = normalizeKnowledgeTime(opts.knowledgeTime);\n const schemaId = opts.schemaId;\n const source = opts.source;\n const rows = freezeRows(opts.rows);\n const dataVersion = opts.dataVersion ?? null;\n const metadata = Object.freeze({ ...(opts.metadata ?? {}) });\n\n const snapshot: DataSnapshot = {\n knowledgeTime,\n schemaId,\n source,\n rows,\n dataVersion,\n metadata,\n toDict(): Record<string, unknown> {\n // `toJsonSafe` handles cycles + non-finite numbers + Dates. DataVersion\n // is a plain dict-shaped object already, so it round-trips cleanly.\n return toJsonSafe({\n knowledge_time: knowledgeTime,\n schema_id: schemaId,\n source,\n rows,\n data_version: dataVersion,\n metadata,\n }) as Record<string, unknown>;\n },\n toToon(): string {\n // TOON encodes a tabular block (rows-only). The header (schema id,\n // source, knowledge time, data version) lives in `toDict()`. Callers\n // that want the full snapshot in TOON wrap toDict output themselves.\n return toonDumps(rows as unknown as Array<Record<string, unknown>>);\n },\n };\n\n return Object.freeze(snapshot);\n}\n","// TS-W6 Wave 4 — DataVersion reproducibility token via Web Crypto SHA-256.\n//\n// Ports Python `mostlyright.discovery.DataVersion.from_components` byte-for-byte:\n// the canonical concatenation is `sdkVersion|sortedSchemaIds|sortedSources|codeSha|dataSha`,\n// SHA-256 hex of the UTF-8 encoded string is the token.\n//\n// Web Crypto API is universal in modern runtimes (browser/Node 16+/Workers/Deno/Bun),\n// so we use `crypto.subtle.digest` without runtime detection.\n\n/** Immutable reproducibility token stamping a single research() call. */\nexport interface DataVersion {\n readonly sdkVersion: string;\n readonly schemaIds: ReadonlyArray<string>;\n readonly sources: ReadonlyArray<string>;\n readonly codeSha: string;\n readonly dataSha: string;\n readonly token: string;\n}\n\nexport interface DataVersionComponents {\n sdkVersion: string;\n schemaIds: ReadonlyArray<string>;\n sources: ReadonlyArray<string>;\n codeSha: string;\n dataSha: string;\n}\n\nconst HEX = \"0123456789abcdef\";\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 1) {\n const b = bytes[i] as number;\n out += HEX[(b >> 4) & 0xf];\n out += HEX[b & 0xf];\n }\n return out;\n}\n\n/**\n * Build a frozen DataVersion from explicit components.\n *\n * Mirrors Python `DataVersion.from_components`: sorts schemaIds + sources\n * INTERNALLY before the canonical hash so input order does not affect the\n * token, but preserves the caller's order on the returned object's\n * `schemaIds` and `sources` arrays. Codex iter-5 P2: prior version sorted\n * the stored arrays alphabetically too, which masked source-priority order\n * (e.g. `awc.live, ghcnh, iem.archive, ...` instead of the canonical\n * `iem.archive, iem.live, awc.live, ghcnh, nws.cli` precedence Python\n * preserves on the tuple).\n */\nexport async function dataVersionFromComponents(\n components: DataVersionComponents,\n): Promise<DataVersion> {\n const sortedSchemaIds = [...components.schemaIds].sort();\n const sortedSources = [...components.sources].sort();\n const canonical = [\n components.sdkVersion,\n sortedSchemaIds.join(\",\"),\n sortedSources.join(\",\"),\n components.codeSha,\n components.dataSha,\n ].join(\"|\");\n\n const encoded = new TextEncoder().encode(canonical);\n const digest = await crypto.subtle.digest(\"SHA-256\", encoded);\n const token = bytesToHex(new Uint8Array(digest));\n\n return Object.freeze({\n sdkVersion: components.sdkVersion,\n schemaIds: Object.freeze([...components.schemaIds]),\n sources: Object.freeze([...components.sources]),\n codeSha: components.codeSha,\n dataSha: components.dataSha,\n token,\n });\n}\n\n/**\n * Build a DataVersion for a research() call. Mirrors Python `DataVersion.for_research`:\n * the codeSha encodes the call signature (`research:STATION:FROM:TO`) and dataSha\n * is supplied by the caller (typically a cache fingerprint).\n *\n * The schema ids + source contract match the v0.1.0 Python SDK exactly so tokens\n * computed in TS match tokens computed in Python for the same inputs.\n */\nexport async function dataVersionForResearch(args: {\n sdkVersion: string;\n station: string;\n fromDate: string;\n toDate: string;\n dataSha: string;\n}): Promise<DataVersion> {\n return dataVersionFromComponents({\n sdkVersion: args.sdkVersion,\n schemaIds: [\"schema.observation.v1\", \"schema.forecast.iem_mos.v1\", \"schema.settlement.cli.v1\"],\n sources: [\"iem.archive\", \"iem.live\", \"awc.live\", \"ghcnh\", \"nws.cli\"],\n codeSha: `research:${args.station}:${args.fromDate}:${args.toDate}`,\n dataSha: args.dataSha,\n });\n}\n","// TS-W6 Wave 5 — describe(schemaId) + featureCatalog() + climateGaps stub.\n//\n// `describe(schemaId)` returns a multi-line human-readable string mined from\n// the embedded JSON-Schema metadata. We bundle schema descriptions as a small\n// JSON map keyed by `$id` (the canonical schema id) — produced by the codegen\n// pipeline if/when it lands; for v0.1.0 we ship a hand-maintained list that\n// matches what the codegen emits.\n//\n// `featureCatalog()` returns the transforms surface as a stable-sorted list\n// of names — matches Python `feature_catalog()` exactly.\n//\n// `climateGaps(station, fromDate, toDate)` throws — TS has no climate cache\n// in v0.1.0 (climate-year parquets are Python-only); the stub matches the\n// Python signature so callers can `try/catch` the platform difference.\n\nimport { MostlyRightError } from \"../exceptions/index.js\";\n\n// ---------------------------------------------------------------------------\n// Schema registry — keep in sync with `packages-ts/core/src/schemas/generated`.\n// ---------------------------------------------------------------------------\n\ninterface SchemaInfo {\n readonly id: string;\n readonly title: string;\n readonly columnCount: number;\n readonly columns: ReadonlyArray<{\n readonly name: string;\n readonly description: string;\n readonly nullable: boolean;\n }>;\n}\n\n// Static manifest of the v0.1.0 schemas. Derived from `schemas/json/*.json`\n// at repo root; baked in here so `@mostlyrightmd/core/discovery` works in\n// browsers (no `node:fs`) without a runtime fetch. The codegen pipeline\n// would replace this hand-maintained list once it covers schema docs.\n//\n// Codex iter-1 P2: prior version left REGISTRY empty until callers ran\n// `registerSchema()`, so `describe('schema.observation.v1')` always threw\n// UNKNOWN_SCHEMA on a fresh import.\nconst BUILT_IN_SCHEMAS: ReadonlyArray<SchemaInfo> = Object.freeze([\n {\n id: \"schema.observation.v1\",\n title: \"schema.observation.v1\",\n columnCount: 20,\n columns: [\n { name: \"dew_point_c\", description: \"units: celsius — bounded\", nullable: true },\n { name: \"event_time\", description: \"observation valid time\", nullable: false },\n {\n name: \"metar_raw\",\n description: \"raw METAR text if source has it; null for AWC JSON (structured-only)\",\n nullable: true,\n },\n {\n name: \"observation_type\",\n description: \"METAR | SPECI; defaults METAR when source can't distinguish (e.g. AWC JSON)\",\n nullable: false,\n },\n {\n name: \"precip_mm_1h\",\n description: \"units: mm — hourly precip (METAR p01i, converted from inches)\",\n nullable: true,\n },\n {\n name: \"sky_base_1_m\",\n description: \"units: meters — first cloud layer base height (converted from feet)\",\n nullable: true,\n },\n { name: \"sky_base_2_m\", description: \"units: meters\", nullable: true },\n { name: \"sky_base_3_m\", description: \"units: meters\", nullable: true },\n { name: \"sky_base_4_m\", description: \"units: meters\", nullable: true },\n { name: \"sky_cover_1\", description: \"first cloud layer cover code\", nullable: true },\n { name: \"sky_cover_2\", description: \"second layer; null if not present\", nullable: true },\n { name: \"sky_cover_3\", description: \"third layer; null if not present\", nullable: true },\n { name: \"sky_cover_4\", description: \"fourth layer; null if not present\", nullable: true },\n {\n name: \"slp_hpa\",\n description:\n \"units: hPa — sea-level pressure (canonical aviation unit, not converted across modes)\",\n nullable: true,\n },\n { name: \"station\", description: \"ICAO/ASOS station ID (e.g. KORD)\", nullable: false },\n {\n name: \"temp_c\",\n description: \"units: celsius — bounded TEMP_MIN_C..TEMP_MAX_C\",\n nullable: true,\n },\n {\n name: \"visibility_m\",\n description: \"units: meters — converted from statute miles\",\n nullable: true,\n },\n {\n name: \"wind_dir_deg\",\n description: \"units: degrees — 0-360, bounded\",\n nullable: true,\n },\n { name: \"wind_gust_ms\", description: \"units: m/s — converted from kt\", nullable: true },\n { name: \"wind_speed_ms\", description: \"units: m/s — converted from kt\", nullable: true },\n ],\n },\n {\n id: \"schema.forecast.iem_mos.v1\",\n title: \"schema.forecast.iem_mos.v1\",\n columnCount: 11,\n columns: [\n { name: \"dew_point_c\", description: \"units: celsius\", nullable: true },\n {\n name: \"forecast_hour\",\n description: \"units: hours — (valid_at - issued_at).total_seconds() / 3600\",\n nullable: false,\n },\n {\n name: \"issued_at\",\n description: \"model run time (from source `runtime` field)\",\n nullable: false,\n },\n { name: \"model\", description: \"e.g. NBE, GFS, LAV, MET\", nullable: false },\n {\n name: \"precip_probability\",\n description: \"units: probability — bounded [0, 1]\",\n nullable: true,\n },\n {\n name: \"sky_cover_pct\",\n description: \"units: percent — bounded [0, 100]\",\n nullable: true,\n },\n { name: \"station\", description: \"\", nullable: false },\n { name: \"temp_c\", description: \"units: celsius\", nullable: true },\n {\n name: \"valid_at\",\n description: \"forecast target time (from source `ftime`)\",\n nullable: false,\n },\n { name: \"wind_dir_deg\", description: \"units: degrees\", nullable: true },\n { name: \"wind_speed_ms\", description: \"units: m/s\", nullable: true },\n ],\n },\n {\n id: \"schema.settlement.cli.v1\",\n title: \"schema.settlement.cli.v1\",\n columnCount: 12,\n columns: [\n {\n name: \"cli_data_quality\",\n description:\n \"NWS CLI data-quality marker (Pitfall 6/16). Allows downstream code to filter or weight settlement rows by issuer quality without re-parsing the product header.\",\n nullable: false,\n },\n {\n name: \"event_time\",\n description: \"00:00 local time on observation_date converted to UTC; for sort/join only\",\n nullable: false,\n },\n {\n name: \"observation_date\",\n description:\n \"local climate day per NWS convention (no timezone applied to the date itself)\",\n nullable: false,\n },\n { name: \"precipitation_in\", description: \"units: inches\", nullable: true },\n {\n name: \"product_release_time\",\n description: \"parsed from CLI product header (_climate.py::_parse_product_timestamp)\",\n nullable: false,\n },\n {\n name: \"report_type\",\n description:\n \"preliminary | final | correction; dedup priority preliminary < final < correction\",\n nullable: false,\n },\n {\n name: \"settlement_finality\",\n description:\n \"provisional | final | superseded. Kalshi NHIGH/NLOW settlement contractually requires 'final'; 'provisional' values are kept for early-look research only.\",\n nullable: false,\n },\n { name: \"snowfall_in\", description: \"units: inches\", nullable: true },\n { name: \"station\", description: \"ICAO/ASOS station ID\", nullable: false },\n {\n name: \"station_tz\",\n description:\n \"IANA timezone for the station (e.g. America/Chicago for KORD). Required for local-climate-day semantics; see §U.\",\n nullable: false,\n },\n {\n name: \"temp_max_F\",\n description:\n \"units: fahrenheit — daily high (uppercase F for consistency with obs imperial mode)\",\n nullable: true,\n },\n { name: \"temp_min_F\", description: \"units: fahrenheit — daily low\", nullable: true },\n ],\n },\n {\n id: \"schema.observation_ledger.v1\",\n title: \"schema.observation_ledger.v1\",\n columnCount: 15,\n columns: [\n { name: \"as_of_time\", description: \"\", nullable: true },\n { name: \"dewpoint_c\", description: \"units: celsius\", nullable: true },\n { name: \"ingestion_id\", description: \"\", nullable: true },\n { name: \"observation_kind\", description: \"\", nullable: true },\n {\n name: \"observation_quality\",\n description:\n \"Lineage row-quality flag per LINEAGE-01; distinct from qc_status enum slot AND distinct from the obs_qc_status bitmask column per QC-05.\",\n nullable: true,\n },\n { name: \"observation_type\", description: \"\", nullable: false },\n { name: \"observed_at\", description: \"\", nullable: false },\n { name: \"parser_name\", description: \"\", nullable: true },\n { name: \"parser_version\", description: \"\", nullable: true },\n { name: \"provenance\", description: \"\", nullable: true },\n { name: \"qc_status\", description: \"\", nullable: true },\n {\n name: \"source\",\n description: \"ncei reserved per D-2.1-09; never written in v0.1.0.\",\n nullable: false,\n },\n { name: \"source_received_at\", description: \"\", nullable: true },\n { name: \"station_code\", description: \"\", nullable: false },\n { name: \"temp_c\", description: \"units: celsius\", nullable: true },\n ],\n },\n {\n id: \"schema.observation_qc.v1\",\n title: \"schema.observation_qc.v1\",\n columnCount: 13,\n columns: [\n { name: \"as_of_time\", description: \"\", nullable: true },\n {\n name: \"detector_metadata\",\n description: \"JSON-serialized detector payload; shape per qc_system.\",\n nullable: true,\n },\n {\n name: \"field\",\n description: \"Observation column the rule evaluated (e.g. temp_c).\",\n nullable: false,\n },\n { name: \"flag\", description: \"\", nullable: false },\n { name: \"ingestion_id\", description: \"\", nullable: true },\n { name: \"observation_kind\", description: \"\", nullable: true },\n { name: \"observed_at\", description: \"\", nullable: false },\n { name: \"parser_name\", description: \"\", nullable: true },\n { name: \"qc_system\", description: \"\", nullable: false },\n { name: \"qc_version\", description: \"\", nullable: false },\n { name: \"rule_id\", description: \"\", nullable: false },\n { name: \"source\", description: \"\", nullable: false },\n { name: \"station_code\", description: \"\", nullable: false },\n ],\n },\n]);\n\nfunction deepFreezeSchema(info: SchemaInfo): SchemaInfo {\n const frozenCols = Object.freeze(info.columns.map((c) => Object.freeze({ ...c })));\n return Object.freeze({ ...info, columns: frozenCols });\n}\n\nconst REGISTRY = new Map<string, SchemaInfo>(\n BUILT_IN_SCHEMAS.map((info) => [info.id, deepFreezeSchema(info)] as const),\n);\n\n/**\n * Register or override a schema for `describe()`. Built-in v0.1.0 schemas\n * are registered at module load (BUILT_IN_SCHEMAS); callers may add custom\n * schemas or override built-ins (e.g. with richer descriptions).\n */\nexport function registerSchema(info: SchemaInfo): void {\n REGISTRY.set(info.id, deepFreezeSchema(info));\n}\n\n/**\n * Return a multi-line description of a registered schema.\n *\n * @throws MostlyRightError if `schemaId` is not registered. The error code is\n * `UNKNOWN_SCHEMA` so callers can distinguish from validation/IO errors.\n */\nexport function describe(schemaId: string): string {\n const info = REGISTRY.get(schemaId);\n if (info === undefined) {\n const known = [...REGISTRY.keys()].sort();\n throw new UnknownSchemaError(\n `Unknown schemaId ${JSON.stringify(schemaId)}; registered: ${\n known.length === 0 ? \"<none>\" : known.join(\", \")\n }`,\n );\n }\n const lines = [`Schema: ${info.id}`, ` Title: ${info.title}`, ` Columns: ${info.columnCount}`];\n for (const col of info.columns) {\n const nullable = col.nullable ? \"?\" : \"\";\n const desc = col.description.length === 0 ? \"\" : ` — ${col.description}`;\n lines.push(` - ${col.name}${nullable}${desc}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Thrown by `describe` when `schemaId` is not registered. */\nexport class UnknownSchemaError extends MostlyRightError {\n constructor(message: string) {\n super(message);\n this.name = \"UnknownSchemaError\";\n }\n static readonly defaultErrorCode = \"UNKNOWN_SCHEMA\";\n}\n\n// ---------------------------------------------------------------------------\n// featureCatalog — list of transforms surface names.\n// ---------------------------------------------------------------------------\n\nconst FEATURE_NAMES: ReadonlyArray<string> = Object.freeze([\n \"calendarFeatures\",\n \"clipOutliers\",\n \"diff\",\n \"diff2\",\n \"heatIndex\",\n \"lag\",\n \"rolling\",\n \"spread\",\n \"windChill\",\n]);\n\n/**\n * Return the transforms surface as a stable-sorted list.\n *\n * Matches Python `feature_catalog()`'s ordering — alphabetical on the\n * snake_case names, here the camelCase TS names sorted identically.\n */\nexport function featureCatalog(): ReadonlyArray<string> {\n return FEATURE_NAMES;\n}\n\n// ---------------------------------------------------------------------------\n// climateGaps — stub that mirrors Python's signature; v1.x deferral.\n// ---------------------------------------------------------------------------\n//\n// Phase 21 21-11 upgrade: raises DataAvailabilityError (typed exception\n// from Phase 21 21-09) with an architectural-reason hint. The legacy\n// ClimateGapsNotImplementedError class is kept as a back-compat alias\n// (subclass of DataAvailabilityError) so existing `catch` sites keep\n// working. New code should catch DataAvailabilityError and dispatch on\n// the `reason` field instead.\n\nimport { DataAvailabilityError } from \"../exceptions/index.js\";\n\nconst CLIMATE_GAPS_HINT =\n \"climateGaps() is server-only in v1.x. Architectural reason: \" +\n \"GHCNh CSVs are 10+ MB per station-year; browser fetch doesn't \" +\n \"slice (no HTTP Range) and IndexedDB quotas don't fit the working \" +\n \"set. Use the Python SDK (mostlyright.discover.climate_gaps) for \" +\n \"v1.x, or wait for the hosted climate-gap-precompute API \" +\n \"(target: post-v1.x). See https://mostlyright.md/docs/sdk/typescript/climate-gaps \" +\n \"for details.\";\n\n/**\n * Climate-gap scanning — TS v1.x deferral.\n *\n * Phase 21 21-11 messaging upgrade: raises DataAvailabilityError with a\n * multi-paragraph hint explaining the architectural constraint (GHCNh\n * CSVs are 10+ MB per station-year; browser cache layer doesn't scale).\n *\n * @throws DataAvailabilityError with reason=\"model_unavailable\" and a\n * hint pointing at the Python SDK as the supported v1.x workaround.\n */\nexport function climateGaps(_station: string, _fromDate: string, _toDate: string): never {\n throw new ClimateGapsNotImplementedError();\n}\n\n/**\n * Back-compat subclass of DataAvailabilityError raised by `climateGaps`\n * in v1.x. Existing `catch (e instanceof ClimateGapsNotImplementedError)`\n * sites keep working; new code should catch the parent class\n * `DataAvailabilityError` and dispatch on `reason === \"model_unavailable\"`.\n *\n * @deprecated Prefer catching `DataAvailabilityError` directly.\n */\nexport class ClimateGapsNotImplementedError extends DataAvailabilityError {\n static override readonly defaultErrorCode = \"DATA_AVAILABILITY\";\n\n constructor() {\n super({\n reason: \"model_unavailable\",\n source: \"climate-cache-browser\",\n hint: CLIMATE_GAPS_HINT,\n });\n this.name = \"ClimateGapsNotImplementedError\";\n }\n}\n"],"mappings":"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CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AACxB,CAAC;AAEM,IAAM,kBAAoD,oBAAI,IAAyB;AAAA,EAC5F,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,E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","names":["minRow","maxRow","cols"]}
|
|
1
|
+
{"version":3,"sources":["../../src/discovery/index.ts","../../src/data/generated/stations.ts","../../src/discovery/availability.ts","../../src/discovery/international.ts","../../src/exceptions/index.ts","../../src/formats/toon.ts","../../src/discovery/snapshot.ts","../../src/discovery/data-version.ts","../../src/discovery/describe.ts"],"sourcesContent":["// Barrel for @mostlyrightmd/core/discovery — TS-W6.\n//\n// Five waves shipped at this subpath:\n//\n// Wave 1: availability(station, cache) reading from CacheStore.\n// Wave 2: internationalDailyExtremes(rows, opts) UTC→local rollup.\n// Wave 3: buildSnapshot(...) + DataSnapshot.toDict / .toToon.\n// Wave 4: dataVersionFromComponents / dataVersionForResearch via Web Crypto.\n// Wave 5: describe(schemaId) + featureCatalog() + climateGaps stub.\n//\n// Discovery lives at the subpath (NOT the root barrel) to keep the\n// @mostlyrightmd/core main bundle under its 25 KB size-limit gate\n// (TS-BUNDLE-01). Same pattern as transforms / temporal / formats / qc /\n// validator — see iter-4 H8 lesson in `packages-ts/core/src/index.ts`.\n//\n// Consumers import with:\n//\n// import {\n// availability,\n// internationalDailyExtremes,\n// buildSnapshot,\n// dataVersionFromComponents,\n// dataVersionForResearch,\n// describe,\n// featureCatalog,\n// climateGaps,\n// } from \"@mostlyrightmd/core/discovery\";\n// import type {\n// AvailabilityResult,\n// KeyEnumerableStore,\n// DailyExtreme,\n// InternationalDailyExtremesOptions,\n// InternationalRow,\n// DataSnapshot,\n// BuildSnapshotOptions,\n// DataVersion,\n// DataVersionComponents,\n// } from \"@mostlyrightmd/core/discovery\";\n\nexport { availability } from \"./availability.js\";\nexport type {\n AvailabilityOptions,\n AvailabilityResult,\n KeyEnumerableStore,\n} from \"./availability.js\";\n\nexport { internationalDailyExtremes } from \"./international.js\";\nexport type {\n DailyExtreme,\n InternationalDailyExtremesOptions,\n InternationalRow,\n} from \"./international.js\";\n\nexport { buildSnapshot } from \"./snapshot.js\";\nexport type { BuildSnapshotOptions, DataSnapshot } from \"./snapshot.js\";\n\nexport {\n dataVersionForResearch,\n dataVersionFromComponents,\n} from \"./data-version.js\";\nexport type { DataVersion, DataVersionComponents } from \"./data-version.js\";\n\nexport {\n ClimateGapsNotImplementedError,\n UnknownSchemaError,\n climateGaps,\n describe,\n featureCatalog,\n registerSchema,\n} from \"./describe.js\";\n","// AUTO-GENERATED by @mostlyrightmd/codegen from schemas/stations.json.\n// DO NOT EDIT — regenerate with: pnpm codegen\n// Last manifest SHA recorded in schemas/EXPORT_MANIFEST.json\n\nexport interface StationInfo {\n code: string | null;\n ghcnh_id: string | null;\n icao: string;\n name: string | null;\n tz: string;\n latitude: number | null;\n longitude: number | null;\n country: string | null;\n venues: ReadonlyArray<string>;\n}\n\nexport const STATIONS: ReadonlyArray<StationInfo> = [\n {\n code: \"CYYZ\",\n country: \"CA\",\n ghcnh_id: null,\n icao: \"CYYZ\",\n latitude: 43.6777,\n longitude: -79.6248,\n name: \"Toronto Pearson International\",\n tz: \"America/Toronto\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EDDB\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDB\",\n latitude: 52.3667,\n longitude: 13.5033,\n name: \"Berlin Brandenburg\",\n tz: \"Europe/Berlin\",\n venues: [],\n },\n {\n code: \"EDDF\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDF\",\n latitude: 50.0379,\n longitude: 8.5622,\n name: \"Frankfurt am Main\",\n tz: \"Europe/Berlin\",\n venues: [],\n },\n {\n code: \"EDDM\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDM\",\n latitude: 48.3538,\n longitude: 11.7861,\n name: \"Munich Franz Josef Strauss\",\n tz: \"Europe/Berlin\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EFHK\",\n country: \"FI\",\n ghcnh_id: null,\n icao: \"EFHK\",\n latitude: 60.3172,\n longitude: 24.9633,\n name: \"Helsinki-Vantaa\",\n tz: \"Europe/Helsinki\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EGKK\",\n country: \"GB\",\n ghcnh_id: null,\n icao: \"EGKK\",\n latitude: 51.1481,\n longitude: -0.1903,\n name: \"London Gatwick\",\n tz: \"Europe/London\",\n venues: [],\n },\n {\n code: \"EGLC\",\n country: \"GB\",\n ghcnh_id: null,\n icao: \"EGLC\",\n latitude: 51.5053,\n longitude: 0.0553,\n name: \"London City\",\n tz: \"Europe/London\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EGLL\",\n country: \"GB\",\n ghcnh_id: null,\n icao: \"EGLL\",\n latitude: 51.4706,\n longitude: -0.4619,\n name: \"London Heathrow\",\n tz: \"Europe/London\",\n venues: [],\n },\n {\n code: \"EHAM\",\n country: \"NL\",\n ghcnh_id: null,\n icao: \"EHAM\",\n latitude: 52.3086,\n longitude: 4.7639,\n name: \"Amsterdam Schiphol\",\n tz: \"Europe/Amsterdam\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"EKCH\",\n country: \"DK\",\n ghcnh_id: null,\n icao: \"EKCH\",\n latitude: 55.6181,\n longitude: 12.6561,\n name: \"Copenhagen Kastrup\",\n tz: \"Europe/Copenhagen\",\n venues: [],\n },\n {\n code: \"EPWA\",\n country: \"PL\",\n ghcnh_id: null,\n icao: \"EPWA\",\n latitude: 52.1657,\n longitude: 20.9671,\n name: \"Warsaw Chopin\",\n tz: \"Europe/Warsaw\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ESSA\",\n country: \"SE\",\n ghcnh_id: null,\n icao: \"ESSA\",\n latitude: 59.6519,\n longitude: 17.9186,\n name: \"Stockholm Arlanda\",\n tz: \"Europe/Stockholm\",\n venues: [],\n },\n {\n code: \"FACT\",\n country: \"ZA\",\n ghcnh_id: null,\n icao: \"FACT\",\n latitude: -33.9648,\n longitude: 18.6017,\n name: \"Cape Town International\",\n tz: \"Africa/Johannesburg\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ATL\",\n country: \"US\",\n ghcnh_id: \"USW00013874\",\n icao: \"KATL\",\n latitude: 33.6407,\n longitude: -84.4277,\n name: \"Hartsfield-Jackson Atlanta International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"AUS\",\n country: \"US\",\n ghcnh_id: \"USW00013904\",\n icao: \"KAUS\",\n latitude: 30.1975,\n longitude: -97.6664,\n name: \"Austin-Bergstrom International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"BKF\",\n country: \"US\",\n ghcnh_id: \"USW00093067\",\n icao: \"KBKF\",\n latitude: 39.7019,\n longitude: -104.7517,\n name: \"Buckley Space Force Base (Denver)\",\n tz: \"America/Denver\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"BNA\",\n country: \"US\",\n ghcnh_id: \"USW00013897\",\n icao: \"KBNA\",\n latitude: 36.1245,\n longitude: -86.6782,\n name: \"Nashville International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"BOS\",\n country: \"US\",\n ghcnh_id: \"USW00014739\",\n icao: \"KBOS\",\n latitude: 42.3656,\n longitude: -71.0096,\n name: \"Boston Logan International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"CVG\",\n country: \"US\",\n ghcnh_id: \"USW00093814\",\n icao: \"KCVG\",\n latitude: 39.0488,\n longitude: -84.6678,\n name: \"Cincinnati/Northern Kentucky International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"DAL\",\n country: \"US\",\n ghcnh_id: \"USW00013960\",\n icao: \"KDAL\",\n latitude: 32.8481,\n longitude: -96.8512,\n name: \"Dallas Love Field\",\n tz: \"America/Chicago\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"DCA\",\n country: \"US\",\n ghcnh_id: \"USW00013743\",\n icao: \"KDCA\",\n latitude: 38.8512,\n longitude: -77.0402,\n name: \"Washington Reagan National\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"DEN\",\n country: \"US\",\n ghcnh_id: \"USW00003017\",\n icao: \"KDEN\",\n latitude: 39.8561,\n longitude: -104.6737,\n name: \"Denver International\",\n tz: \"America/Denver\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"DFW\",\n country: \"US\",\n ghcnh_id: \"USW00003927\",\n icao: \"KDFW\",\n latitude: 32.8998,\n longitude: -97.0403,\n name: \"Dallas-Fort Worth International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"DTW\",\n country: \"US\",\n ghcnh_id: \"USW00094847\",\n icao: \"KDTW\",\n latitude: 42.2124,\n longitude: -83.3534,\n name: \"Detroit Metropolitan Wayne County\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"HOU\",\n country: \"US\",\n ghcnh_id: \"USW00012918\",\n icao: \"KHOU\",\n latitude: 29.6454,\n longitude: -95.2789,\n name: \"Houston Hobby\",\n tz: \"America/Chicago\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"IAH\",\n country: \"US\",\n ghcnh_id: \"USW00012960\",\n icao: \"KIAH\",\n latitude: 29.9844,\n longitude: -95.3414,\n name: \"Houston George Bush Intercontinental\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"LAS\",\n country: \"US\",\n ghcnh_id: \"USW00023169\",\n icao: \"KLAS\",\n latitude: 36.084,\n longitude: -115.1537,\n name: \"Harry Reid (McCarran) International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"LAX\",\n country: \"US\",\n ghcnh_id: \"USW00023174\",\n icao: \"KLAX\",\n latitude: 33.9425,\n longitude: -118.4081,\n name: \"Los Angeles International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"LGA\",\n country: \"US\",\n ghcnh_id: \"USW00014732\",\n icao: \"KLGA\",\n latitude: 40.7772,\n longitude: -73.8726,\n name: \"New York LaGuardia\",\n tz: \"America/New_York\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"MDW\",\n country: \"US\",\n ghcnh_id: \"USW00014819\",\n icao: \"KMDW\",\n latitude: 41.7868,\n longitude: -87.7522,\n name: \"Chicago Midway International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"MIA\",\n country: \"US\",\n ghcnh_id: \"USW00012839\",\n icao: \"KMIA\",\n latitude: 25.7959,\n longitude: -80.287,\n name: \"Miami International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"MSP\",\n country: \"US\",\n ghcnh_id: \"USW00014922\",\n icao: \"KMSP\",\n latitude: 44.8848,\n longitude: -93.2223,\n name: \"Minneapolis-St Paul International\",\n tz: \"America/Chicago\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"MSY\",\n country: \"US\",\n ghcnh_id: \"USW00012916\",\n icao: \"KMSY\",\n latitude: 29.9934,\n longitude: -90.258,\n name: \"New Orleans Louis Armstrong International\",\n tz: \"America/Chicago\",\n venues: [],\n },\n {\n code: \"NYC\",\n country: \"US\",\n ghcnh_id: \"USW00094728\",\n icao: \"KNYC\",\n latitude: 40.7789,\n longitude: -73.9692,\n name: \"Central Park, New York\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"OKC\",\n country: \"US\",\n ghcnh_id: \"USW00013967\",\n icao: \"KOKC\",\n latitude: 35.3931,\n longitude: -97.6007,\n name: \"Oklahoma City Will Rogers World\",\n tz: \"America/Chicago\",\n venues: [],\n },\n {\n code: \"ORD\",\n country: \"US\",\n ghcnh_id: \"USW00094846\",\n icao: \"KORD\",\n latitude: 41.9742,\n longitude: -87.9073,\n name: \"Chicago O'Hare International\",\n tz: \"America/Chicago\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"PHL\",\n country: \"US\",\n ghcnh_id: \"USW00013739\",\n icao: \"KPHL\",\n latitude: 39.8721,\n longitude: -75.2411,\n name: \"Philadelphia International\",\n tz: \"America/New_York\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"PHX\",\n country: \"US\",\n ghcnh_id: \"USW00023183\",\n icao: \"KPHX\",\n latitude: 33.4373,\n longitude: -112.0078,\n name: \"Phoenix Sky Harbor International\",\n tz: \"America/Phoenix\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"SAT\",\n country: \"US\",\n ghcnh_id: \"USW00012921\",\n icao: \"KSAT\",\n latitude: 29.5337,\n longitude: -98.4698,\n name: \"San Antonio International\",\n tz: \"America/Chicago\",\n venues: [],\n },\n {\n code: \"SEA\",\n country: \"US\",\n ghcnh_id: \"USW00024233\",\n icao: \"KSEA\",\n latitude: 47.4502,\n longitude: -122.3088,\n name: \"Seattle-Tacoma International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"SFO\",\n country: \"US\",\n ghcnh_id: \"USW00023234\",\n icao: \"KSFO\",\n latitude: 37.6213,\n longitude: -122.379,\n name: \"San Francisco International\",\n tz: \"America/Los_Angeles\",\n venues: [\n \"kalshi\",\n \"polymarket\",\n ],\n },\n {\n code: \"SLC\",\n country: \"US\",\n ghcnh_id: \"USW00024127\",\n icao: \"KSLC\",\n latitude: 40.7884,\n longitude: -111.9778,\n name: \"Salt Lake City International\",\n tz: \"America/Denver\",\n venues: [\n \"kalshi\",\n ],\n },\n {\n code: \"LEBL\",\n country: \"ES\",\n ghcnh_id: null,\n icao: \"LEBL\",\n latitude: 41.2974,\n longitude: 2.0833,\n name: \"Barcelona El Prat\",\n tz: \"Europe/Madrid\",\n venues: [],\n },\n {\n code: \"LEMD\",\n country: \"ES\",\n ghcnh_id: null,\n icao: \"LEMD\",\n latitude: 40.4719,\n longitude: -3.5626,\n name: \"Madrid Barajas\",\n tz: \"Europe/Madrid\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LFPB\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPB\",\n latitude: 48.9694,\n longitude: 2.4414,\n name: \"Paris Le Bourget\",\n tz: \"Europe/Paris\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LFPG\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPG\",\n latitude: 49.0097,\n longitude: 2.5479,\n name: \"Paris Charles de Gaulle\",\n tz: \"Europe/Paris\",\n venues: [],\n },\n {\n code: \"LFPO\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPO\",\n latitude: 48.7233,\n longitude: 2.3794,\n name: \"Paris Orly\",\n tz: \"Europe/Paris\",\n venues: [],\n },\n {\n code: \"LIMC\",\n country: \"IT\",\n ghcnh_id: null,\n icao: \"LIMC\",\n latitude: 45.6306,\n longitude: 8.7281,\n name: \"Milan Malpensa\",\n tz: \"Europe/Rome\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LIRF\",\n country: \"IT\",\n ghcnh_id: null,\n icao: \"LIRF\",\n latitude: 41.8003,\n longitude: 12.2389,\n name: \"Rome Fiumicino\",\n tz: \"Europe/Rome\",\n venues: [],\n },\n {\n code: \"LLBG\",\n country: \"IL\",\n ghcnh_id: null,\n icao: \"LLBG\",\n latitude: 32.0114,\n longitude: 34.8867,\n name: \"Tel Aviv Ben Gurion\",\n tz: \"Asia/Jerusalem\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LOWW\",\n country: \"AT\",\n ghcnh_id: null,\n icao: \"LOWW\",\n latitude: 48.1103,\n longitude: 16.5697,\n name: \"Vienna International\",\n tz: \"Europe/Vienna\",\n venues: [],\n },\n {\n code: \"LSZH\",\n country: \"CH\",\n ghcnh_id: null,\n icao: \"LSZH\",\n latitude: 47.4647,\n longitude: 8.5492,\n name: \"Zurich\",\n tz: \"Europe/Zurich\",\n venues: [],\n },\n {\n code: \"LTAC\",\n country: \"TR\",\n ghcnh_id: null,\n icao: \"LTAC\",\n latitude: 40.1281,\n longitude: 32.9951,\n name: \"Ankara Esenboga\",\n tz: \"Europe/Istanbul\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"LTFM\",\n country: \"TR\",\n ghcnh_id: null,\n icao: \"LTFM\",\n latitude: 41.2753,\n longitude: 28.7519,\n name: \"Istanbul Airport\",\n tz: \"Europe/Istanbul\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"MMMX\",\n country: \"MX\",\n ghcnh_id: null,\n icao: \"MMMX\",\n latitude: 19.4363,\n longitude: -99.0721,\n name: \"Mexico City Benito Juarez International\",\n tz: \"America/Mexico_City\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"MPMG\",\n country: \"PA\",\n ghcnh_id: null,\n icao: \"MPMG\",\n latitude: 8.9733,\n longitude: -79.5556,\n name: \"Panama City Marcos A. Gelabert (Albrook)\",\n tz: \"America/Panama\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"NZAA\",\n country: \"NZ\",\n ghcnh_id: null,\n icao: \"NZAA\",\n latitude: -37.0081,\n longitude: 174.7917,\n name: \"Auckland\",\n tz: \"Pacific/Auckland\",\n venues: [],\n },\n {\n code: \"NZWN\",\n country: \"NZ\",\n ghcnh_id: null,\n icao: \"NZWN\",\n latitude: -41.3272,\n longitude: 174.8053,\n name: \"Wellington\",\n tz: \"Pacific/Auckland\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"OEJN\",\n country: \"SA\",\n ghcnh_id: null,\n icao: \"OEJN\",\n latitude: 21.6796,\n longitude: 39.1565,\n name: \"Jeddah King Abdulaziz International\",\n tz: \"Asia/Riyadh\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"OERK\",\n country: \"SA\",\n ghcnh_id: null,\n icao: \"OERK\",\n latitude: 24.9576,\n longitude: 46.6988,\n name: \"Riyadh King Khalid International\",\n tz: \"Asia/Riyadh\",\n venues: [],\n },\n {\n code: \"OMDB\",\n country: \"AE\",\n ghcnh_id: null,\n icao: \"OMDB\",\n latitude: 25.2532,\n longitude: 55.3657,\n name: \"Dubai International\",\n tz: \"Asia/Dubai\",\n venues: [],\n },\n {\n code: \"OPKC\",\n country: \"PK\",\n ghcnh_id: null,\n icao: \"OPKC\",\n latitude: 24.9065,\n longitude: 67.1608,\n name: \"Karachi Jinnah International\",\n tz: \"Asia/Karachi\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"OTHH\",\n country: \"QA\",\n ghcnh_id: null,\n icao: \"OTHH\",\n latitude: 25.2731,\n longitude: 51.608,\n name: \"Doha Hamad International\",\n tz: \"Asia/Qatar\",\n venues: [],\n },\n {\n code: \"RCSS\",\n country: \"TW\",\n ghcnh_id: null,\n icao: \"RCSS\",\n latitude: 25.0694,\n longitude: 121.5519,\n name: \"Taipei Songshan\",\n tz: \"Asia/Taipei\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RCTP\",\n country: \"TW\",\n ghcnh_id: null,\n icao: \"RCTP\",\n latitude: 25.0777,\n longitude: 121.2328,\n name: \"Taipei Taoyuan\",\n tz: \"Asia/Taipei\",\n venues: [],\n },\n {\n code: \"RJAA\",\n country: \"JP\",\n ghcnh_id: null,\n icao: \"RJAA\",\n latitude: 35.7647,\n longitude: 140.3864,\n name: \"Tokyo Narita\",\n tz: \"Asia/Tokyo\",\n venues: [],\n },\n {\n code: \"RJTT\",\n country: \"JP\",\n ghcnh_id: null,\n icao: \"RJTT\",\n latitude: 35.5522,\n longitude: 139.78,\n name: \"Tokyo Haneda\",\n tz: \"Asia/Tokyo\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RKPK\",\n country: \"KR\",\n ghcnh_id: null,\n icao: \"RKPK\",\n latitude: 35.1795,\n longitude: 128.9382,\n name: \"Busan Gimhae International\",\n tz: \"Asia/Seoul\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RKSI\",\n country: \"KR\",\n ghcnh_id: null,\n icao: \"RKSI\",\n latitude: 37.4691,\n longitude: 126.4505,\n name: \"Seoul Incheon\",\n tz: \"Asia/Seoul\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"RPLL\",\n country: \"PH\",\n ghcnh_id: null,\n icao: \"RPLL\",\n latitude: 14.5086,\n longitude: 121.0197,\n name: \"Manila Ninoy Aquino International\",\n tz: \"Asia/Manila\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"SAEZ\",\n country: \"AR\",\n ghcnh_id: null,\n icao: \"SAEZ\",\n latitude: -34.8222,\n longitude: -58.5358,\n name: \"Buenos Aires Ezeiza\",\n tz: \"America/Argentina/Buenos_Aires\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"SBGR\",\n country: \"BR\",\n ghcnh_id: null,\n icao: \"SBGR\",\n latitude: -23.4356,\n longitude: -46.4731,\n name: \"São Paulo Guarulhos\",\n tz: \"America/Sao_Paulo\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"UUEE\",\n country: \"RU\",\n ghcnh_id: null,\n icao: \"UUEE\",\n latitude: 55.9728,\n longitude: 37.4147,\n name: \"Moscow Sheremetyevo\",\n tz: \"Europe/Moscow\",\n venues: [],\n },\n {\n code: \"UUWW\",\n country: \"RU\",\n ghcnh_id: null,\n icao: \"UUWW\",\n latitude: 55.5915,\n longitude: 37.2615,\n name: \"Moscow Vnukovo\",\n tz: \"Europe/Moscow\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"VABB\",\n country: \"IN\",\n ghcnh_id: null,\n icao: \"VABB\",\n latitude: 19.0887,\n longitude: 72.8679,\n name: \"Mumbai Chhatrapati Shivaji\",\n tz: \"Asia/Kolkata\",\n venues: [],\n },\n {\n code: \"VHHH\",\n country: \"HK\",\n ghcnh_id: null,\n icao: \"VHHH\",\n latitude: 22.308,\n longitude: 113.9185,\n name: \"Hong Kong International\",\n tz: \"Asia/Hong_Kong\",\n venues: [],\n },\n {\n code: \"VIDP\",\n country: \"IN\",\n ghcnh_id: null,\n icao: \"VIDP\",\n latitude: 28.5562,\n longitude: 77.1,\n name: \"Delhi Indira Gandhi\",\n tz: \"Asia/Kolkata\",\n venues: [],\n },\n {\n code: \"VILK\",\n country: \"IN\",\n ghcnh_id: null,\n icao: \"VILK\",\n latitude: 26.7606,\n longitude: 80.8893,\n name: \"Lucknow Chaudhary Charan Singh International\",\n tz: \"Asia/Kolkata\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"VTBS\",\n country: \"TH\",\n ghcnh_id: null,\n icao: \"VTBS\",\n latitude: 13.69,\n longitude: 100.7501,\n name: \"Bangkok Suvarnabhumi\",\n tz: \"Asia/Bangkok\",\n venues: [],\n },\n {\n code: \"WMKK\",\n country: \"MY\",\n ghcnh_id: null,\n icao: \"WMKK\",\n latitude: 2.7456,\n longitude: 101.7099,\n name: \"Kuala Lumpur International\",\n tz: \"Asia/Kuala_Lumpur\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"WSSS\",\n country: \"SG\",\n ghcnh_id: null,\n icao: \"WSSS\",\n latitude: 1.3644,\n longitude: 103.9915,\n name: \"Singapore Changi\",\n tz: \"Asia/Singapore\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"YBBN\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YBBN\",\n latitude: -27.3842,\n longitude: 153.1175,\n name: \"Brisbane\",\n tz: \"Australia/Brisbane\",\n venues: [],\n },\n {\n code: \"YMML\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YMML\",\n latitude: -37.6733,\n longitude: 144.8433,\n name: \"Melbourne Tullamarine\",\n tz: \"Australia/Melbourne\",\n venues: [],\n },\n {\n code: \"YSSY\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YSSY\",\n latitude: -33.9461,\n longitude: 151.1772,\n name: \"Sydney Kingsford Smith\",\n tz: \"Australia/Sydney\",\n venues: [],\n },\n {\n code: \"ZBAA\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZBAA\",\n latitude: 40.0801,\n longitude: 116.5846,\n name: \"Beijing Capital\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZGGG\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZGGG\",\n latitude: 23.3924,\n longitude: 113.2988,\n name: \"Guangzhou Baiyun International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZGSZ\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZGSZ\",\n latitude: 22.6393,\n longitude: 113.8108,\n name: \"Shenzhen Bao'an International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZHCC\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZHCC\",\n latitude: 34.5197,\n longitude: 113.8408,\n name: \"Zhengzhou Xinzheng International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZHHH\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZHHH\",\n latitude: 30.7838,\n longitude: 114.2081,\n name: \"Wuhan Tianhe International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZSJN\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZSJN\",\n latitude: 36.8572,\n longitude: 117.2161,\n name: \"Jinan Yaoqiang International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZSPD\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZSPD\",\n latitude: 31.1443,\n longitude: 121.8083,\n name: \"Shanghai Pudong\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZSQD\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZSQD\",\n latitude: 36.3614,\n longitude: 120.0867,\n name: \"Qingdao Jiaodong International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZUCK\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZUCK\",\n latitude: 29.7192,\n longitude: 106.6417,\n name: \"Chongqing Jiangbei International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n {\n code: \"ZUUU\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZUUU\",\n latitude: 30.5785,\n longitude: 103.9471,\n name: \"Chengdu Shuangliu International\",\n tz: \"Asia/Shanghai\",\n venues: [\n \"polymarket\",\n ],\n },\n] as const;\n\nexport const STATION_BY_CODE: ReadonlyMap<string, StationInfo> = new Map<string, StationInfo>([\n [\"ATL\", STATIONS[13]!],\n [\"AUS\", STATIONS[14]!],\n [\"BKF\", STATIONS[15]!],\n [\"BNA\", STATIONS[16]!],\n [\"BOS\", STATIONS[17]!],\n [\"CVG\", STATIONS[18]!],\n [\"CYYZ\", STATIONS[0]!],\n [\"DAL\", STATIONS[19]!],\n [\"DCA\", STATIONS[20]!],\n [\"DEN\", STATIONS[21]!],\n [\"DFW\", STATIONS[22]!],\n [\"DTW\", STATIONS[23]!],\n [\"EDDB\", STATIONS[1]!],\n [\"EDDF\", STATIONS[2]!],\n [\"EDDM\", STATIONS[3]!],\n [\"EFHK\", STATIONS[4]!],\n [\"EGKK\", STATIONS[5]!],\n [\"EGLC\", STATIONS[6]!],\n [\"EGLL\", STATIONS[7]!],\n [\"EHAM\", STATIONS[8]!],\n [\"EKCH\", STATIONS[9]!],\n [\"EPWA\", STATIONS[10]!],\n [\"ESSA\", STATIONS[11]!],\n [\"FACT\", STATIONS[12]!],\n [\"HOU\", STATIONS[24]!],\n [\"IAH\", STATIONS[25]!],\n [\"LAS\", STATIONS[26]!],\n [\"LAX\", STATIONS[27]!],\n [\"LEBL\", STATIONS[42]!],\n [\"LEMD\", STATIONS[43]!],\n [\"LFPB\", STATIONS[44]!],\n [\"LFPG\", STATIONS[45]!],\n [\"LFPO\", STATIONS[46]!],\n [\"LGA\", STATIONS[28]!],\n [\"LIMC\", STATIONS[47]!],\n [\"LIRF\", STATIONS[48]!],\n [\"LLBG\", STATIONS[49]!],\n [\"LOWW\", STATIONS[50]!],\n [\"LSZH\", STATIONS[51]!],\n [\"LTAC\", STATIONS[52]!],\n [\"LTFM\", STATIONS[53]!],\n [\"MDW\", STATIONS[29]!],\n [\"MIA\", STATIONS[30]!],\n [\"MMMX\", STATIONS[54]!],\n [\"MPMG\", STATIONS[55]!],\n [\"MSP\", STATIONS[31]!],\n [\"MSY\", STATIONS[32]!],\n [\"NYC\", STATIONS[33]!],\n [\"NZAA\", STATIONS[56]!],\n [\"NZWN\", STATIONS[57]!],\n [\"OEJN\", STATIONS[58]!],\n [\"OERK\", STATIONS[59]!],\n [\"OKC\", STATIONS[34]!],\n [\"OMDB\", STATIONS[60]!],\n [\"OPKC\", STATIONS[61]!],\n [\"ORD\", STATIONS[35]!],\n [\"OTHH\", STATIONS[62]!],\n [\"PHL\", STATIONS[36]!],\n [\"PHX\", STATIONS[37]!],\n [\"RCSS\", STATIONS[63]!],\n [\"RCTP\", STATIONS[64]!],\n [\"RJAA\", STATIONS[65]!],\n [\"RJTT\", STATIONS[66]!],\n [\"RKPK\", STATIONS[67]!],\n [\"RKSI\", STATIONS[68]!],\n [\"RPLL\", STATIONS[69]!],\n [\"SAEZ\", STATIONS[70]!],\n [\"SAT\", STATIONS[38]!],\n [\"SBGR\", STATIONS[71]!],\n [\"SEA\", STATIONS[39]!],\n [\"SFO\", STATIONS[40]!],\n [\"SLC\", STATIONS[41]!],\n [\"UUEE\", STATIONS[72]!],\n [\"UUWW\", STATIONS[73]!],\n [\"VABB\", STATIONS[74]!],\n [\"VHHH\", STATIONS[75]!],\n [\"VIDP\", STATIONS[76]!],\n [\"VILK\", STATIONS[77]!],\n [\"VTBS\", STATIONS[78]!],\n [\"WMKK\", STATIONS[79]!],\n [\"WSSS\", STATIONS[80]!],\n [\"YBBN\", STATIONS[81]!],\n [\"YMML\", STATIONS[82]!],\n [\"YSSY\", STATIONS[83]!],\n [\"ZBAA\", STATIONS[84]!],\n [\"ZGGG\", STATIONS[85]!],\n [\"ZGSZ\", STATIONS[86]!],\n [\"ZHCC\", STATIONS[87]!],\n [\"ZHHH\", STATIONS[88]!],\n [\"ZSJN\", STATIONS[89]!],\n [\"ZSPD\", STATIONS[90]!],\n [\"ZSQD\", STATIONS[91]!],\n [\"ZUCK\", STATIONS[92]!],\n [\"ZUUU\", STATIONS[93]!],\n]);\n\nexport const STATION_BY_ICAO: ReadonlyMap<string, StationInfo> = new Map<string, StationInfo>([\n [\"CYYZ\", STATIONS[0]!],\n [\"EDDB\", STATIONS[1]!],\n [\"EDDF\", STATIONS[2]!],\n [\"EDDM\", STATIONS[3]!],\n [\"EFHK\", STATIONS[4]!],\n [\"EGKK\", STATIONS[5]!],\n [\"EGLC\", STATIONS[6]!],\n [\"EGLL\", STATIONS[7]!],\n [\"EHAM\", STATIONS[8]!],\n [\"EKCH\", STATIONS[9]!],\n [\"EPWA\", STATIONS[10]!],\n [\"ESSA\", STATIONS[11]!],\n [\"FACT\", STATIONS[12]!],\n [\"KATL\", STATIONS[13]!],\n [\"KAUS\", STATIONS[14]!],\n [\"KBKF\", STATIONS[15]!],\n [\"KBNA\", STATIONS[16]!],\n [\"KBOS\", STATIONS[17]!],\n [\"KCVG\", STATIONS[18]!],\n [\"KDAL\", STATIONS[19]!],\n [\"KDCA\", STATIONS[20]!],\n [\"KDEN\", STATIONS[21]!],\n [\"KDFW\", STATIONS[22]!],\n [\"KDTW\", STATIONS[23]!],\n [\"KHOU\", STATIONS[24]!],\n [\"KIAH\", STATIONS[25]!],\n [\"KLAS\", STATIONS[26]!],\n [\"KLAX\", STATIONS[27]!],\n [\"KLGA\", STATIONS[28]!],\n [\"KMDW\", STATIONS[29]!],\n [\"KMIA\", STATIONS[30]!],\n [\"KMSP\", STATIONS[31]!],\n [\"KMSY\", STATIONS[32]!],\n [\"KNYC\", STATIONS[33]!],\n [\"KOKC\", STATIONS[34]!],\n [\"KORD\", STATIONS[35]!],\n [\"KPHL\", STATIONS[36]!],\n [\"KPHX\", STATIONS[37]!],\n [\"KSAT\", STATIONS[38]!],\n [\"KSEA\", STATIONS[39]!],\n [\"KSFO\", STATIONS[40]!],\n [\"KSLC\", STATIONS[41]!],\n [\"LEBL\", STATIONS[42]!],\n [\"LEMD\", STATIONS[43]!],\n [\"LFPB\", STATIONS[44]!],\n [\"LFPG\", STATIONS[45]!],\n [\"LFPO\", STATIONS[46]!],\n [\"LIMC\", STATIONS[47]!],\n [\"LIRF\", STATIONS[48]!],\n [\"LLBG\", STATIONS[49]!],\n [\"LOWW\", STATIONS[50]!],\n [\"LSZH\", STATIONS[51]!],\n [\"LTAC\", STATIONS[52]!],\n [\"LTFM\", STATIONS[53]!],\n [\"MMMX\", STATIONS[54]!],\n [\"MPMG\", STATIONS[55]!],\n [\"NZAA\", STATIONS[56]!],\n [\"NZWN\", STATIONS[57]!],\n [\"OEJN\", STATIONS[58]!],\n [\"OERK\", STATIONS[59]!],\n [\"OMDB\", STATIONS[60]!],\n [\"OPKC\", STATIONS[61]!],\n [\"OTHH\", STATIONS[62]!],\n [\"RCSS\", STATIONS[63]!],\n [\"RCTP\", STATIONS[64]!],\n [\"RJAA\", STATIONS[65]!],\n [\"RJTT\", STATIONS[66]!],\n [\"RKPK\", STATIONS[67]!],\n [\"RKSI\", STATIONS[68]!],\n [\"RPLL\", STATIONS[69]!],\n [\"SAEZ\", STATIONS[70]!],\n [\"SBGR\", STATIONS[71]!],\n [\"UUEE\", STATIONS[72]!],\n [\"UUWW\", STATIONS[73]!],\n [\"VABB\", STATIONS[74]!],\n [\"VHHH\", STATIONS[75]!],\n [\"VIDP\", STATIONS[76]!],\n [\"VILK\", STATIONS[77]!],\n [\"VTBS\", STATIONS[78]!],\n [\"WMKK\", STATIONS[79]!],\n [\"WSSS\", STATIONS[80]!],\n [\"YBBN\", STATIONS[81]!],\n [\"YMML\", STATIONS[82]!],\n [\"YSSY\", STATIONS[83]!],\n [\"ZBAA\", STATIONS[84]!],\n [\"ZGGG\", STATIONS[85]!],\n [\"ZGSZ\", STATIONS[86]!],\n [\"ZHCC\", STATIONS[87]!],\n [\"ZHHH\", STATIONS[88]!],\n [\"ZSJN\", STATIONS[89]!],\n [\"ZSPD\", STATIONS[90]!],\n [\"ZSQD\", STATIONS[91]!],\n [\"ZUCK\", STATIONS[92]!],\n [\"ZUUU\", STATIONS[93]!],\n]);\n","// TS-W6 Wave 1 — availability(station, cache) reading from CacheStore.\n//\n// Ports Python `mostlyright.discovery.availability` semantics. Python walks the\n// on-disk parquet hierarchy; TS uses the same canonical cache-key shape so the\n// CacheStore implementation (Memory / IndexedDB / Fs) is the persistence layer.\n//\n// The keys we scan match `cacheKeyForObservations(station, year, month, source?)`\n// and `cacheKeyForClimate(station, year)`. @mostlyrightmd/meta's `research()` writes\n// cache entries under the 3-letter NWS code (`resolved.code` from\n// STATION_BY_ICAO / STATION_BY_CODE) for US stations — e.g. `KNYC` resolves to\n// `NYC` and the cache key reads `...:observations:NYC:...`. Codex iter-2 P2:\n// availability resolves the input the same way so `availability(\"KNYC\", cache)`\n// finds entries written by `research(\"KNYC\", ...)`.\n\nimport { STATION_BY_CODE, STATION_BY_ICAO } from \"../data/generated/stations.js\";\nimport type { CacheStore } from \"../internal/cache/index.js\";\n\n/**\n * Cache-coverage summary for a station.\n *\n * Mirrors Python `availability()` return shape.\n */\nexport interface AvailabilityResult {\n station: string;\n /** Count of distinct (year, month) observation cache entries. */\n monthsCached: number;\n /** Earliest cached month as `\"YYYY-MM\"`, or null if none. */\n firstMonth: string | null;\n /** Latest cached month as `\"YYYY-MM\"`, or null if none. */\n lastMonth: string | null;\n /** Count of cached climate years. */\n climateYears: number;\n /** Earliest cached climate year as `\"YYYY\"`, or null if none. */\n firstClimateYear: string | null;\n /** Latest cached climate year as `\"YYYY\"`, or null if none. */\n lastClimateYear: string | null;\n}\n\n/**\n * Optional adapter that lets `availability()` enumerate keys from a store.\n *\n * CacheStore's mandatory contract is opaque key-value: get/set/delete/withLock.\n * Discovery needs to enumerate which keys exist for a station — this is\n * implementation-specific (Memory iterates its Map, IndexedDB uses\n * `getAllKeys`, Fs walks the directory tree). Stores that support enumeration\n * implement the optional `listKeys(prefix)` method and `availability()` uses\n * it; stores without it return zero-coverage but never throw.\n *\n * Listed keys may exceed the requested prefix in the result (callers filter);\n * `listKeys` is best-effort.\n */\nexport interface KeyEnumerableStore extends CacheStore {\n listKeys(prefix: string): Promise<ReadonlyArray<string>>;\n}\n\nfunction hasListKeys(store: CacheStore): store is KeyEnumerableStore {\n return typeof (store as KeyEnumerableStore).listKeys === \"function\";\n}\n\nconst STATION_RE = /^[A-Z0-9]{3,5}$/;\n\n/**\n * Resolve `station` to the canonical CACHE-KEY station code.\n *\n * - For known stations: returns the 3-letter NWS `code` (e.g. `KNYC` → `NYC`)\n * if one exists, falling back to the 4-letter ICAO. This matches the cache\n * key that `research()` writes for US stations via `resolved.code` and\n * international stations via `resolved.icao` (no NWS code exists).\n * - For unknown inputs that still satisfy the 3-5 char alphanumeric format:\n * returns the upper-cased input. This lets bespoke callers query custom\n * keys without coupling availability to the station registry.\n */\nfunction normalizeStation(station: string): string {\n const upper = station.toUpperCase();\n if (!STATION_RE.test(upper)) {\n throw new RangeError(\n `availability: station must be a 3-5 char alphanumeric code; got ${JSON.stringify(station)}`,\n );\n }\n const byIcao = STATION_BY_ICAO.get(upper);\n if (byIcao !== undefined) {\n // US stations: NWS code is the cache-key form. International stations:\n // no NWS code, ICAO is the cache-key form.\n return byIcao.code ?? byIcao.icao;\n }\n const byCode = STATION_BY_CODE.get(upper);\n if (byCode !== undefined) {\n return byCode.code ?? byCode.icao;\n }\n // Bespoke / unknown codes — pass through. availability() returns\n // zero-coverage if the cache doesn't have entries under this exact key.\n return upper;\n}\n\nconst OBS_KEY_RE = /^mostlyright:v1:observations:([A-Z0-9]+):(\\d{4}):(\\d{2})(?::[a-z0-9_-]+)?$/;\nconst CLIMATE_KEY_RE = /^mostlyright:v1:climate:([A-Z0-9]+):(\\d{4})$/;\n\n/**\n * Options for `availability()`.\n */\nexport interface AvailabilityOptions {\n /**\n * If true, confirm each candidate key with `cache.get()` before counting.\n * Eliminates the small overcount possible on stores whose `listKeys()` can\n * return keys with already-expired TTL entries (FsStore and IndexedDBStore\n * lazy-evict on `get`, not on `listKeys` — codex iter-3 P2). Off by default\n * because the v0.1.0 `research()` flow never writes with `ttlMs`, so the\n * overcount window is empty; turn on only if you populate the cache with\n * explicit TTLs.\n *\n * Cost: one `get()` per matching key. On warm caches this is cheap\n * (MemoryStore + IndexedDBStore in-memory). On FsStore it reads each\n * candidate's file.\n */\n readonly validate?: boolean;\n}\n\n/**\n * Return a summary of cached coverage for `station`.\n *\n * Stores without enumeration support return a zero-coverage result with the\n * station name populated (counts all zero, dates null).\n *\n * Pass `{ validate: true }` to confirm each candidate key via `cache.get()`\n * — needed if your callers populate the cache with `ttlMs` and might query\n * after expiry. The v0.1.0 `research()` flow does not use `ttlMs`, so the\n * default (fast scan, no validation) is correct for the canonical path.\n */\nexport async function availability(\n station: string,\n cache: CacheStore,\n opts: AvailabilityOptions = {},\n): Promise<AvailabilityResult> {\n const stationCode = normalizeStation(station);\n const empty: AvailabilityResult = Object.freeze({\n station: stationCode,\n monthsCached: 0,\n firstMonth: null,\n lastMonth: null,\n climateYears: 0,\n firstClimateYear: null,\n lastClimateYear: null,\n });\n\n if (!hasListKeys(cache)) {\n return empty;\n }\n\n // Scan both the canonical cache-key form AND the original upper-cased\n // input (when they differ — e.g. user passed \"KNYC\" → normalized \"NYC\";\n // scan \":NYC:\" AND \":KNYC:\"). Codex iter-5 P2: a caller using the\n // documented `cacheKeyForObservations(\"KNYC\", ...)` helper writes under\n // :KNYC:, which the normalized prefix would miss.\n const upperInput = station.toUpperCase();\n const scanCodes = upperInput === stationCode ? [stationCode] : [stationCode, upperInput];\n\n const obsPrefixes = scanCodes.map((c) => `mostlyright:v1:observations:${c}:`);\n const climatePrefixes = scanCodes.map((c) => `mostlyright:v1:climate:${c}:`);\n\n const obsKeySets = await Promise.all(obsPrefixes.map((p) => cache.listKeys(p)));\n const climateKeySets = await Promise.all(climatePrefixes.map((p) => cache.listKeys(p)));\n const obsKeys = obsKeySets.flat();\n const climateKeys = climateKeySets.flat();\n\n // Collect the matching keys grouped by (year-month) / year so we can both\n // dedupe (e.g. per-source observation keys for the same month) and run a\n // single validation get() per group.\n const monthCandidates = new Map<string, string[]>();\n for (const key of obsKeys) {\n const m = OBS_KEY_RE.exec(key);\n if (m === null) continue;\n const keyStation = m[1] as string;\n if (!scanCodes.includes(keyStation)) continue;\n const ym = `${m[2]}-${m[3]}`;\n const arr = monthCandidates.get(ym) ?? [];\n arr.push(key);\n monthCandidates.set(ym, arr);\n }\n\n const yearCandidates = new Map<string, string[]>();\n for (const key of climateKeys) {\n const m = CLIMATE_KEY_RE.exec(key);\n if (m === null) continue;\n const keyStation = m[1] as string;\n if (!scanCodes.includes(keyStation)) continue;\n const y = m[2] as string;\n const arr = yearCandidates.get(y) ?? [];\n arr.push(key);\n yearCandidates.set(y, arr);\n }\n\n let months: string[];\n let years: string[];\n\n if (opts.validate === true) {\n // For each candidate group, confirm at least one key still resolves.\n // Stores lazy-evict expired entries inside get() — calling it discards\n // stale TTLs from the on-disk / on-IDB state and gives us a correct\n // overall count.\n const monthChecks = await Promise.all(\n [...monthCandidates.entries()].map(async ([ym, keys]) => {\n for (const k of keys) {\n if ((await cache.get(k)) !== null) return ym;\n }\n return null;\n }),\n );\n months = monthChecks.filter((v): v is string => v !== null).sort();\n const yearChecks = await Promise.all(\n [...yearCandidates.entries()].map(async ([y, keys]) => {\n for (const k of keys) {\n if ((await cache.get(k)) !== null) return y;\n }\n return null;\n }),\n );\n years = yearChecks.filter((v): v is string => v !== null).sort();\n } else {\n months = [...monthCandidates.keys()].sort();\n years = [...yearCandidates.keys()].sort();\n }\n\n return Object.freeze({\n station: stationCode,\n monthsCached: months.length,\n firstMonth: months[0] ?? null,\n lastMonth: months.at(-1) ?? null,\n climateYears: years.length,\n firstClimateYear: years[0] ?? null,\n lastClimateYear: years.at(-1) ?? null,\n });\n}\n","// TS-W6 Wave 2 — internationalDailyExtremes rollup.\n//\n// Ports Python `mostlyright.international.daily_extremes` semantics:\n//\n// - For each row, parse `observed_at` as UTC, convert to the station's IANA\n// local calendar date via `Intl.DateTimeFormat` (the only universally-\n// available tz-aware extractor in JS), bucket per `(localDate)`.\n// - For each bucketed day:\n// * n_obs < 12 → tmin/tmax/tmean null (low coverage; matches Python\n// `_LOW_COVERAGE_THRESHOLD`).\n// * Otherwise: tmin = min(temp_c), tmax = max(temp_c), tmean = mean.\n// Round HALF_UP — to 1 decimal for US stations, whole °C for intl.\n// - precip_mm summed across rows that report it (mm — matches the\n// observation schema field name; Python uses `precip_inches` because its\n// historical units are inches, but the TS schema is mm).\n//\n// `stationTz` is required because the input rows are raw observations (no\n// station registry lookup here); callers supply the IANA tz string for the\n// station they're rolling up.\n\nconst LOW_COVERAGE_THRESHOLD = 12;\n\n/** Minimal row shape consumed by `internationalDailyExtremes`. */\nexport interface InternationalRow {\n /** ISO 8601 UTC instant. Must end with `Z` or include an offset. */\n observed_at?: string | null;\n /** Air temperature in degrees Celsius. */\n temp_c?: number | null;\n /** 1-hour precipitation total in millimeters. */\n precip_mm_1h?: number | null;\n /** Source identifier (preserved on the tmin/tmax aggregate). */\n source?: string | null;\n}\n\nexport interface DailyExtreme {\n /** Station-local calendar date as `YYYY-MM-DD`. */\n localDate: string;\n /** Count of rows with a parseable temp_c. */\n nObs: number;\n /** Min temperature in °C, or null on low coverage. */\n tempMinC: number | null;\n /** Max temperature in °C, or null on low coverage. */\n tempMaxC: number | null;\n /** Mean temperature in °C, or null on low coverage. */\n tempMeanC: number | null;\n /** Min temperature in °F, or null on low coverage. */\n tempMinF: number | null;\n /** Max temperature in °F, or null on low coverage. */\n tempMaxF: number | null;\n /** Total 1-hour precipitation across the local day, in mm. */\n precipMm: number;\n /** Source identifier of the row that produced tmin (or null on low coverage). */\n sourceTmin: string | null;\n /** Source identifier of the row that produced tmax (or null on low coverage). */\n sourceTmax: string | null;\n}\n\nexport interface InternationalDailyExtremesOptions {\n /** IANA timezone identifier for the station, e.g. `\"Asia/Tokyo\"`. Required. */\n stationTz: string;\n /**\n * Decimal places for HALF_UP rounding. Defaults to 0 (whole °C) — the\n * international convention. Pass `1` for US-station tenths.\n */\n precision?: number;\n /**\n * Minimum number of observations required for tmin/tmax/tmean to be\n * populated. Defaults to 12 (the Python threshold). Tests can override.\n */\n minObs?: number;\n}\n\nconst PARTS_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nfunction getDateFormatter(tz: string): Intl.DateTimeFormat {\n let f = PARTS_CACHE.get(tz);\n if (f === undefined) {\n // `formatToParts` with these options yields `{year, month, day}` parts\n // for the given UTC instant in the requested tz. The result is the\n // local calendar date even across DST and arbitrary UTC offsets.\n f = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: tz,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n });\n PARTS_CACHE.set(tz, f);\n }\n return f;\n}\n\nfunction localDateFor(instant: Date, tz: string): string {\n const parts = getDateFormatter(tz).formatToParts(instant);\n let y = \"\";\n let m = \"\";\n let d = \"\";\n for (const p of parts) {\n if (p.type === \"year\") y = p.value;\n else if (p.type === \"month\") m = p.value;\n else if (p.type === \"day\") d = p.value;\n }\n return `${y}-${m}-${d}`;\n}\n\nfunction parseInstant(observed: string | null | undefined): Date | null {\n if (observed === undefined || observed === null || observed.length === 0) {\n return null;\n }\n const ms = Date.parse(observed);\n if (Number.isNaN(ms)) return null;\n return new Date(ms);\n}\n\nfunction roundHalfUp(value: number, places: number): number {\n if (!Number.isFinite(value)) return value;\n // HALF_UP rounding: tie-breaks always round away from zero for positives,\n // toward +∞ for negatives. JS `Math.round` rounds half toward +∞, which\n // disagrees with HALF_UP on negative .5 boundaries; replicate the Python\n // Decimal behavior by adjusting positives only and mirroring negatives.\n const scale = 10 ** places;\n const sign = value < 0 ? -1 : 1;\n const abs = Math.abs(value);\n // Add a tiny epsilon scaled to the magnitude to defeat IEEE-754 errors that\n // make `2.675 * 100` come out as `267.49999...`. The epsilon is small\n // enough (relative-1e-12) not to affect legitimate non-tie values.\n const rounded = Math.floor(abs * scale + 0.5 + abs * 1e-12) / scale;\n return sign * rounded;\n}\n\nfunction cToF(c: number): number {\n return c * 1.8 + 32;\n}\n\n/**\n * Roll up observation rows to per-local-calendar-day temperature extremes.\n *\n * @param rows raw observation rows (any source). Rows without a parseable\n * `observed_at` are dropped.\n * @param opts `stationTz` is required. Optional `precision` (default 0;\n * pass 1 for US-station tenths) and `minObs` (default 12).\n *\n * @returns one entry per local calendar day with at least one row. Days\n * with fewer than `minObs` rows have temps set to null.\n */\nexport function internationalDailyExtremes(\n rows: ReadonlyArray<InternationalRow>,\n opts: InternationalDailyExtremesOptions,\n): DailyExtreme[] {\n const tz = opts.stationTz;\n if (typeof tz !== \"string\" || tz.length === 0) {\n throw new RangeError(\"internationalDailyExtremes: stationTz is required (non-empty string)\");\n }\n // Phase 18: integer-°F lattice rationale.\n // For US stations (ASOS), constituent observations carry temp_c values\n // recovered from Tgroup tenths-°C (e.g. 10.0, 11.1, 12.2 from integer °F\n // 50, 52, 54 — Phase 18 PREC-01/PREC-02). tmin/tmax = min/max of those\n // values are themselves on the integer-°F lattice, and 0.1°C HALF_UP\n // rounding is a no-op. tmean IS a non-lattice average and benefits from\n // 0.1°C rounding. For international stations (no Tgroup), constituent\n // values are derived floats and rounding to whole °C (`precision = 0`) is\n // the convention.\n //\n // Callers pass `precision: 1` for US ASOS data and `precision: 0` (the\n // default) for international. See\n // .planning/phases/18-precision-fix-asos-integer-fahrenheit/18-CONTEXT.md.\n const precision = opts.precision ?? 0;\n const minObs = opts.minObs ?? LOW_COVERAGE_THRESHOLD;\n\n // Validate tz up front so we get a clean error rather than per-row failures.\n try {\n getDateFormatter(tz);\n } catch (e) {\n throw new RangeError(\n `internationalDailyExtremes: invalid stationTz ${JSON.stringify(tz)}: ${(e as Error).message}`,\n );\n }\n\n type Bucket = {\n temps: { value: number; source: string | null }[];\n precipMm: number;\n };\n const byLocalDate = new Map<string, Bucket>();\n\n for (const row of rows) {\n const instant = parseInstant(row.observed_at);\n if (instant === null) continue;\n const localDate = localDateFor(instant, tz);\n let bucket = byLocalDate.get(localDate);\n if (bucket === undefined) {\n bucket = { temps: [], precipMm: 0 };\n byLocalDate.set(localDate, bucket);\n }\n const t = row.temp_c;\n if (typeof t === \"number\" && Number.isFinite(t)) {\n bucket.temps.push({ value: t, source: row.source ?? null });\n }\n const p = row.precip_mm_1h;\n if (typeof p === \"number\" && Number.isFinite(p)) {\n bucket.precipMm += p;\n }\n }\n\n const out: DailyExtreme[] = [];\n const sortedDates = [...byLocalDate.keys()].sort();\n for (const localDate of sortedDates) {\n const bucket = byLocalDate.get(localDate);\n if (bucket === undefined) continue;\n const nObs = bucket.temps.length;\n let tempMinC: number | null = null;\n let tempMaxC: number | null = null;\n let tempMeanC: number | null = null;\n let sourceTmin: string | null = null;\n let sourceTmax: string | null = null;\n\n // Codex iter-4 P2: `nObs >= minObs` alone is not enough when minObs=0,\n // because a day with a parseable timestamp but no finite temp_c reaches\n // this branch with nObs === 0 and then dereferences bucket.temps[0].\n // Always require at least one temperature row before computing extremes.\n if (nObs > 0 && nObs >= minObs) {\n let minIdx = 0;\n let maxIdx = 0;\n let sum = 0;\n for (let i = 0; i < bucket.temps.length; i += 1) {\n const v = bucket.temps[i] as { value: number; source: string | null };\n sum += v.value;\n const minRow = bucket.temps[minIdx] as { value: number };\n const maxRow = bucket.temps[maxIdx] as { value: number };\n if (v.value < minRow.value) minIdx = i;\n if (v.value > maxRow.value) maxIdx = i;\n }\n const mean = sum / nObs;\n const minRow = bucket.temps[minIdx] as { value: number; source: string | null };\n const maxRow = bucket.temps[maxIdx] as { value: number; source: string | null };\n tempMinC = roundHalfUp(minRow.value, precision);\n tempMaxC = roundHalfUp(maxRow.value, precision);\n tempMeanC = roundHalfUp(mean, precision);\n sourceTmin = minRow.source;\n sourceTmax = maxRow.source;\n }\n\n out.push(\n Object.freeze({\n localDate,\n nObs,\n tempMinC,\n tempMaxC,\n tempMeanC,\n tempMinF: tempMinC === null ? null : roundHalfUp(cToF(tempMinC), precision),\n tempMaxF: tempMaxC === null ? null : roundHalfUp(cToF(tempMaxC), precision),\n precipMm: roundHalfUp(bucket.precipMm, 4),\n sourceTmin,\n sourceTmax,\n }),\n );\n }\n\n return out;\n}\n","// Structured exception hierarchy for the mostlyright TS SDK.\n//\n// Mirrors the Python design in `packages/core/src/mostlyright/core/exceptions.py`\n// and `packages/core/src/mostlyright/_internal/exceptions.py`. Every error\n// subclasses `MostlyRightError` and exposes a `toDict()` method that returns a\n// JSON-safe payload suitable for MCP `error.data` / extension messaging.\n//\n// Role-name vocabulary for SourceMismatchError matches Python:\n// \"observations\" / \"forecasts\" / \"settlement\" (long form, NOT the col prefixes)\n\n// ---------------------------------------------------------------------------\n// JSON-safe coercion (mirrors `mostlyright.core._json_safe.to_json_safe`)\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively coerce `value` into a JSON-serializable structure.\n *\n * Coercion rules (mirrors Python's `to_json_safe`):\n * - `null` / `undefined` / `NaN` / `Infinity` / `-Infinity` → `null`\n * - `Date` → ISO 8601 UTC string ending in `Z`\n * - Numeric / boolean / string scalars pass through (non-finite numbers → null)\n * - Arrays + plain objects → recursive (cycles → `{ _cycle: true, value: String(obj) }`)\n * - Dict keys MUST be strings; non-string keys throw `TypeError`.\n * - Anything else (Symbol, function, class instance without `toJSON`) →\n * `{ _repr_only: true, value: String(value) }`.\n */\nexport function toJsonSafe(value: unknown, seen?: WeakSet<object>): unknown {\n const visited = seen ?? new WeakSet<object>();\n\n // null / undefined → null\n if (value === null || value === undefined) {\n return null;\n }\n\n // Booleans pass through.\n if (typeof value === \"boolean\") {\n return value;\n }\n\n // Strings pass through.\n if (typeof value === \"string\") {\n return value;\n }\n\n // Numbers — non-finite (NaN, +/-Infinity) coerce to null.\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n\n // bigint → number when safe, else stringify (JSON can't natively encode bigint).\n if (typeof value === \"bigint\") {\n // Match Python: integers pass through as native numeric. Safe-range only.\n if (value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER)) {\n return Number(value);\n }\n return { _repr_only: true, value: value.toString() };\n }\n\n // Date → ISO 8601 UTC string (always ending in \"Z\").\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n return null;\n }\n return value.toISOString();\n }\n\n // Arrays — recurse, track cycles.\n if (Array.isArray(value)) {\n if (visited.has(value)) {\n return { _cycle: true, value: String(value) };\n }\n visited.add(value);\n try {\n return value.map((item) => toJsonSafe(item, visited));\n } finally {\n visited.delete(value);\n }\n }\n\n // Plain objects — recurse, track cycles, enforce string keys.\n if (typeof value === \"object\") {\n if (visited.has(value as object)) {\n return { _cycle: true, value: String(value) };\n }\n visited.add(value as object);\n try {\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value as Record<string, unknown>)) {\n if (typeof key !== \"string\") {\n throw new TypeError(`toJsonSafe dict keys must be string; got ${typeof key}`);\n }\n out[key] = toJsonSafe((value as Record<string, unknown>)[key], visited);\n }\n return out;\n } finally {\n visited.delete(value as object);\n }\n }\n\n // Symbols, functions, etc. — repr-only marker.\n return { _repr_only: true, value: String(value) };\n}\n\n// ---------------------------------------------------------------------------\n// Base class\n// ---------------------------------------------------------------------------\n\nexport interface MostlyRightErrorOptions {\n errorCode?: string;\n source?: string | null;\n requestId?: string | null;\n}\n\n/**\n * Base class for all mostlyright structured errors.\n *\n * `errorCode` is a stable enum (e.g. \"SOURCE_UNAVAILABLE\") used by callers /\n * agents to branch on without parsing message text. `source` is the source id\n * involved (e.g. \"iem.archive\") when applicable, and `requestId` correlates a\n * JSON-RPC / MCP request id when applicable.\n */\nexport class MostlyRightError extends Error {\n /** Subclass override — the stable string enum surfaced via `errorCode`. */\n static defaultErrorCode = \"MOSTLYRIGHT_ERROR\";\n\n readonly errorCode: string;\n readonly source: string | null;\n readonly requestId: string | null;\n\n constructor(message = \"\", options: MostlyRightErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n const ctor = this.constructor as typeof MostlyRightError;\n this.errorCode = options.errorCode ?? ctor.defaultErrorCode;\n this.source = options.source ?? null;\n this.requestId = options.requestId ?? null;\n // Restore prototype chain after `Error` (needed for `instanceof` across\n // transpilation / ES5 targets).\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * Subclass hook returning the structured attributes for `toDict`.\n * Values are passed through `toJsonSafe` by `toDict()`, so subclasses\n * don't need to coerce values themselves.\n */\n protected payload(): Record<string, unknown> {\n return {\n error_code: this.errorCode,\n message: this.message,\n source: this.source,\n request_id: this.requestId,\n };\n }\n\n /** Return a JSON-safe dict suitable for MCP `error.data`. */\n toDict(): Record<string, unknown> {\n const safe = toJsonSafe(this.payload());\n return safe as Record<string, unknown>;\n }\n}\n\n// ---------------------------------------------------------------------------\n// SourceUnavailableError\n// ---------------------------------------------------------------------------\n\nexport interface SourceUnavailableErrorOptions extends MostlyRightErrorOptions {\n httpStatus?: number | null;\n retryable?: boolean;\n retryAfterS?: number | null;\n underlying?: string;\n url?: string | null;\n}\n\nexport class SourceUnavailableError extends MostlyRightError {\n static override defaultErrorCode = \"SOURCE_UNAVAILABLE\";\n\n readonly httpStatus: number | null;\n readonly retryable: boolean;\n readonly retryAfterS: number | null;\n readonly underlying: string;\n readonly url: string | null;\n\n constructor(message = \"\", options: SourceUnavailableErrorOptions = {}) {\n super(message, options);\n this.httpStatus = options.httpStatus ?? null;\n this.retryable = options.retryable ?? false;\n this.retryAfterS = options.retryAfterS ?? null;\n this.underlying = options.underlying ?? \"\";\n this.url = options.url ?? null;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n http_status: this.httpStatus,\n retryable: this.retryable,\n retry_after_s: this.retryAfterS,\n underlying: this.underlying,\n url: this.url,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// DataAvailabilityError (Phase 21 21-09)\n// ---------------------------------------------------------------------------\n//\n// Typed exception for \"I tried to fetch and got nothing usable\" — replaces\n// 3+ overloaded SourceUnavailableError sites where consumers had to parse\n// message strings to differentiate (rate-limit retry vs model-unavailable\n// hard-fail vs cache-miss re-fetch). The reason enum is shared lockstep\n// with Python (`mostlyright.core.exceptions.DataAvailabilityError`); drift\n// is the load-bearing risk.\n\n/** Shared reason enum — MUST match Python EXACTLY (Phase 21 D-04). */\nexport const DATA_AVAILABILITY_REASONS = [\n \"model_unavailable\",\n \"out_of_window\",\n \"cache_miss\",\n \"source_404\",\n \"source_5xx\",\n \"rate_limited\",\n] as const;\n\nexport type DataAvailabilityReason = (typeof DATA_AVAILABILITY_REASONS)[number];\n\nexport interface DataAvailabilityErrorOptions extends MostlyRightErrorOptions {\n reason: DataAvailabilityReason;\n hint: string;\n}\n\nexport class DataAvailabilityError extends MostlyRightError {\n static override defaultErrorCode = \"DATA_AVAILABILITY\";\n\n readonly reason: DataAvailabilityReason;\n readonly hint: string;\n\n constructor(options: DataAvailabilityErrorOptions) {\n if (!DATA_AVAILABILITY_REASONS.includes(options.reason)) {\n throw new RangeError(\n `DataAvailabilityError: unknown reason \"${String(options.reason)}\". ` +\n `Valid reasons: ${DATA_AVAILABILITY_REASONS.join(\", \")}`,\n );\n }\n if (typeof options.hint !== \"string\" || options.hint.length === 0) {\n throw new TypeError(\"DataAvailabilityError: hint is required and must be a non-empty string\");\n }\n const message = `[${options.reason}] ${options.hint}`;\n super(message, options);\n this.reason = options.reason;\n this.hint = options.hint;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n reason: this.reason,\n hint: this.hint,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// NwpNotAvailableError (Post-21-07 follow-up)\n// ---------------------------------------------------------------------------\n//\n// Subclass of DataAvailabilityError raised when the TS `forecastNwp()` stub\n// is called. Phase 21 21-07 routes the generic stub error through\n// DataAvailabilityError; this dedicated subclass adds:\n//\n// 1. instanceof-based dispatch — `catch (e) { if (e instanceof\n// NwpNotAvailableError) ... }` is cleaner than `e.reason ===\n// \"model_unavailable\" && e.source === \"nwp-stub\"`.\n// 2. IDE autocomplete on `.model` + `.station` — narrows the payload so\n// consumers don't have to parse `e.hint` to retrieve them.\n// 3. A typed compile-time signal: `forecastNwp()` returns\n// `Promise<never>`, but the throw site declares `@throws\n// NwpNotAvailableError` so JSDoc tooling surfaces the deferral up-front.\n//\n// Back-compat: NwpNotAvailableError IS-A DataAvailabilityError with\n// reason=\"model_unavailable\", so existing `catch (e) { if (e instanceof\n// DataAvailabilityError && e.reason === \"model_unavailable\") ... }` paths\n// continue to work unchanged.\n\nexport interface NwpNotAvailableErrorOptions extends MostlyRightErrorOptions {\n /** Station the caller asked for (echoed back for log/error attribution). */\n station: string;\n /** NWP model the caller asked for (e.g. `\"gfs\"`, `\"hrrr\"`). */\n model: string;\n /** Operator-actionable hint. Required (matches DataAvailabilityError contract). */\n hint: string;\n}\n\n/**\n * Raised when the TS `forecastNwp()` stub is called.\n *\n * **Why this exists:** no production-ready browser GRIB2 decoder ships in\n * v1.x (eccodes / cfgrib are C/Python only; WASM compile-time + bundle\n * size make a browser port impractical today). The function signature is\n * stable so callers can write code today; v2.0+ lands the execution body.\n *\n * **Recommended catch pattern:**\n *\n * ```ts\n * import { forecastNwp } from '@mostlyrightmd/weather';\n * import { NwpNotAvailableError } from '@mostlyrightmd/core';\n *\n * try {\n * const grid = await forecastNwp('KNYC', 'gfs');\n * } catch (e) {\n * if (e instanceof NwpNotAvailableError) {\n * console.warn(`NWP deferred to v2.0+; ${e.hint}`);\n * // Fall back to iemMosForecasts() when available, else Python SDK.\n * } else {\n * throw e;\n * }\n * }\n * ```\n *\n * See [docs/nwp-forecasts.md](https://mostlyright.md/docs/sdk/typescript/nwp-forecasts/)\n * for the full architectural rationale and the v2.0+ roadmap.\n */\nexport class NwpNotAvailableError extends DataAvailabilityError {\n static override defaultErrorCode = \"NWP_NOT_AVAILABLE\";\n\n readonly station: string;\n readonly model: string;\n\n constructor(options: NwpNotAvailableErrorOptions) {\n // exactOptionalPropertyTypes: true — only include requestId when the\n // caller passed a non-undefined value. Passing `requestId: undefined`\n // explicitly would type-error against the parent's narrower contract.\n const parentOpts: DataAvailabilityErrorOptions = {\n reason: \"model_unavailable\",\n hint: options.hint,\n source: options.source ?? `nwp.${options.model}`,\n };\n if (options.requestId !== undefined && options.requestId !== null) {\n parentOpts.requestId = options.requestId;\n }\n super(parentOpts);\n this.station = options.station;\n this.model = options.model;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n station: this.station,\n model: this.model,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// SchemaValidationError\n// ---------------------------------------------------------------------------\n\nexport interface SchemaValidationErrorOptions extends MostlyRightErrorOptions {\n schemaId: string;\n violations?: Array<Record<string, unknown>>;\n quarantineCount?: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\nexport class SchemaValidationError extends MostlyRightError {\n static override defaultErrorCode = \"SCHEMA_VALIDATION_FAILED\";\n\n readonly schemaId: string;\n readonly violations: Array<Record<string, unknown>>;\n readonly quarantineCount: number;\n readonly sampleViolations: Array<Record<string, unknown>>;\n\n constructor(message: string, options: SchemaValidationErrorOptions) {\n super(message, options);\n this.schemaId = options.schemaId;\n this.violations = [...(options.violations ?? [])];\n this.quarantineCount = options.quarantineCount ?? 0;\n this.sampleViolations = [...(options.sampleViolations ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n schema_id: this.schemaId,\n violations: this.violations,\n quarantine_count: this.quarantineCount,\n sample_violations: this.sampleViolations,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// SourceMismatchError\n// ---------------------------------------------------------------------------\n\nexport type SourceMismatchRole = \"observations\" | \"forecasts\" | \"settlement\";\n\nexport interface SourceMismatchErrorOptions extends MostlyRightErrorOptions {\n schemaSource: string;\n dataSource: string;\n role?: SourceMismatchRole | null;\n catalogWarning?: string | null;\n}\n\nexport class SourceMismatchError extends MostlyRightError {\n static override defaultErrorCode = \"SOURCE_MISMATCH\";\n\n /** Canonical role-name vocabulary (design.md §R). */\n static readonly VALID_ROLES: ReadonlySet<SourceMismatchRole> = new Set([\n \"observations\",\n \"forecasts\",\n \"settlement\",\n ]);\n\n readonly schemaSource: string;\n readonly dataSource: string;\n readonly role: SourceMismatchRole | null;\n readonly catalogWarning: string | null;\n\n constructor(message: string, options: SourceMismatchErrorOptions) {\n super(message, options);\n this.schemaSource = options.schemaSource;\n this.dataSource = options.dataSource;\n this.role = options.role ?? null;\n this.catalogWarning = options.catalogWarning ?? null;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n schema_source: this.schemaSource,\n data_source: this.dataSource,\n role: this.role,\n catalog_warning: this.catalogWarning,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// LeakageError\n// ---------------------------------------------------------------------------\n\nexport interface LeakageErrorOptions extends MostlyRightErrorOptions {\n asOf: string;\n violatingCount: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\nexport class LeakageError extends MostlyRightError {\n static override defaultErrorCode = \"LEAKAGE_DETECTED\";\n\n readonly asOf: string;\n readonly violatingCount: number;\n readonly sampleViolations: Array<Record<string, unknown>>;\n\n constructor(message: string, options: LeakageErrorOptions) {\n super(message, options);\n this.asOf = options.asOf;\n this.violatingCount = options.violatingCount;\n this.sampleViolations = [...(options.sampleViolations ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n as_of: this.asOf,\n violating_count: this.violatingCount,\n sample_violations: this.sampleViolations,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// IssuedAtMissingError (Phase 20 OM-04)\n// ---------------------------------------------------------------------------\n\nexport interface IssuedAtMissingErrorOptions extends MostlyRightErrorOptions {\n violatingCount?: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\n/**\n * A forecast row would land with `issuedAt = null`.\n *\n * Phase 20 OM-04. Origin: Tarabcak/mostlyright#70 — the legacy\n * seamless-feed bug where `/forecast_series` proxied Open-Meteo's\n * seamless endpoint without preserving `issued_at`, silently using\n * post-snapshot model runs in training data.\n */\nexport class IssuedAtMissingError extends SchemaValidationError {\n static override defaultErrorCode = \"ISSUED_AT_MISSING\";\n\n readonly violatingCountRows: number;\n\n constructor(message: string, options: IssuedAtMissingErrorOptions = {}) {\n super(message, {\n ...options,\n schemaId: \"schema.forecast.station.v1\",\n violations: [{ column: \"issued_at\", rule: \"non_null\" }],\n });\n this.violatingCountRows = options.violatingCount ?? 0;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n name: \"IssuedAtMissingError\",\n violating_count: this.violatingCountRows,\n origin_issue: \"Tarabcak/mostlyright#70\",\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// OpenMeteoSeamlessLeakageError (Phase 20 OM-04)\n// ---------------------------------------------------------------------------\n\nexport interface OpenMeteoSeamlessLeakageErrorOptions extends MostlyRightErrorOptions {\n model: string;\n endpointUrl: string;\n asOf?: string | null;\n}\n\n/**\n * The Open-Meteo Historical Forecast (seamless) endpoint was used\n * without `allowLeakage: true`.\n *\n * Phase 20 D-01 (locked decision): the seamless endpoint silently\n * stitches forecasts from multiple model cycles into a continuous\n * timeseries; the cycle that produced each value is unrecoverable from\n * the response. `LeakageDetector` rejects rows tagged\n * `source=\"open_meteo.seamless\"` whenever `as_of` is asserted.\n *\n * Origin: Tarabcak/mostlyright#70.\n */\nexport class OpenMeteoSeamlessLeakageError extends LeakageError {\n static override defaultErrorCode = \"OPEN_METEO_SEAMLESS_LEAKAGE\";\n\n readonly model: string;\n readonly endpointUrl: string;\n\n constructor(message: string, options: OpenMeteoSeamlessLeakageErrorOptions) {\n super(message, {\n ...options,\n asOf: options.asOf ?? \"(seamless-endpoint-refused-before-fetch)\",\n violatingCount: 0,\n });\n this.model = options.model;\n this.endpointUrl = options.endpointUrl;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n name: \"OpenMeteoSeamlessLeakageError\",\n model: this.model,\n endpoint_url: this.endpointUrl,\n origin_issue: \"Tarabcak/mostlyright#70\",\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// TemporalDriftError\n// ---------------------------------------------------------------------------\n\nexport interface TemporalDriftErrorOptions extends MostlyRightErrorOptions {\n schemaId: string;\n assertedRange: [string, string];\n violatingRows: number;\n sampleViolations?: Array<Record<string, unknown>>;\n}\n\nexport class TemporalDriftError extends MostlyRightError {\n static override defaultErrorCode = \"TEMPORAL_DRIFT\";\n\n readonly schemaId: string;\n readonly assertedRange: [string, string];\n readonly violatingRows: number;\n readonly sampleViolations: Array<Record<string, unknown>>;\n\n constructor(message: string, options: TemporalDriftErrorOptions) {\n super(message, options);\n this.schemaId = options.schemaId;\n this.assertedRange = [options.assertedRange[0], options.assertedRange[1]];\n this.violatingRows = options.violatingRows;\n this.sampleViolations = [...(options.sampleViolations ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n schema_id: this.schemaId,\n asserted_range: [this.assertedRange[0], this.assertedRange[1]],\n violating_rows: this.violatingRows,\n sample_violations: this.sampleViolations,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// PayloadTooLargeError\n// ---------------------------------------------------------------------------\n\nexport interface PayloadTooLargeErrorOptions extends MostlyRightErrorOptions {\n declaredSize: number;\n limit: number;\n acceptedModes?: string[];\n}\n\nexport class PayloadTooLargeError extends MostlyRightError {\n static override defaultErrorCode = \"PAYLOAD_TOO_LARGE\";\n\n readonly declaredSize: number;\n readonly limit: number;\n readonly acceptedModes: string[];\n\n constructor(message: string, options: PayloadTooLargeErrorOptions) {\n super(message, options);\n this.declaredSize = options.declaredSize;\n this.limit = options.limit;\n this.acceptedModes = [...(options.acceptedModes ?? [])];\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n declared_size: this.declaredSize,\n limit: this.limit,\n accepted_modes: this.acceptedModes,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// DeferredMarketError (TS-W6 placeholder; mirrors mostlyright.international)\n// ---------------------------------------------------------------------------\n\nexport class DeferredMarketError extends MostlyRightError {\n static override defaultErrorCode = \"DEFERRED_MARKET\";\n}\n\n// ---------------------------------------------------------------------------\n// PolymarketEventError (TS-W5 placeholder; mirrors mostlyright.markets.polymarket)\n// ---------------------------------------------------------------------------\n\nexport class PolymarketEventError extends MostlyRightError {\n static override defaultErrorCode = \"POLYMARKET_EVENT_INVALID\";\n}\n\n// ---------------------------------------------------------------------------\n// HTTP-layer hierarchy (mirrors mostlyright._internal.exceptions)\n// ---------------------------------------------------------------------------\n\nexport interface TherminalErrorOptions extends MostlyRightErrorOptions {\n statusCode?: number | null;\n retryAfter?: number | null;\n}\n\n/**\n * Base HTTP-layer marker. Subclass of `MostlyRightError` so callers that\n * catch `MostlyRightError` also catch transport errors.\n */\nexport class TherminalError extends MostlyRightError {\n static override defaultErrorCode = \"HTTP_ERROR\";\n\n readonly statusCode: number | null;\n\n constructor(message: string, options: TherminalErrorOptions = {}) {\n super(message, options);\n this.statusCode = options.statusCode ?? null;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n status_code: this.statusCode,\n };\n }\n}\n\nexport class NotFoundError extends TherminalError {\n static override defaultErrorCode = \"HTTP_NOT_FOUND\";\n\n constructor(message = \"Resource not found\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 404 });\n }\n}\n\nexport interface RateLimitErrorOptions extends TherminalErrorOptions {\n retryAfter?: number | null;\n}\n\nexport class RateLimitError extends TherminalError {\n static override defaultErrorCode = \"HTTP_RATE_LIMITED\";\n\n readonly retryAfter: number | null;\n\n constructor(retryAfter: number | null = 1, options: RateLimitErrorOptions = {}) {\n const msg = `Rate limit exceeded. Retry after ${retryAfter ?? \"?\"}s`;\n super(msg, { ...options, statusCode: options.statusCode ?? 429 });\n this.retryAfter = retryAfter;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n retry_after: this.retryAfter,\n };\n }\n}\n\nexport class ValidationError extends TherminalError {\n static override defaultErrorCode = \"HTTP_BAD_REQUEST\";\n\n constructor(message = \"Invalid request\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 400 });\n }\n}\n\nexport class AuthenticationError extends TherminalError {\n static override defaultErrorCode = \"HTTP_UNAUTHORIZED\";\n\n constructor(message = \"Authentication required\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 401 });\n }\n}\n\nexport class ForbiddenError extends TherminalError {\n static override defaultErrorCode = \"HTTP_FORBIDDEN\";\n\n constructor(message = \"Access denied\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 403 });\n }\n}\n\nexport class ServerError extends TherminalError {\n static override defaultErrorCode = \"HTTP_SERVER_ERROR\";\n\n constructor(message = \"Server error\", options: TherminalErrorOptions = {}) {\n super(message, { ...options, statusCode: options.statusCode ?? 500 });\n }\n}\n\n// ---------------------------------------------------------------------------\n// LiveStreamError + NoLiveDataError (Phase 11)\n// ---------------------------------------------------------------------------\n\n/**\n * Base class for `mostlyright.live.stream` / `live.latest` failures.\n *\n * Mirrors Python `LiveStreamError`. Live-streaming errors are a separate\n * sub-tree from `SourceUnavailableError` because the recovery path differs —\n * `stream()` swallows empty-tick errors and waits for the next polite-floor\n * cycle. Only `latest()` raises `NoLiveDataError` on empty responses.\n */\nexport class LiveStreamError extends MostlyRightError {\n static override defaultErrorCode = \"LIVE_STREAM_ERROR\";\n}\n\nexport interface NoLiveDataErrorOptions extends MostlyRightErrorOptions {\n station: string;\n source: string;\n}\n\n/**\n * `mostlyright.live.latest` returned no observations for the station.\n *\n * Carries the resolved ICAO `station` and the canonical source identity\n * tag (`\"awc.live\"` / `\"iem.live\"`) so caller logs can branch by source\n * without re-parsing the message.\n */\nexport class NoLiveDataError extends LiveStreamError {\n static override defaultErrorCode = \"NO_LIVE_DATA\";\n\n readonly station: string;\n\n constructor(message: string, options: NoLiveDataErrorOptions) {\n super(message, { ...options, source: options.source });\n this.station = options.station;\n }\n\n protected override payload(): Record<string, unknown> {\n return {\n ...super.payload(),\n station: this.station,\n };\n }\n}\n","// TOON v3.0 tabular format — byte-equivalent to Python `encode_tabular`.\n//\n// Ports the encoder portions of\n// `packages/core/src/mostlyright/core/formats/_toon.py` and the tabular\n// loader from `packages/core/src/mostlyright/core/formats/toon.py`.\n//\n// Wire shape (single tabular block):\n//\n// rows[N]{col1,col2,col3}:\n// v1a,v2a,v3a\n// v1b,v2b,v3b\n//\n// Where N is the row count, `{...}` is the column list, each subsequent line\n// is one row's values. Column order comes from the first row's keys.\n//\n// TOON loss matrix (matches Python `toon.py`):\n// - dict/object cells stringify deterministically via canonical JSON\n// (sorted keys + JSON.stringify of nested values).\n// - null + undefined both encode as the bare literal `null`.\n// - NaN / +Infinity / -Infinity encode as `null` (per `_format_number`).\n// - Integer-valued floats serialize without a fractional part (1.0 → \"1\").\n// - Strings that look numeric, start with - / + / digit, are\n// `true`/`false`/`null`, or contain commas/quotes/control chars are\n// quoted. Otherwise emitted bare.\n\n// ---------------------------------------------------------------------------\n// Encoder regex set (mirrors Python `_toon.py`)\n// ---------------------------------------------------------------------------\n\nconst SAFE_KEY_RE = /^[A-Za-z_][A-Za-z0-9_.]*$/;\nconst NUMERIC_LIKE_RE = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n// Quote triggers per TOON spec: colon, quote, backslash, brackets, braces,\n// ASCII control chars, NEL, LSEP, PSEP. Constructed via RegExp(...) to avoid\n// embedding literal LSEP/PSEP bytes (esbuild rejects those in regex literals).\n// biome-ignore lint/suspicious/noControlCharactersInRegex: TOON spec parity\nconst NEEDS_QUOTE_CHARS_RE = /[:\\\\\\\"'\\[\\]{}\\x00-\\x1f\\x7f\\x85\\u2028\\u2029]/;\n// Control chars without a defined TOON escape — stripped on quote.\n// biome-ignore lint/suspicious/noControlCharactersInRegex: TOON spec parity\nconst UNSUPPORTED_CTRL_RE = /[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f\\x85\\u2028\\u2029]/g;\n\n// ---------------------------------------------------------------------------\n// Scalar encoding\n// ---------------------------------------------------------------------------\n\nfunction formatNumber(n: number): string {\n if (!Number.isFinite(n)) return \"null\";\n if (n === 0) return \"0\"; // collapses -0 to \"0\"\n if (Number.isInteger(n) && Math.abs(n) <= 2 ** 53) return String(n);\n let s = String(n);\n // Expand scientific notation to plain decimal. Python uses Decimal —\n // we use toFixed where possible, falling back to toPrecision-based logic.\n if (/[eE]/.test(s)) {\n // toFixed/toPrecision don't fully match Python's Decimal expansion at\n // extreme values, but for the values realistically in weather data\n // (temperatures, lat/lng) String(n) returns plain decimal already.\n // For extreme cases, fall back to a manual expansion.\n s = expandExponent(s);\n }\n return s;\n}\n\nfunction expandExponent(s: string): string {\n const m = /^(-?)(\\d+(?:\\.\\d+)?)[eE]([+-]?\\d+)$/.exec(s);\n if (!m) return s;\n const sign = m[1] ?? \"\";\n const mantissa = m[2] ?? \"\";\n const exp = Number(m[3]);\n const [intPart, fracPart = \"\"] = mantissa.split(\".\");\n const digits = (intPart ?? \"\") + fracPart;\n const pointPos = (intPart ?? \"\").length + exp;\n let out: string;\n if (pointPos <= 0) {\n out = `0.${\"0\".repeat(-pointPos)}${digits}`.replace(/0+$/, \"\");\n if (out.endsWith(\".\")) out = out.slice(0, -1);\n } else if (pointPos >= digits.length) {\n out = digits + \"0\".repeat(pointPos - digits.length);\n } else {\n out = `${digits.slice(0, pointPos)}.${digits.slice(pointPos)}`.replace(/0+$/, \"\");\n if (out.endsWith(\".\")) out = out.slice(0, -1);\n }\n return sign + out;\n}\n\nfunction needsQuoting(s: string, delimiter: string): boolean {\n if (s.length === 0) return true;\n const first = s.charAt(0);\n const last = s.charAt(s.length - 1);\n if (first === \" \" || first === \"\\t\") return true;\n if (last === \" \" || last === \"\\t\") return true;\n if (s === \"true\" || s === \"false\" || s === \"null\") return true;\n if (first === \"-\" || first === \"+\") return true;\n if (first >= \"0\" && first <= \"9\") return true;\n if (NUMERIC_LIKE_RE.test(s)) return true;\n if (s.includes(delimiter)) return true;\n if (NEEDS_QUOTE_CHARS_RE.test(s)) return true;\n return false;\n}\n\nfunction quoteString(s: string): string {\n // Strip unsupported control chars first (matches Python — no escape\n // sequence exists for them).\n let out = s.replace(UNSUPPORTED_CTRL_RE, \"\");\n out = out.replace(/\\\\/g, \"\\\\\\\\\");\n out = out.replace(/\"/g, '\\\\\"');\n out = out.replace(/\\n/g, \"\\\\n\");\n out = out.replace(/\\r/g, \"\\\\r\");\n out = out.replace(/\\t/g, \"\\\\t\");\n return `\"${out}\"`;\n}\n\nfunction formatKey(key: string): string {\n if (typeof key !== \"string\") {\n throw new TypeError(`TOON keys must be strings; got ${typeof key}`);\n }\n if (SAFE_KEY_RE.test(key)) return key;\n return quoteString(key);\n}\n\nfunction encodeScalar(value: unknown, delimiter: string): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"number\") return formatNumber(value);\n if (typeof value === \"string\") {\n if (needsQuoting(value, delimiter)) return quoteString(value);\n return value;\n }\n // Objects / arrays / etc. — canonical JSON (sorted keys) for parity with\n // Python `_coerce_cell` dict-handling, otherwise String(value).\n if (typeof value === \"object\") {\n if (Array.isArray(value)) {\n return quoteString(JSON.stringify(value));\n }\n // Sorted-key JSON for determinism (matches Python json.dumps sort_keys).\n const sorted = sortedJson(value as Record<string, unknown>);\n return quoteString(sorted);\n }\n return quoteString(String(value));\n}\n\nfunction sortedJson(obj: Record<string, unknown>): string {\n const keys = Object.keys(obj).sort();\n const parts = keys.map((k) => `${JSON.stringify(k)}:${JSON.stringify(obj[k])}`);\n return `{${parts.join(\",\")}}`;\n}\n\n// ---------------------------------------------------------------------------\n// Tabular validation (mirrors Python `_is_tabular`)\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when {@link toonDumps} receives rows that aren't valid tabular\n * input. Mirrors the Python `encode_tabular` `ValueError` — the encoder\n * MUST refuse non-uniform rows or non-primitive values rather than\n * silently dropping columns or stringifying nested structures.\n *\n * Iter-1 C3: the previous TS encoder used `Object.keys(rows[0])` and\n * encoded every subsequent row through that column list — meaning rows\n * with extra keys had them dropped, rows missing a first-row key got a\n * silent `null`, and rows with object/array values stringified via\n * `JSON.stringify` (also silent). All three are data corruption when the\n * caller didn't realize their rows weren't uniform.\n */\nexport class ToonTabularError extends RangeError {\n override name = \"ToonTabularError\";\n}\n\nfunction isToonPrimitive(v: unknown): boolean {\n // Python `_is_tabular` accepts None / str / int / float / bool. The TS\n // analog: null/undefined (both encode as `null`), string, finite or\n // non-finite number (NaN/Inf encode as `null` via formatNumber),\n // boolean. Anything else (object, array, function, symbol, bigint) is\n // non-tabular.\n if (v === null || v === undefined) return true;\n const t = typeof v;\n return t === \"string\" || t === \"number\" || t === \"boolean\";\n}\n\nfunction assertTabular(rows: ReadonlyArray<Record<string, unknown>>): void {\n if (rows.length === 0) return;\n const first = rows[0] as Record<string, unknown>;\n const expectedKeys = Object.keys(first);\n if (expectedKeys.length === 0) {\n throw new ToonTabularError(\n \"toonDumps requires non-empty rows; first row has no keys (Python parity: encode_tabular rejects empty key set)\",\n );\n }\n const expectedKeySet = new Set(expectedKeys);\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i] as Record<string, unknown>;\n const rowKeys = Object.keys(row);\n // (a) Key-set equality. Python compares `set(item.keys()) != key_set`.\n if (rowKeys.length !== expectedKeySet.size) {\n throw new ToonTabularError(\n `toonDumps requires uniform rows; row ${i} has ${rowKeys.length} key(s) vs row 0's ${expectedKeySet.size}. Python encode_tabular rejects rows whose key sets differ.`,\n );\n }\n for (const k of rowKeys) {\n if (!expectedKeySet.has(k)) {\n throw new ToonTabularError(\n `toonDumps requires uniform rows; row ${i} has key ${JSON.stringify(k)} not present in row 0. Python encode_tabular rejects rows whose key sets differ.`,\n );\n }\n }\n // (b) Value primitivity. Python check: `v is None or isinstance(v, str|int|float|bool)`.\n for (const k of expectedKeys) {\n const v = row[k];\n if (!isToonPrimitive(v)) {\n throw new ToonTabularError(\n `toonDumps requires primitive cell values; row ${i} column ${JSON.stringify(k)} has non-primitive value of type ${typeof v}. Python encode_tabular rejects nested objects/arrays at the cell level.`,\n );\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public encoder\n// ---------------------------------------------------------------------------\n\n/**\n * Encode rows as a TOON v3.0 tabular block.\n *\n * Header is `rows[N]{c1,c2,...}:`; data lines are 2-space indented and\n * comma-separated. Empty rows emits `rows[0]:` (header-only, no columns\n * region; matches Python `_encode_array_field` empty-list path).\n *\n * Note: empty-row encoding differs from `dumps()` in `toon.py` (which\n * carries column names through `rows[0]{...}:`). The TS encoder accepts\n * a `columns` second arg in the empty case for parity with that\n * pandas-aware wrapper.\n *\n * @throws {ToonTabularError} when rows are non-uniform (differing key\n * sets across rows) or when any cell value is non-primitive\n * (object/array/bigint/etc.). Mirrors Python `encode_tabular`'s\n * `ValueError`. Iter-1 C3 fix.\n */\nexport function toonDumps(\n rows: ReadonlyArray<Record<string, unknown>>,\n columns?: ReadonlyArray<string>,\n): string {\n if (rows.length === 0) {\n // Empty-frame: carry column names if provided (matches the Python\n // DataFrame wrapper's `rows[0]{...}:` empty form). Otherwise emit the\n // bare encoder form.\n if (columns !== undefined) {\n const cols = columns.map((c) => formatKey(String(c))).join(\",\");\n return `rows[0]{${cols}}:`;\n }\n return \"rows[0]:\";\n }\n // C3 hard gate: refuse non-uniform rows BEFORE looking at row 0's keys\n // for the column header. Otherwise we'd silently drop extra columns or\n // null-fill missing ones.\n assertTabular(rows);\n const cols = Object.keys(rows[0] as Record<string, unknown>);\n const colHeader = cols.map((c) => formatKey(c)).join(\",\");\n const header = `rows[${rows.length}]{${colHeader}}:`;\n const dataLines = rows.map((r) => {\n const vals = cols.map((c) => encodeScalar((r as Record<string, unknown>)[c], \",\"));\n return ` ${vals.join(\",\")}`;\n });\n return `${header}\\n${dataLines.join(\"\\n\")}`;\n}\n\n// ---------------------------------------------------------------------------\n// Decoder\n// ---------------------------------------------------------------------------\n\nconst HEADER_PREFIX_RE = /^(?<key>[A-Za-z_][A-Za-z0-9_.]*)\\[(?<count>\\d+)\\]/;\n\nfunction parseHeaderLine(line: string): { count: number; cols: string } {\n const prefix = HEADER_PREFIX_RE.exec(line);\n if (prefix == null) {\n throw new RangeError(`TOON payload missing tabular header; got: ${JSON.stringify(line)}`);\n }\n const declared = Number(prefix.groups?.count ?? \"\");\n let i = prefix[0].length;\n const n = line.length;\n // Handle the header-only empty form: `rows[0]:` (no `{cols}` region).\n if (i < n && line[i] === \":\" && declared === 0) {\n const rest = line.slice(i + 1).trim();\n if (rest === \"\") return { count: 0, cols: \"\" };\n throw new RangeError(`TOON header has trailing junk: ${JSON.stringify(line)}`);\n }\n if (i >= n || line[i] !== \"{\") {\n throw new RangeError(`TOON header missing column region: ${JSON.stringify(line)}`);\n }\n i++; // consume `{`\n // Walk to matching `}` honoring quoted strings.\n while (i < n) {\n const ch = line[i];\n if (ch === '\"') {\n let j = i + 1;\n while (j < n) {\n if (line[j] === \"\\\\\" && j + 1 < n) {\n j += 2;\n continue;\n }\n if (line[j] === '\"') break;\n j++;\n }\n if (j >= n) {\n throw new RangeError(\n `TOON header has unterminated quoted column name: ${JSON.stringify(line)}`,\n );\n }\n i = j + 1;\n continue;\n }\n if (ch === \"}\") break;\n i++;\n }\n if (i >= n || line[i] !== \"}\") {\n throw new RangeError(`TOON header missing closing brace: ${JSON.stringify(line)}`);\n }\n const cols = line.slice(prefix[0].length + 1, i);\n const rest = line.slice(i + 1).trim();\n if (rest !== \":\") {\n throw new RangeError(`TOON header missing colon terminator: ${JSON.stringify(line)}`);\n }\n return { count: declared, cols };\n}\n\nfunction splitCsvRow(line: string): string[] {\n const tokens: string[] = [];\n const n = line.length;\n if (n === 0) return tokens;\n let i = 0;\n while (true) {\n // Skip leading whitespace (defensive — encoder never emits padding).\n while (i < n && line[i] === \" \") i++;\n if (i >= n) {\n tokens.push(\"\");\n break;\n }\n if (line[i] === '\"') {\n let j = i + 1;\n while (j < n) {\n if (line[j] === \"\\\\\" && j + 1 < n) {\n j += 2;\n continue;\n }\n if (line[j] === '\"') break;\n j++;\n }\n tokens.push(line.slice(i, j + 1));\n i = j + 1;\n if (i >= n) break;\n if (line[i] === \",\") {\n i++;\n continue;\n }\n while (i < n && line[i] !== \",\") i++;\n if (i >= n) break;\n i++;\n } else {\n let j = i;\n while (j < n && line[j] !== \",\") j++;\n tokens.push(line.slice(i, j));\n i = j;\n if (i >= n) break;\n i++; // consume comma\n }\n }\n return tokens;\n}\n\nfunction decodeQuoted(token: string): string {\n const inner = token.slice(1, -1);\n let out = \"\";\n let i = 0;\n while (i < inner.length) {\n const ch = inner[i];\n if (ch === \"\\\\\" && i + 1 < inner.length) {\n const nxt = inner.charAt(i + 1);\n if (nxt === \"\\\\\") out += \"\\\\\";\n else if (nxt === '\"') out += '\"';\n else if (nxt === \"n\") out += \"\\n\";\n else if (nxt === \"r\") out += \"\\r\";\n else if (nxt === \"t\") out += \"\\t\";\n else out += nxt;\n i += 2;\n continue;\n }\n out += ch;\n i++;\n }\n return out;\n}\n\nfunction unquoteIfQuoted(token: string): string {\n if (token.length >= 2 && token[0] === '\"' && token[token.length - 1] === '\"') {\n return decodeQuoted(token);\n }\n return token;\n}\n\nfunction decodeValue(token: string): unknown {\n if (token.length === 0) return null;\n if (token[0] === '\"' && token[token.length - 1] === '\"' && token.length >= 2) {\n return decodeQuoted(token);\n }\n if (token === \"null\") return null;\n if (token === \"true\") return true;\n if (token === \"false\") return false;\n // Numeric attempt.\n if (NUMERIC_LIKE_RE.test(token)) {\n if (!token.includes(\".\") && !/[eE]/.test(token)) {\n const n = Number.parseInt(token, 10);\n if (!Number.isNaN(n)) return n;\n }\n const f = Number.parseFloat(token);\n if (!Number.isNaN(f)) return f;\n }\n // Bare unquoted string — TOON allows it when no quote-triggers fire.\n return token;\n}\n\n/**\n * Parse a TOON v3.0 tabular block back into rows + columns.\n *\n * Accepts ONLY the tabular shape that `toonDumps` produces; nested objects\n * / expanded lists are out of scope for the formats module.\n */\nexport function toonLoads(data: string): {\n rows: Array<Record<string, unknown>>;\n columns: string[];\n} {\n const lines = data.split(/\\r?\\n/);\n let idx = 0;\n while (idx < lines.length && lines[idx]?.trim() === \"\") idx++;\n if (idx >= lines.length) throw new RangeError(\"empty TOON payload\");\n\n const { count: declared, cols: colsRegion } = parseHeaderLine(lines[idx] ?? \"\");\n const columns = colsRegion === \"\" ? [] : splitCsvRow(colsRegion).map((t) => unquoteIfQuoted(t));\n\n const rawRows: unknown[][] = [];\n for (const raw of lines.slice(idx + 1)) {\n const line = raw.replace(/\\s+$/u, \"\");\n if (line.trim() === \"\") continue;\n const stripped = line.replace(/^ +/u, \"\");\n const tokens = splitCsvRow(stripped);\n if (columns.length > 0 && tokens.length !== columns.length) {\n throw new RangeError(\n `TOON row column count mismatch: expected ${columns.length}, got ${tokens.length}: ${JSON.stringify(stripped)}`,\n );\n }\n rawRows.push(tokens.map((t) => decodeValue(t)));\n }\n if (declared !== rawRows.length) {\n throw new RangeError(`TOON declared row count ${declared} != actual ${rawRows.length}`);\n }\n const rows = rawRows.map((row) => {\n const r: Record<string, unknown> = {};\n for (let i = 0; i < columns.length; i++) {\n r[columns[i] as string] = row[i];\n }\n return r;\n });\n return { rows, columns };\n}\n","// TS-W6 Wave 3 — DataSnapshot + buildSnapshot.\n//\n// Frozen, JSON-safe immutable record of a research() result with provenance.\n// `toDict()` returns the JSON-safe payload (cycles + non-finite numbers\n// handled by `toJsonSafe`); `toToon()` serializes as a TOON tabular block\n// via the existing `toonDumps` encoder.\n\nimport { toJsonSafe } from \"../exceptions/index.js\";\nimport { toonDumps } from \"../formats/toon.js\";\n\nimport type { DataVersion } from \"./data-version.js\";\n\n/** Frozen snapshot wrapper around row data + provenance. */\nexport interface DataSnapshot {\n /** ISO 8601 UTC instant when the snapshot was built (always ends with Z). */\n readonly knowledgeTime: string;\n /** Schema id the rows conform to. */\n readonly schemaId: string;\n /** Source identifier (e.g. `iem.archive`, `awc.live`). Snapshot-scoped. */\n readonly source: string;\n /** Row payload — opaque to this layer. Frozen. */\n readonly rows: ReadonlyArray<Readonly<Record<string, unknown>>>;\n /** Optional reproducibility token. */\n readonly dataVersion: DataVersion | null;\n /** Optional arbitrary metadata. JSON-safe-coerced on `toDict`. */\n readonly metadata: Readonly<Record<string, unknown>>;\n /** JSON-safe dict form. */\n toDict(): Record<string, unknown>;\n /** TOON-v3 tabular form (rows only — provenance lives in the dict form). */\n toToon(): string;\n}\n\nexport interface BuildSnapshotOptions {\n schemaId: string;\n source: string;\n rows: ReadonlyArray<Record<string, unknown>>;\n knowledgeTime?: Date | string;\n dataVersion?: DataVersion | null;\n metadata?: Record<string, unknown>;\n}\n\nfunction normalizeKnowledgeTime(value: Date | string | undefined): string {\n if (value === undefined) {\n return new Date().toISOString();\n }\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n throw new RangeError(\"buildSnapshot: knowledgeTime is an invalid Date\");\n }\n return value.toISOString();\n }\n // String: parse + re-emit so the result is always canonical ISO with Z.\n const ms = Date.parse(value);\n if (Number.isNaN(ms)) {\n throw new RangeError(\n `buildSnapshot: knowledgeTime ${JSON.stringify(value)} is not a parseable ISO 8601 timestamp`,\n );\n }\n return new Date(ms).toISOString();\n}\n\nfunction freezeRows(\n rows: ReadonlyArray<Record<string, unknown>>,\n): ReadonlyArray<Readonly<Record<string, unknown>>> {\n const out: Readonly<Record<string, unknown>>[] = [];\n for (const r of rows) {\n out.push(Object.freeze({ ...r }));\n }\n return Object.freeze(out);\n}\n\n/**\n * Build a frozen DataSnapshot.\n *\n * Throws RangeError on invalid `knowledgeTime`. Row payloads are shallow-\n * cloned and frozen so callers can't mutate snapshot state post-build.\n */\nexport function buildSnapshot(opts: BuildSnapshotOptions): DataSnapshot {\n if (typeof opts.schemaId !== \"string\" || opts.schemaId.length === 0) {\n throw new RangeError(\"buildSnapshot: schemaId must be a non-empty string\");\n }\n if (typeof opts.source !== \"string\" || opts.source.length === 0) {\n throw new RangeError(\"buildSnapshot: source must be a non-empty string\");\n }\n if (!Array.isArray(opts.rows)) {\n throw new RangeError(\"buildSnapshot: rows must be an array\");\n }\n\n // Capture every component into local consts so the returned snapshot's\n // closures never read from the mutable `opts` argument. Codex iter-1\n // P2: a caller that did `const s = buildSnapshot({...}); opts.schemaId = \"x\"`\n // would have seen `s.toDict()` emit the mutated schemaId while\n // `s.schemaId` still showed the original — provenance drift on an API\n // that promises immutability.\n const knowledgeTime = normalizeKnowledgeTime(opts.knowledgeTime);\n const schemaId = opts.schemaId;\n const source = opts.source;\n const rows = freezeRows(opts.rows);\n const dataVersion = opts.dataVersion ?? null;\n const metadata = Object.freeze({ ...(opts.metadata ?? {}) });\n\n const snapshot: DataSnapshot = {\n knowledgeTime,\n schemaId,\n source,\n rows,\n dataVersion,\n metadata,\n toDict(): Record<string, unknown> {\n // `toJsonSafe` handles cycles + non-finite numbers + Dates. DataVersion\n // is a plain dict-shaped object already, so it round-trips cleanly.\n return toJsonSafe({\n knowledge_time: knowledgeTime,\n schema_id: schemaId,\n source,\n rows,\n data_version: dataVersion,\n metadata,\n }) as Record<string, unknown>;\n },\n toToon(): string {\n // TOON encodes a tabular block (rows-only). The header (schema id,\n // source, knowledge time, data version) lives in `toDict()`. Callers\n // that want the full snapshot in TOON wrap toDict output themselves.\n return toonDumps(rows as unknown as Array<Record<string, unknown>>);\n },\n };\n\n return Object.freeze(snapshot);\n}\n","// TS-W6 Wave 4 — DataVersion reproducibility token via Web Crypto SHA-256.\n//\n// Ports Python `mostlyright.discovery.DataVersion.from_components` byte-for-byte:\n// the canonical concatenation is `sdkVersion|sortedSchemaIds|sortedSources|codeSha|dataSha`,\n// SHA-256 hex of the UTF-8 encoded string is the token.\n//\n// Web Crypto API is universal in modern runtimes (browser/Node 16+/Workers/Deno/Bun),\n// so we use `crypto.subtle.digest` without runtime detection.\n\n/** Immutable reproducibility token stamping a single research() call. */\nexport interface DataVersion {\n readonly sdkVersion: string;\n readonly schemaIds: ReadonlyArray<string>;\n readonly sources: ReadonlyArray<string>;\n readonly codeSha: string;\n readonly dataSha: string;\n readonly token: string;\n}\n\nexport interface DataVersionComponents {\n sdkVersion: string;\n schemaIds: ReadonlyArray<string>;\n sources: ReadonlyArray<string>;\n codeSha: string;\n dataSha: string;\n}\n\nconst HEX = \"0123456789abcdef\";\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 1) {\n const b = bytes[i] as number;\n out += HEX[(b >> 4) & 0xf];\n out += HEX[b & 0xf];\n }\n return out;\n}\n\n/**\n * Build a frozen DataVersion from explicit components.\n *\n * Mirrors Python `DataVersion.from_components`: sorts schemaIds + sources\n * INTERNALLY before the canonical hash so input order does not affect the\n * token, but preserves the caller's order on the returned object's\n * `schemaIds` and `sources` arrays. Codex iter-5 P2: prior version sorted\n * the stored arrays alphabetically too, which masked source-priority order\n * (e.g. `awc.live, ghcnh, iem.archive, ...` instead of the canonical\n * `iem.archive, iem.live, awc.live, ghcnh, nws.cli` precedence Python\n * preserves on the tuple).\n */\nexport async function dataVersionFromComponents(\n components: DataVersionComponents,\n): Promise<DataVersion> {\n const sortedSchemaIds = [...components.schemaIds].sort();\n const sortedSources = [...components.sources].sort();\n const canonical = [\n components.sdkVersion,\n sortedSchemaIds.join(\",\"),\n sortedSources.join(\",\"),\n components.codeSha,\n components.dataSha,\n ].join(\"|\");\n\n const encoded = new TextEncoder().encode(canonical);\n const digest = await crypto.subtle.digest(\"SHA-256\", encoded);\n const token = bytesToHex(new Uint8Array(digest));\n\n return Object.freeze({\n sdkVersion: components.sdkVersion,\n schemaIds: Object.freeze([...components.schemaIds]),\n sources: Object.freeze([...components.sources]),\n codeSha: components.codeSha,\n dataSha: components.dataSha,\n token,\n });\n}\n\n/**\n * Build a DataVersion for a research() call. Mirrors Python `DataVersion.for_research`:\n * the codeSha encodes the call signature (`research:STATION:FROM:TO`) and dataSha\n * is supplied by the caller (typically a cache fingerprint).\n *\n * The schema ids + source contract match the v0.1.0 Python SDK exactly so tokens\n * computed in TS match tokens computed in Python for the same inputs.\n */\nexport async function dataVersionForResearch(args: {\n sdkVersion: string;\n station: string;\n fromDate: string;\n toDate: string;\n dataSha: string;\n}): Promise<DataVersion> {\n return dataVersionFromComponents({\n sdkVersion: args.sdkVersion,\n schemaIds: [\"schema.observation.v1\", \"schema.forecast.iem_mos.v1\", \"schema.settlement.cli.v1\"],\n sources: [\"iem.archive\", \"iem.live\", \"awc.live\", \"ghcnh\", \"nws.cli\"],\n codeSha: `research:${args.station}:${args.fromDate}:${args.toDate}`,\n dataSha: args.dataSha,\n });\n}\n","// TS-W6 Wave 5 — describe(schemaId) + featureCatalog() + climateGaps stub.\n//\n// `describe(schemaId)` returns a multi-line human-readable string mined from\n// the embedded JSON-Schema metadata. We bundle schema descriptions as a small\n// JSON map keyed by `$id` (the canonical schema id) — produced by the codegen\n// pipeline if/when it lands; for v0.1.0 we ship a hand-maintained list that\n// matches what the codegen emits.\n//\n// `featureCatalog()` returns the transforms surface as a stable-sorted list\n// of names — matches Python `feature_catalog()` exactly.\n//\n// `climateGaps(station, fromDate, toDate)` throws — TS has no climate cache\n// in v0.1.0 (climate-year parquets are Python-only); the stub matches the\n// Python signature so callers can `try/catch` the platform difference.\n\nimport { MostlyRightError } from \"../exceptions/index.js\";\n\n// ---------------------------------------------------------------------------\n// Schema registry — keep in sync with `packages-ts/core/src/schemas/generated`.\n// ---------------------------------------------------------------------------\n\ninterface SchemaInfo {\n readonly id: string;\n readonly title: string;\n readonly columnCount: number;\n readonly columns: ReadonlyArray<{\n readonly name: string;\n readonly description: string;\n readonly nullable: boolean;\n }>;\n}\n\n// Static manifest of the v0.1.0 schemas. Derived from `schemas/json/*.json`\n// at repo root; baked in here so `@mostlyrightmd/core/discovery` works in\n// browsers (no `node:fs`) without a runtime fetch. The codegen pipeline\n// would replace this hand-maintained list once it covers schema docs.\n//\n// Codex iter-1 P2: prior version left REGISTRY empty until callers ran\n// `registerSchema()`, so `describe('schema.observation.v1')` always threw\n// UNKNOWN_SCHEMA on a fresh import.\nconst BUILT_IN_SCHEMAS: ReadonlyArray<SchemaInfo> = Object.freeze([\n {\n id: \"schema.observation.v1\",\n title: \"schema.observation.v1\",\n columnCount: 20,\n columns: [\n { name: \"dew_point_c\", description: \"units: celsius — bounded\", nullable: true },\n { name: \"event_time\", description: \"observation valid time\", nullable: false },\n {\n name: \"metar_raw\",\n description: \"raw METAR text if source has it; null for AWC JSON (structured-only)\",\n nullable: true,\n },\n {\n name: \"observation_type\",\n description: \"METAR | SPECI; defaults METAR when source can't distinguish (e.g. AWC JSON)\",\n nullable: false,\n },\n {\n name: \"precip_mm_1h\",\n description: \"units: mm — hourly precip (METAR p01i, converted from inches)\",\n nullable: true,\n },\n {\n name: \"sky_base_1_m\",\n description: \"units: meters — first cloud layer base height (converted from feet)\",\n nullable: true,\n },\n { name: \"sky_base_2_m\", description: \"units: meters\", nullable: true },\n { name: \"sky_base_3_m\", description: \"units: meters\", nullable: true },\n { name: \"sky_base_4_m\", description: \"units: meters\", nullable: true },\n { name: \"sky_cover_1\", description: \"first cloud layer cover code\", nullable: true },\n { name: \"sky_cover_2\", description: \"second layer; null if not present\", nullable: true },\n { name: \"sky_cover_3\", description: \"third layer; null if not present\", nullable: true },\n { name: \"sky_cover_4\", description: \"fourth layer; null if not present\", nullable: true },\n {\n name: \"slp_hpa\",\n description:\n \"units: hPa — sea-level pressure (canonical aviation unit, not converted across modes)\",\n nullable: true,\n },\n { name: \"station\", description: \"ICAO/ASOS station ID (e.g. KORD)\", nullable: false },\n {\n name: \"temp_c\",\n description: \"units: celsius — bounded TEMP_MIN_C..TEMP_MAX_C\",\n nullable: true,\n },\n {\n name: \"visibility_m\",\n description: \"units: meters — converted from statute miles\",\n nullable: true,\n },\n {\n name: \"wind_dir_deg\",\n description: \"units: degrees — 0-360, bounded\",\n nullable: true,\n },\n { name: \"wind_gust_ms\", description: \"units: m/s — converted from kt\", nullable: true },\n { name: \"wind_speed_ms\", description: \"units: m/s — converted from kt\", nullable: true },\n ],\n },\n {\n id: \"schema.forecast.iem_mos.v1\",\n title: \"schema.forecast.iem_mos.v1\",\n columnCount: 11,\n columns: [\n { name: \"dew_point_c\", description: \"units: celsius\", nullable: true },\n {\n name: \"forecast_hour\",\n description: \"units: hours — (valid_at - issued_at).total_seconds() / 3600\",\n nullable: false,\n },\n {\n name: \"issued_at\",\n description: \"model run time (from source `runtime` field)\",\n nullable: false,\n },\n { name: \"model\", description: \"e.g. NBE, GFS, LAV, MET\", nullable: false },\n {\n name: \"precip_probability\",\n description: \"units: probability — bounded [0, 1]\",\n nullable: true,\n },\n {\n name: \"sky_cover_pct\",\n description: \"units: percent — bounded [0, 100]\",\n nullable: true,\n },\n { name: \"station\", description: \"\", nullable: false },\n { name: \"temp_c\", description: \"units: celsius\", nullable: true },\n {\n name: \"valid_at\",\n description: \"forecast target time (from source `ftime`)\",\n nullable: false,\n },\n { name: \"wind_dir_deg\", description: \"units: degrees\", nullable: true },\n { name: \"wind_speed_ms\", description: \"units: m/s\", nullable: true },\n ],\n },\n {\n id: \"schema.settlement.cli.v1\",\n title: \"schema.settlement.cli.v1\",\n columnCount: 12,\n columns: [\n {\n name: \"cli_data_quality\",\n description:\n \"NWS CLI data-quality marker (Pitfall 6/16). Allows downstream code to filter or weight settlement rows by issuer quality without re-parsing the product header.\",\n nullable: false,\n },\n {\n name: \"event_time\",\n description: \"00:00 local time on observation_date converted to UTC; for sort/join only\",\n nullable: false,\n },\n {\n name: \"observation_date\",\n description:\n \"local climate day per NWS convention (no timezone applied to the date itself)\",\n nullable: false,\n },\n { name: \"precipitation_in\", description: \"units: inches\", nullable: true },\n {\n name: \"product_release_time\",\n description: \"parsed from CLI product header (_climate.py::_parse_product_timestamp)\",\n nullable: false,\n },\n {\n name: \"report_type\",\n description:\n \"preliminary | final | correction; dedup priority preliminary < final < correction\",\n nullable: false,\n },\n {\n name: \"settlement_finality\",\n description:\n \"provisional | final | superseded. Kalshi NHIGH/NLOW settlement contractually requires 'final'; 'provisional' values are kept for early-look research only.\",\n nullable: false,\n },\n { name: \"snowfall_in\", description: \"units: inches\", nullable: true },\n { name: \"station\", description: \"ICAO/ASOS station ID\", nullable: false },\n {\n name: \"station_tz\",\n description:\n \"IANA timezone for the station (e.g. America/Chicago for KORD). Required for local-climate-day semantics; see §U.\",\n nullable: false,\n },\n {\n name: \"temp_max_F\",\n description:\n \"units: fahrenheit — daily high (uppercase F for consistency with obs imperial mode)\",\n nullable: true,\n },\n { name: \"temp_min_F\", description: \"units: fahrenheit — daily low\", nullable: true },\n ],\n },\n {\n id: \"schema.observation_ledger.v1\",\n title: \"schema.observation_ledger.v1\",\n columnCount: 15,\n columns: [\n { name: \"as_of_time\", description: \"\", nullable: true },\n { name: \"dewpoint_c\", description: \"units: celsius\", nullable: true },\n { name: \"ingestion_id\", description: \"\", nullable: true },\n { name: \"observation_kind\", description: \"\", nullable: true },\n {\n name: \"observation_quality\",\n description:\n \"Lineage row-quality flag per LINEAGE-01; distinct from qc_status enum slot AND distinct from the obs_qc_status bitmask column per QC-05.\",\n nullable: true,\n },\n { name: \"observation_type\", description: \"\", nullable: false },\n { name: \"observed_at\", description: \"\", nullable: false },\n { name: \"parser_name\", description: \"\", nullable: true },\n { name: \"parser_version\", description: \"\", nullable: true },\n { name: \"provenance\", description: \"\", nullable: true },\n { name: \"qc_status\", description: \"\", nullable: true },\n {\n name: \"source\",\n description: \"ncei reserved per D-2.1-09; never written in v0.1.0.\",\n nullable: false,\n },\n { name: \"source_received_at\", description: \"\", nullable: true },\n { name: \"station_code\", description: \"\", nullable: false },\n { name: \"temp_c\", description: \"units: celsius\", nullable: true },\n ],\n },\n {\n id: \"schema.observation_qc.v1\",\n title: \"schema.observation_qc.v1\",\n columnCount: 13,\n columns: [\n { name: \"as_of_time\", description: \"\", nullable: true },\n {\n name: \"detector_metadata\",\n description: \"JSON-serialized detector payload; shape per qc_system.\",\n nullable: true,\n },\n {\n name: \"field\",\n description: \"Observation column the rule evaluated (e.g. temp_c).\",\n nullable: false,\n },\n { name: \"flag\", description: \"\", nullable: false },\n { name: \"ingestion_id\", description: \"\", nullable: true },\n { name: \"observation_kind\", description: \"\", nullable: true },\n { name: \"observed_at\", description: \"\", nullable: false },\n { name: \"parser_name\", description: \"\", nullable: true },\n { name: \"qc_system\", description: \"\", nullable: false },\n { name: \"qc_version\", description: \"\", nullable: false },\n { name: \"rule_id\", description: \"\", nullable: false },\n { name: \"source\", description: \"\", nullable: false },\n { name: \"station_code\", description: \"\", nullable: false },\n ],\n },\n]);\n\nfunction deepFreezeSchema(info: SchemaInfo): SchemaInfo {\n const frozenCols = Object.freeze(info.columns.map((c) => Object.freeze({ ...c })));\n return Object.freeze({ ...info, columns: frozenCols });\n}\n\nconst REGISTRY = new Map<string, SchemaInfo>(\n BUILT_IN_SCHEMAS.map((info) => [info.id, deepFreezeSchema(info)] as const),\n);\n\n/**\n * Register or override a schema for `describe()`. Built-in v0.1.0 schemas\n * are registered at module load (BUILT_IN_SCHEMAS); callers may add custom\n * schemas or override built-ins (e.g. with richer descriptions).\n */\nexport function registerSchema(info: SchemaInfo): void {\n REGISTRY.set(info.id, deepFreezeSchema(info));\n}\n\n/**\n * Return a multi-line description of a registered schema.\n *\n * @throws MostlyRightError if `schemaId` is not registered. The error code is\n * `UNKNOWN_SCHEMA` so callers can distinguish from validation/IO errors.\n */\nexport function describe(schemaId: string): string {\n const info = REGISTRY.get(schemaId);\n if (info === undefined) {\n const known = [...REGISTRY.keys()].sort();\n throw new UnknownSchemaError(\n `Unknown schemaId ${JSON.stringify(schemaId)}; registered: ${\n known.length === 0 ? \"<none>\" : known.join(\", \")\n }`,\n );\n }\n const lines = [`Schema: ${info.id}`, ` Title: ${info.title}`, ` Columns: ${info.columnCount}`];\n for (const col of info.columns) {\n const nullable = col.nullable ? \"?\" : \"\";\n const desc = col.description.length === 0 ? \"\" : ` — ${col.description}`;\n lines.push(` - ${col.name}${nullable}${desc}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Thrown by `describe` when `schemaId` is not registered. */\nexport class UnknownSchemaError extends MostlyRightError {\n constructor(message: string) {\n super(message);\n this.name = \"UnknownSchemaError\";\n }\n static readonly defaultErrorCode = \"UNKNOWN_SCHEMA\";\n}\n\n// ---------------------------------------------------------------------------\n// featureCatalog — list of transforms surface names.\n// ---------------------------------------------------------------------------\n\nconst FEATURE_NAMES: ReadonlyArray<string> = Object.freeze([\n \"calendarFeatures\",\n \"clipOutliers\",\n \"diff\",\n \"diff2\",\n \"heatIndex\",\n \"lag\",\n \"rolling\",\n \"spread\",\n \"windChill\",\n]);\n\n/**\n * Return the transforms surface as a stable-sorted list.\n *\n * Matches Python `feature_catalog()`'s ordering — alphabetical on the\n * snake_case names, here the camelCase TS names sorted identically.\n */\nexport function featureCatalog(): ReadonlyArray<string> {\n return FEATURE_NAMES;\n}\n\n// ---------------------------------------------------------------------------\n// climateGaps — stub that mirrors Python's signature; v1.x deferral.\n// ---------------------------------------------------------------------------\n//\n// Phase 21 21-11 upgrade: raises DataAvailabilityError (typed exception\n// from Phase 21 21-09) with an architectural-reason hint. The legacy\n// ClimateGapsNotImplementedError class is kept as a back-compat alias\n// (subclass of DataAvailabilityError) so existing `catch` sites keep\n// working. New code should catch DataAvailabilityError and dispatch on\n// the `reason` field instead.\n\nimport { DataAvailabilityError } from \"../exceptions/index.js\";\n\nconst CLIMATE_GAPS_HINT =\n \"climateGaps() is server-only in v1.x. Architectural reason: \" +\n \"GHCNh CSVs are 10+ MB per station-year; browser fetch doesn't \" +\n \"slice (no HTTP Range) and IndexedDB quotas don't fit the working \" +\n \"set. Use the Python SDK (mostlyright.discover.climate_gaps) for \" +\n \"v1.x, or wait for the hosted climate-gap-precompute API \" +\n \"(target: post-v1.x). See https://mostlyright.md/docs/sdk/typescript/climate-gaps \" +\n \"for details.\";\n\n/**\n * Climate-gap scanning — TS v1.x deferral.\n *\n * Phase 21 21-11 messaging upgrade: raises DataAvailabilityError with a\n * multi-paragraph hint explaining the architectural constraint (GHCNh\n * CSVs are 10+ MB per station-year; browser cache layer doesn't scale).\n *\n * @throws DataAvailabilityError with reason=\"model_unavailable\" and a\n * hint pointing at the Python SDK as the supported v1.x workaround.\n */\nexport function climateGaps(_station: string, _fromDate: string, _toDate: string): never {\n throw new ClimateGapsNotImplementedError();\n}\n\n/**\n * Back-compat subclass of DataAvailabilityError raised by `climateGaps`\n * in v1.x. Existing `catch (e instanceof ClimateGapsNotImplementedError)`\n * sites keep working; new code should catch the parent class\n * `DataAvailabilityError` and dispatch on `reason === \"model_unavailable\"`.\n *\n * @deprecated Prefer catching `DataAvailabilityError` directly.\n */\nexport class ClimateGapsNotImplementedError extends DataAvailabilityError {\n static override readonly defaultErrorCode = \"DATA_AVAILABILITY\";\n\n constructor() {\n super({\n reason: \"model_unavailable\",\n source: \"climate-cache-browser\",\n hint: CLIMATE_GAPS_HINT,\n });\n this.name = \"ClimateGapsNotImplementedError\";\n }\n}\n"],"mappings":"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AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AACxB,CAAC;AAEM,IAAM,kBAAoD,oBAAI,IAAyB;AAAA,EAC5F,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ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","names":["minRow","maxRow","cols"]}
|