@chrtco/sdk 0.10.2 → 0.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -340,10 +340,11 @@ var TilesEndpoint = class {
340
340
  }
341
341
  region;
342
342
  tileBaseUrl;
343
- styleEndpoint(theme, symbols) {
343
+ styleEndpoint(opts) {
344
344
  const params = new URLSearchParams();
345
- if (theme) params.set("theme", theme);
346
- if (symbols) params.set("symbols", symbols);
345
+ if (opts.theme) params.set("theme", opts.theme);
346
+ if (opts.symbols) params.set("symbols", opts.symbols);
347
+ if (opts.mode) params.set("mode", opts.mode);
347
348
  const query2 = params.size > 0 ? `?${params.toString()}` : "";
348
349
  return `${this.tileBaseUrl}/v1/styles/${this.region}/style.json${query2}`;
349
350
  }
@@ -369,7 +370,7 @@ var TilesEndpoint = class {
369
370
  */
370
371
  async styleUrl(opts = {}) {
371
372
  await this.tileAuth.getToken(this.region);
372
- return this.styleEndpoint(opts.theme, opts.symbols);
373
+ return this.styleEndpoint(opts);
373
374
  }
374
375
  /**
375
376
  * Fetch the served S-52 style as a MapLibre style object (see
@@ -383,7 +384,7 @@ var TilesEndpoint = class {
383
384
  */
384
385
  async fetchStyle(opts = {}) {
385
386
  const token = await this.tileAuth.getToken(this.region);
386
- const res = await fetch(this.styleEndpoint(opts.theme, opts.symbols), {
387
+ const res = await fetch(this.styleEndpoint(opts), {
387
388
  headers: { authorization: `Bearer ${token.token}` },
388
389
  signal: opts.signal
389
390
  });
@@ -447,6 +448,79 @@ var CellsEndpoint = class {
447
448
  }
448
449
  };
449
450
 
451
+ // src/endpoints/weather.ts
452
+ var WeatherEndpoint = class {
453
+ constructor(http) {
454
+ this.http = http;
455
+ }
456
+ /**
457
+ * Observed conditions from the nearest reporting NOAA NDBC station.
458
+ *
459
+ * A **measurement, not a forecast**, and not live — most buoys report hourly
460
+ * and the median observation is around 40 minutes old. `observed.ageMinutes`
461
+ * is on every response and should be displayed: a readout that looks current
462
+ * but is 90 minutes stale is worse than one that says so.
463
+ *
464
+ * `unavailable` names every field the station did not report, so absence is
465
+ * stated rather than inferred from a missing key.
466
+ */
467
+ async conditions(options) {
468
+ return this.http.request(
469
+ "/weather/conditions",
470
+ {
471
+ lat: options.lat,
472
+ lon: options.lon,
473
+ units: options.units,
474
+ station: options.station
475
+ },
476
+ options.signal
477
+ );
478
+ }
479
+ /**
480
+ * Active NWS marine warnings for the zone — Small Craft Advisory, Gale,
481
+ * Storm, Hurricane Force Wind, Special Marine Warning. Most severe first.
482
+ *
483
+ * Its own call, so warnings can be re-checked cheaply (~60 s) without pulling
484
+ * a forecast you already have.
485
+ *
486
+ * **`expires` and `ends` are different.** `expires` is when the *bulletin*
487
+ * lapses — alerts are usually re-issued before then. `ends` is when the
488
+ * *hazard* is expected to be over. They are routinely hours apart, so
489
+ * describe the hazard with `ends` and use `expires` only to decide when to
490
+ * re-fetch.
491
+ *
492
+ * Display `instruction` verbatim: it is NWS's own advice to mariners.
493
+ */
494
+ async alerts(options) {
495
+ return this.http.request(
496
+ "/weather/marine-alerts",
497
+ { lat: options.lat, lon: options.lon, zone: options.zone },
498
+ options.signal
499
+ );
500
+ }
501
+ /**
502
+ * The NWS marine zone forecast — U.S. coastal and Great Lakes waters.
503
+ *
504
+ * Periods are NWS's own and are **neither hourly nor uniform**: `OVERNIGHT`,
505
+ * `TUE NIGHT`, `WED NIGHT THROUGH THU NIGHT`. A single period can span days.
506
+ * Flattening them into an hourly series invents resolution the data does not
507
+ * have.
508
+ *
509
+ * `expires` is the forecast's **own** stated validity, taken from the
510
+ * bulletin, not a TTL CHRT invented. `source.productId` identifies the
511
+ * upstream NWS product, so you can verify CHRT against NOAA directly.
512
+ *
513
+ * Offshore zones are not yet supported and fail with `501`.
514
+ */
515
+ async forecast(options) {
516
+ return this.http.request(
517
+ "/weather/marine-forecast",
518
+ { lat: options.lat, lon: options.lon, zone: options.zone },
519
+ options.signal
520
+ );
521
+ }
522
+ };
523
+
450
524
  // src/endpoints/coverage.ts
451
525
  var METRES_PER_NAUTICAL_MILE = 1852;
452
526
  var CoverageEndpoint = class {
@@ -958,7 +1032,9 @@ var OfflineEndpoint = class {
958
1032
  const token = await this.requireToken([region]);
959
1033
  const palette = opts.palette ?? "DAY";
960
1034
  const protocol = opts.protocol ?? "mbtiles";
961
- const path = `/offline/styles/${encodeURIComponent(region)}?palette=${palette}&protocol=${protocol}`;
1035
+ const symbolsParam = opts.symbols ? `&symbols=${encodeURIComponent(opts.symbols)}` : "";
1036
+ const modeParam = opts.mode ? `&mode=${encodeURIComponent(opts.mode)}` : "";
1037
+ const path = `/offline/styles/${encodeURIComponent(region)}?palette=${palette}&protocol=${protocol}${symbolsParam}${modeParam}`;
962
1038
  const res = await this.http.getJsonWithBearer(
963
1039
  path,
964
1040
  token.token
@@ -1303,157 +1379,519 @@ function dirname(p) {
1303
1379
  return p.slice(0, k);
1304
1380
  }
1305
1381
 
1306
- // src/interact/decode.ts
1307
- var LITCHR_TABLE = {
1308
- 1: { name: "Fixed", abbr: "F" },
1309
- 2: { name: "Flashing", abbr: "Fl" },
1310
- 3: { name: "Long Flashing", abbr: "LFl" },
1311
- 4: { name: "Occulting", abbr: "Oc" },
1312
- 5: { name: "Isophase", abbr: "Iso" },
1313
- 6: { name: "Short Flashing", abbr: "S.Fl" },
1314
- 7: { name: "Short Long Flashing", abbr: "S.LFl" },
1315
- 8: { name: "Alternating Occulting", abbr: "Al.Oc" },
1316
- 9: { name: "Alternating Long Flashing", abbr: "Al.LFl" },
1317
- 10: { name: "Alternating Flashing", abbr: "Al.Fl" },
1318
- 11: { name: "Alternating Group", abbr: "Al.Gp" },
1319
- 12: { name: "Morse", abbr: "Mo" },
1320
- 13: { name: "Quick", abbr: "Q" },
1321
- 14: { name: "Very Quick", abbr: "VQ" },
1322
- 15: { name: "Ultra Quick", abbr: "UQ" },
1323
- 16: { name: "Alternating", abbr: "Al" },
1324
- 17: { name: "Alternating Fixed/Flash", abbr: "Al.F.Fl" },
1325
- 25: { name: "Quick + Long Flash", abbr: "Q+LFl" },
1326
- 26: { name: "Very Quick + Long Flash", abbr: "VQ+LFl" },
1327
- 27: { name: "Ultra Quick + Long Flash", abbr: "UQ+LFl" },
1328
- 28: { name: "Alternating", abbr: "Al" },
1329
- 29: { name: "Fixed + Long Flash", abbr: "F.LFl" }
1382
+ // src/s57/codelists.generated.ts
1383
+ var BOYSHP_CODES = {
1384
+ 1: { code: 1, name: "Conical (nun, ogival)" },
1385
+ 2: { code: 2, name: "Can (cylindrical)" },
1386
+ 3: { code: 3, name: "Spherical" },
1387
+ 4: { code: 4, name: "Pillar" },
1388
+ 5: { code: 5, name: "Spar (spindle)" },
1389
+ 6: { code: 6, name: "Barrel (tun)" },
1390
+ 7: { code: 7, name: "Super-buoy" },
1391
+ 8: { code: 8, name: "Ice buoy" }
1392
+ };
1393
+ var CATACH_CODES = {
1394
+ 1: { code: 1, name: "Unrestricted anchorage" },
1395
+ 2: { code: 2, name: "Deep water anchorage" },
1396
+ 3: { code: 3, name: "Tanker anchorage" },
1397
+ 4: { code: 4, name: "Explosives anchorage" },
1398
+ 5: { code: 5, name: "Quarantine anchorage" },
1399
+ 6: { code: 6, name: "Sea-plane anchorage" },
1400
+ 7: { code: 7, name: "Small craft anchorage" },
1401
+ 8: { code: 8, name: "Small craft mooring area" },
1402
+ 9: { code: 9, name: "Anchorage for periods up to 24 hours" }
1403
+ };
1404
+ var CATCAM_CODES = {
1405
+ 1: { code: 1, name: "North cardinal mark" },
1406
+ 2: { code: 2, name: "East cardinal mark" },
1407
+ 3: { code: 3, name: "South cardinal mark" },
1408
+ 4: { code: 4, name: "West cardinal mark" }
1409
+ };
1410
+ var CATCBL_CODES = {
1411
+ 1: { code: 1, name: "Power line" },
1412
+ 2: { code: 2, name: "Submarine cable", supplement: true, unverified: true },
1413
+ 3: { code: 3, name: "Transmission line" },
1414
+ 4: { code: 4, name: "Telephone" },
1415
+ 5: { code: 5, name: "Telegraph" },
1416
+ 6: { code: 6, name: "Mooring cable/chain" }
1417
+ };
1418
+ var CATCOA_CODES = {
1419
+ 1: { code: 1, name: "Steep coast" },
1420
+ 2: { code: 2, name: "Flat coast" },
1421
+ 3: { code: 3, name: "Sandy shore" },
1422
+ 4: { code: 4, name: "Stony shore" },
1423
+ 5: { code: 5, name: "Shingly shore" },
1424
+ 6: { code: 6, name: "Glacier (seaward end)" },
1425
+ 7: { code: 7, name: "Mangrove" },
1426
+ 8: { code: 8, name: "Marshy shore" },
1427
+ 9: { code: 9, name: "Coral reef" },
1428
+ 10: { code: 10, name: "Ice coast" },
1429
+ 11: { code: 11, name: "Embankment", supplement: true, unverified: true }
1430
+ };
1431
+ var CATCRN_CODES = {
1432
+ 2: { code: 2, name: "Container crane/gantry" },
1433
+ 3: { code: 3, name: "Sheerlegs" },
1434
+ 4: { code: 4, name: "Travelling crane" },
1435
+ 5: { code: 5, name: "A-frame" }
1436
+ };
1437
+ var CATDPG_CODES = {
1438
+ 1: { code: 1, name: "General dumping ground", supplement: true, unverified: true },
1439
+ 2: { code: 2, name: "Chemical waste dumping ground" },
1440
+ 3: { code: 3, name: "Nuclear waste dumping ground" },
1441
+ 4: { code: 4, name: "Explosives dumping ground" },
1442
+ 5: { code: 5, name: "Spoil ground" },
1443
+ 6: { code: 6, name: "Vessel dumping ground" }
1444
+ };
1445
+ var CATFOG_CODES = {
1446
+ 1: { code: 1, name: "Explosive", abbr: "EXPLOS" },
1447
+ 2: { code: 2, name: "Diaphone", abbr: "DIA" },
1448
+ 3: { code: 3, name: "Siren", abbr: "SIREN" },
1449
+ 4: { code: 4, name: "Nautophone", abbr: "NAUTO" },
1450
+ 5: { code: 5, name: "Reed", abbr: "REED" },
1451
+ 6: { code: 6, name: "Tyfon", abbr: "TYFON" },
1452
+ 7: { code: 7, name: "Bell", abbr: "BELL" },
1453
+ 8: { code: 8, name: "Whistle", abbr: "WHIS" },
1454
+ 9: { code: 9, name: "Gong", abbr: "GONG" },
1455
+ 10: { code: 10, name: "Horn", abbr: "HORN" }
1456
+ };
1457
+ var CATHAF_CODES = {
1458
+ 1: { code: 1, name: "RoRo-terminal" },
1459
+ 3: { code: 3, name: "Ferry terminal" },
1460
+ 4: { code: 4, name: "Fishing harbour" },
1461
+ 5: { code: 5, name: "Yacht harbour/marina" },
1462
+ 6: { code: 6, name: "Naval base" },
1463
+ 7: { code: 7, name: "Tanker terminal" },
1464
+ 8: { code: 8, name: "Passenger terminal" },
1465
+ 9: { code: 9, name: "Shipyard" },
1466
+ 10: { code: 10, name: "Container terminal" },
1467
+ 11: { code: 11, name: "Bulk terminal" },
1468
+ 12: { code: 12, name: "Synchrolift", supplement: true, unverified: true },
1469
+ 13: { code: 13, name: "Straddle carrier", supplement: true, unverified: true },
1470
+ 14: { code: 14, name: "Port terminal", supplement: true, unverified: true }
1471
+ };
1472
+ var CATLAM_CODES = {
1473
+ 1: { code: 1, name: "Port-hand lateral mark" },
1474
+ 2: { code: 2, name: "Starboard-hand lateral mark" },
1475
+ 3: { code: 3, name: "Preferred channel to starboard lateral mark" },
1476
+ 4: { code: 4, name: "Preferred channel to port lateral mark" }
1477
+ };
1478
+ var CATLIT_CODES = {
1479
+ 1: { code: 1, name: "Directional function" },
1480
+ 4: { code: 4, name: "Leading light" },
1481
+ 5: { code: 5, name: "Aero light" },
1482
+ 6: { code: 6, name: "Air obstruction light" },
1483
+ 7: { code: 7, name: "Fog detector light" },
1484
+ 8: { code: 8, name: "Flood light" },
1485
+ 9: { code: 9, name: "Strip light" },
1486
+ 10: { code: 10, name: "Subsidiary light" },
1487
+ 11: { code: 11, name: "Spotlight" },
1488
+ 12: { code: 12, name: "Front" },
1489
+ 13: { code: 13, name: "Rear" },
1490
+ 14: { code: 14, name: "Lower" },
1491
+ 15: { code: 15, name: "Upper" },
1492
+ 16: { code: 16, name: "Moir\xE9 effect" },
1493
+ 17: { code: 17, name: "Emergency" },
1494
+ 18: { code: 18, name: "Bearing light" },
1495
+ 19: { code: 19, name: "Horizontally disposed" },
1496
+ 20: { code: 20, name: "Vertically disposed" }
1497
+ };
1498
+ var CATLMK_CODES = {
1499
+ 1: { code: 1, name: "Cairn" },
1500
+ 2: { code: 2, name: "Cemetery" },
1501
+ 3: { code: 3, name: "Chimney" },
1502
+ 4: { code: 4, name: "Dish aerial" },
1503
+ 5: { code: 5, name: "Flagstaff (flagpole)" },
1504
+ 6: { code: 6, name: "Flare stack" },
1505
+ 7: { code: 7, name: "Mast" },
1506
+ 8: { code: 8, name: "Windsock" },
1507
+ 9: { code: 9, name: "Monument" },
1508
+ 10: { code: 10, name: "Column (pillar)" },
1509
+ 11: { code: 11, name: "Memorial plaque" },
1510
+ 12: { code: 12, name: "Obelisk" },
1511
+ 13: { code: 13, name: "Statue" },
1512
+ 14: { code: 14, name: "Cross" },
1513
+ 15: { code: 15, name: "Dome" },
1514
+ 16: { code: 16, name: "Radar scanner" },
1515
+ 17: { code: 17, name: "Tower" },
1516
+ 18: { code: 18, name: "Windmill" },
1517
+ 19: { code: 19, name: "Windmotor" },
1518
+ 20: { code: 20, name: "Spire/minaret" }
1519
+ };
1520
+ var CATMFA_CODES = {
1521
+ 1: { code: 1, name: "Crustaceans" },
1522
+ 2: { code: 2, name: "Oyster/mussels" },
1523
+ 3: { code: 3, name: "Fish" },
1524
+ 4: { code: 4, name: "Seaweed" },
1525
+ 5: { code: 5, name: "Seaweed / kelp farm", supplement: true, unverified: true }
1526
+ };
1527
+ var CATOBS_CODES = {
1528
+ 1: { code: 1, name: "Snag / stump" },
1529
+ 2: { code: 2, name: "Wellhead" },
1530
+ 3: { code: 3, name: "Diffuser" },
1531
+ 4: { code: 4, name: "Crib" },
1532
+ 5: { code: 5, name: "Fish haven" },
1533
+ 6: { code: 6, name: "Foul area" },
1534
+ 7: { code: 7, name: "Foul ground" },
1535
+ 8: { code: 8, name: "Ice boom" },
1536
+ 9: { code: 9, name: "Ground tackle" },
1537
+ 10: { code: 10, name: "Boom", supplement: true, unverified: true },
1538
+ 11: { code: 11, name: "Platform", supplement: true, unverified: true }
1539
+ };
1540
+ var CATPIP_CODES = {
1541
+ 1: { code: 1, name: "Pipeline in general", supplement: true, unverified: true },
1542
+ 2: { code: 2, name: "Outfall pipe" },
1543
+ 3: { code: 3, name: "Intake pipe" },
1544
+ 4: { code: 4, name: "Sewer" },
1545
+ 5: { code: 5, name: "Bubbler system" },
1546
+ 6: { code: 6, name: "Supply pipe" }
1330
1547
  };
1331
- var COLOUR_TABLE = {
1332
- 1: { name: "White", abbr: "W", hex: "#ffffff" },
1333
- 2: { name: "Black", abbr: "B", hex: "#333333" },
1334
- 3: { name: "Red", abbr: "R", hex: "#ef4444" },
1335
- 4: { name: "Green", abbr: "G", hex: "#22c55e" },
1336
- 5: { name: "Blue", abbr: "Bu", hex: "#3b82f6" },
1337
- 6: { name: "Yellow", abbr: "Y", hex: "#eab308" },
1338
- 7: { name: "Grey", abbr: "Gr", hex: "#9ca3af" },
1339
- 8: { name: "Brown", abbr: "Bn", hex: "#92400e" },
1340
- 9: { name: "Amber", abbr: "Am", hex: "#f59e0b" },
1341
- 10: { name: "Violet", abbr: "Vi", hex: "#8b5cf6" },
1342
- 11: { name: "Orange", abbr: "Or", hex: "#f97316" },
1343
- 12: { name: "Magenta", abbr: "Mg", hex: "#d946ef" },
1344
- 13: { name: "Pink", abbr: "Pk", hex: "#f472b6" }
1548
+ var CATREA_CODES = {
1549
+ 1: { code: 1, name: "Offshore safety zone" },
1550
+ 2: { code: 2, name: "Anchoring prohibition", supplement: true, unverified: true },
1551
+ 3: { code: 3, name: "Fishing prohibition", supplement: true, unverified: true },
1552
+ 4: { code: 4, name: "Nature reserve" },
1553
+ 5: { code: 5, name: "Bird sanctuary" },
1554
+ 6: { code: 6, name: "Game preserve" },
1555
+ 7: { code: 7, name: "Seal sanctuary" },
1556
+ 8: { code: 8, name: "Degaussing range" },
1557
+ 9: { code: 9, name: "Military area" },
1558
+ 10: { code: 10, name: "Historic wreck area" },
1559
+ 12: { code: 12, name: "Navigational aid safety zone" },
1560
+ 14: { code: 14, name: "Minefield" },
1561
+ 18: { code: 18, name: "Swimming area" },
1562
+ 19: { code: 19, name: "Waiting area" },
1563
+ 20: { code: 20, name: "Research area" },
1564
+ 21: { code: 21, name: "Dredging area" },
1565
+ 22: { code: 22, name: "Fish sanctuary" },
1566
+ 23: { code: 23, name: "Ecological reserve" },
1567
+ 24: { code: 24, name: "No wake area" },
1568
+ 25: { code: 25, name: "Swinging area" },
1569
+ 26: { code: 26, name: "No fishing area", supplement: true, unverified: true },
1570
+ 27: { code: 27, name: "Speed restriction zone", supplement: true, unverified: true },
1571
+ 28: { code: 28, name: "To be avoided area", supplement: true, unverified: true }
1345
1572
  };
1346
- var BOYSHP_TABLE = {
1347
- 1: "Conical (nun)",
1348
- 2: "Can (cylindrical)",
1349
- 3: "Spherical",
1350
- 4: "Pillar",
1351
- 5: "Spar",
1352
- 6: "Barrel",
1353
- 7: "Super buoy",
1354
- 8: "Ice buoy"
1573
+ var CATSCF_CODES = {
1574
+ 1: { code: 1, name: "Visitors' berth" },
1575
+ 2: { code: 2, name: "Nautical club" },
1576
+ 3: { code: 3, name: "Boat hoist" },
1577
+ 4: { code: 4, name: "Sailmaker" },
1578
+ 5: { code: 5, name: "Boatyard" },
1579
+ 6: { code: 6, name: "Public inn" },
1580
+ 7: { code: 7, name: "Restaurant" },
1581
+ 8: { code: 8, name: "Chandler" },
1582
+ 9: { code: 9, name: "Provisions" },
1583
+ 10: { code: 10, name: "Doctor" },
1584
+ 11: { code: 11, name: "Pharmacy" },
1585
+ 12: { code: 12, name: "Water tap" },
1586
+ 13: { code: 13, name: "Fuel station" },
1587
+ 14: { code: 14, name: "Electricity" },
1588
+ 15: { code: 15, name: "Bottle gas" },
1589
+ 16: { code: 16, name: "Showers" },
1590
+ 17: { code: 17, name: "Launderette" },
1591
+ 18: { code: 18, name: "Public toilets" },
1592
+ 19: { code: 19, name: "Post box" },
1593
+ 20: { code: 20, name: "Public telephone" },
1594
+ 21: { code: 21, name: "Refuse bin" },
1595
+ 22: { code: 22, name: "Car park" },
1596
+ 23: { code: 23, name: "Parking for boats and trailers" },
1597
+ 24: { code: 24, name: "Caravan site" },
1598
+ 25: { code: 25, name: "Camping site" },
1599
+ 26: { code: 26, name: "Sewerage pump-out station" },
1600
+ 27: { code: 27, name: "Emergency telephone" },
1601
+ 28: { code: 28, name: "Landing / launching place for boats" },
1602
+ 29: { code: 29, name: "Visitors mooring" },
1603
+ 30: { code: 30, name: "Scrubbing berth" },
1604
+ 31: { code: 31, name: "Picnic area" }
1355
1605
  };
1356
- var CATLAM_TABLE = {
1357
- 1: "Port",
1358
- 2: "Starboard",
1359
- 3: "Preferred channel to starboard",
1360
- 4: "Preferred channel to port"
1606
+ var CATWRK_CODES = {
1607
+ 1: { code: 1, name: "Non-dangerous wreck" },
1608
+ 2: { code: 2, name: "Dangerous wreck" },
1609
+ 3: { code: 3, name: "Distributed remains of wreck" },
1610
+ 4: { code: 4, name: "Wreck showing mast/masts" },
1611
+ 5: { code: 5, name: "Wreck showing any portion of hull or superstructure" }
1361
1612
  };
1362
- var CATCAM_TABLE = {
1363
- 1: "North cardinal",
1364
- 2: "East cardinal",
1365
- 3: "South cardinal",
1366
- 4: "West cardinal"
1613
+ var COLOUR_CODES = {
1614
+ 1: { code: 1, name: "White", abbr: "W" },
1615
+ 2: { code: 2, name: "Black", abbr: "B" },
1616
+ 3: { code: 3, name: "Red", abbr: "R" },
1617
+ 4: { code: 4, name: "Green", abbr: "G" },
1618
+ 5: { code: 5, name: "Blue", abbr: "Bu" },
1619
+ 6: { code: 6, name: "Yellow", abbr: "Y" },
1620
+ 7: { code: 7, name: "Grey", abbr: "Gr" },
1621
+ 8: { code: 8, name: "Brown", abbr: "Bn" },
1622
+ 9: { code: 9, name: "Amber", abbr: "Am" },
1623
+ 10: { code: 10, name: "Violet", abbr: "Vi" },
1624
+ 11: { code: 11, name: "Orange", abbr: "Or" },
1625
+ 12: { code: 12, name: "Magenta", abbr: "Mg" },
1626
+ 13: { code: 13, name: "Pink", abbr: "Pk" }
1367
1627
  };
1368
- var CATLMK_TABLE = {
1369
- 1: "Cairn",
1370
- 2: "Cemetery",
1371
- 3: "Chimney",
1372
- 4: "Dish aerial",
1373
- 5: "Flagstaff",
1374
- 6: "Flare stack",
1375
- 7: "Mast",
1376
- 8: "Windsock",
1377
- 9: "Monument",
1378
- 10: "Column / pillar",
1379
- 11: "Memorial plaque",
1380
- 12: "Obelisk",
1381
- 13: "Statue",
1382
- 14: "Cross",
1383
- 15: "Dome",
1384
- 16: "Radar scanner",
1385
- 17: "Tower",
1386
- 18: "Windmill",
1387
- 19: "Wind turbine",
1388
- 20: "Spire"
1628
+ var CONDTN_CODES = {
1629
+ 1: { code: 1, name: "Under construction" },
1630
+ 2: { code: 2, name: "Ruined" },
1631
+ 3: { code: 3, name: "Under reclamation" },
1632
+ 4: { code: 4, name: "Wingless" },
1633
+ 5: { code: 5, name: "Planned construction" }
1389
1634
  };
1390
- var CATFOG_TABLE = {
1391
- 1: "Explosive",
1392
- 2: "Diaphone",
1393
- 3: "Siren",
1394
- 4: "Nautophone",
1395
- 5: "Bell",
1396
- 6: "Whistle",
1397
- 7: "Reed",
1398
- 8: "Gong",
1399
- 9: "Horn"
1635
+ var LITCHR_CODES = {
1636
+ 1: { code: 1, name: "Fixed", abbr: "F" },
1637
+ 2: { code: 2, name: "Flashing", abbr: "Fl" },
1638
+ 3: { code: 3, name: "Long-flashing", abbr: "LFl" },
1639
+ 4: { code: 4, name: "Quick-flashing", abbr: "Q" },
1640
+ 5: { code: 5, name: "Very quick-flashing", abbr: "VQ" },
1641
+ 6: { code: 6, name: "Ultra quick-flashing", abbr: "UQ" },
1642
+ 7: { code: 7, name: "Isophase", abbr: "Iso" },
1643
+ 8: { code: 8, name: "Occulting", abbr: "Oc" },
1644
+ 9: { code: 9, name: "Interrupted quick-flashing", abbr: "IQ" },
1645
+ 10: { code: 10, name: "Interrupted very quick-flashing", abbr: "IVQ" },
1646
+ 11: { code: 11, name: "Interrupted ultra quick-flashing", abbr: "IUQ" },
1647
+ 12: { code: 12, name: "Morse", abbr: "Mo" },
1648
+ 13: { code: 13, name: "Fixed / flash", abbr: "FFl" },
1649
+ 14: { code: 14, name: "Flash / long-flash", abbr: "Fl+LFl" },
1650
+ 15: { code: 15, name: "Occulting / flash", abbr: "Oc+Fl" },
1651
+ 16: { code: 16, name: "Fixed / long-flash", abbr: "FLFl" },
1652
+ 17: { code: 17, name: "Occulting alternating", abbr: "Al.Oc" },
1653
+ 18: { code: 18, name: "Long-flash alternating", abbr: "Al.LFl" },
1654
+ 19: { code: 19, name: "Flash alternating", abbr: "Al.Fl" },
1655
+ 20: { code: 20, name: "Group alternating", abbr: "Al.Gr" },
1656
+ 25: { code: 25, name: "Quick-flash plus long-flash", abbr: "Q+LFl" },
1657
+ 26: { code: 26, name: "Very quick-flash plus long-flash", abbr: "VQ+LFl" },
1658
+ 27: { code: 27, name: "Ultra quick-flash plus long-flash", abbr: "UQ+LFl" },
1659
+ 28: { code: 28, name: "Alternating", abbr: "Al" },
1660
+ 29: { code: 29, name: "Fixed and alternating flashing", abbr: "F.Al.Fl" }
1400
1661
  };
1401
- var CATFOG_ABBR_TABLE = {
1402
- 1: "EXPLOS",
1403
- 2: "DIA",
1404
- 3: "SIREN",
1405
- 4: "NAUTO",
1406
- 5: "BELL",
1407
- 6: "WHIS",
1408
- 7: "REED",
1409
- 8: "GONG",
1410
- 9: "HORN"
1662
+ var MARSYS_CODES = {
1663
+ 1: { code: 1, name: "IALA A" },
1664
+ 2: { code: 2, name: "IALA B" },
1665
+ 9: { code: 9, name: "No system" },
1666
+ 10: { code: 10, name: "Other system" }
1411
1667
  };
1412
- var TOPSHP_TABLE = {
1413
- 1: "Cone, point up",
1414
- 2: "Cone, point down",
1415
- 3: "Sphere",
1416
- 4: "2 spheres",
1417
- 5: "Cylinder",
1418
- 6: "Board",
1419
- 7: "X-shape",
1420
- 8: "Upright cross",
1421
- 9: "Cube, point up",
1422
- 10: "2 cones, point to point",
1423
- 11: "2 cones, base to base",
1424
- 12: "Rhombus",
1425
- 13: "2 cones, up",
1426
- 14: "2 cones, down",
1427
- 15: "Besom, point up",
1428
- 16: "Besom, point down",
1429
- 17: "Flag",
1430
- 18: "Sphere over rhombus",
1431
- 19: "Square",
1432
- 33: "T-shape"
1668
+ var NATSUR_CODES = {
1669
+ 1: { code: 1, name: "Mud" },
1670
+ 2: { code: 2, name: "Clay" },
1671
+ 3: { code: 3, name: "Silt" },
1672
+ 4: { code: 4, name: "Sand" },
1673
+ 5: { code: 5, name: "Stone" },
1674
+ 6: { code: 6, name: "Gravel" },
1675
+ 7: { code: 7, name: "Pebbles" },
1676
+ 8: { code: 8, name: "Cobbles" },
1677
+ 9: { code: 9, name: "Rock" },
1678
+ 11: { code: 11, name: "Lava" },
1679
+ 14: { code: 14, name: "Coral" },
1680
+ 17: { code: 17, name: "Shells" },
1681
+ 18: { code: 18, name: "Boulder" }
1433
1682
  };
1434
- var STATUS_TABLE = {
1435
- 1: "Permanent",
1436
- 2: "Occasional",
1437
- 3: "Recommended",
1438
- 4: "Not in use",
1439
- 5: "Periodic/intermittent",
1440
- 6: "Reserved",
1441
- 7: "Temporary",
1442
- 8: "Private",
1443
- 9: "Mandatory",
1444
- 11: "Extinguished",
1445
- 12: "Illuminated",
1446
- 13: "Historic",
1447
- 14: "Public",
1448
- 15: "Synchronized",
1449
- 16: "Watched",
1450
- 17: "Un-watched",
1451
- 18: "Existence doubtful"
1683
+ var QUASOU_CODES = {
1684
+ 1: { code: 1, name: "Depth known" },
1685
+ 2: { code: 2, name: "Depth unknown" },
1686
+ 3: { code: 3, name: "Doubtful sounding" },
1687
+ 4: { code: 4, name: "Unreliable sounding" },
1688
+ 5: { code: 5, name: "No bottom found at value shown" },
1689
+ 6: { code: 6, name: "Least depth known" },
1690
+ 7: { code: 7, name: "Least depth unknown, safe clearance at value shown" },
1691
+ 8: { code: 8, name: "Value reported (not surveyed)" },
1692
+ 9: { code: 9, name: "Value reported (not confirmed)" },
1693
+ 10: { code: 10, name: "Maintained depth" },
1694
+ 11: { code: 11, name: "Not regularly maintained" }
1452
1695
  };
1453
- var MARSYS_TABLE = {
1454
- 1: "IALA-A",
1455
- 2: "IALA-B"
1696
+ var RESTRN_CODES = {
1697
+ 1: { code: 1, name: "Anchoring prohibited" },
1698
+ 2: { code: 2, name: "Anchoring restricted" },
1699
+ 3: { code: 3, name: "Fishing prohibited" },
1700
+ 4: { code: 4, name: "Fishing restricted" },
1701
+ 5: { code: 5, name: "Trawling prohibited" },
1702
+ 6: { code: 6, name: "Trawling restricted" },
1703
+ 7: { code: 7, name: "Entry prohibited" },
1704
+ 8: { code: 8, name: "Entry restricted" },
1705
+ 9: { code: 9, name: "Dredging prohibited" },
1706
+ 10: { code: 10, name: "Dredging restricted" },
1707
+ 11: { code: 11, name: "Diving prohibited" },
1708
+ 12: { code: 12, name: "Diving restricted" },
1709
+ 13: { code: 13, name: "No wake" },
1710
+ 14: { code: 14, name: "Area to be avoided" },
1711
+ 15: { code: 15, name: "Construction prohibited" },
1712
+ 16: { code: 16, name: "Discharging prohibited", supplement: true, unverified: true },
1713
+ 17: { code: 17, name: "Discharging restricted", supplement: true, unverified: true },
1714
+ 18: { code: 18, name: "Industrial prohibited", supplement: true, unverified: true },
1715
+ 19: { code: 19, name: "Metallic hull vessels prohibited", supplement: true, unverified: true },
1716
+ 20: { code: 20, name: "Navigating prohibited", supplement: true, unverified: true },
1717
+ 21: { code: 21, name: "Speed restricted", supplement: true, unverified: true },
1718
+ 24: { code: 24, name: "Stopping prohibited", supplement: true, unverified: true },
1719
+ 25: { code: 25, name: "Landing prohibited", supplement: true, unverified: true }
1456
1720
  };
1721
+ var STATUS_CODES = {
1722
+ 1: { code: 1, name: "Permanent" },
1723
+ 2: { code: 2, name: "Occasional" },
1724
+ 3: { code: 3, name: "Recommended" },
1725
+ 4: { code: 4, name: "Disused" },
1726
+ 5: { code: 5, name: "Periodically/intermittent" },
1727
+ 6: { code: 6, name: "Reserved" },
1728
+ 7: { code: 7, name: "Temporary" },
1729
+ 8: { code: 8, name: "Private" },
1730
+ 9: { code: 9, name: "Mandatory" },
1731
+ 11: { code: 11, name: "Extinguished" },
1732
+ 12: { code: 12, name: "Illuminated" },
1733
+ 13: { code: 13, name: "Historic" },
1734
+ 14: { code: 14, name: "Public" },
1735
+ 15: { code: 15, name: "Synchronized" },
1736
+ 16: { code: 16, name: "Watched" },
1737
+ 17: { code: 17, name: "Un-watched" },
1738
+ 18: { code: 18, name: "Existence doubtful" }
1739
+ };
1740
+ var TOPSHP_CODES = {
1741
+ 1: { code: 1, name: "Cone, point up" },
1742
+ 2: { code: 2, name: "Cone, point down" },
1743
+ 3: { code: 3, name: "Sphere" },
1744
+ 4: { code: 4, name: "2 sphere" },
1745
+ 5: { code: 5, name: "Cylinder (can)" },
1746
+ 6: { code: 6, name: "Board" },
1747
+ 7: { code: 7, name: "X-shape (St. Andrew's cross)" },
1748
+ 8: { code: 8, name: "Upright cross (St. George cross)" },
1749
+ 9: { code: 9, name: "Cube, point up" },
1750
+ 10: { code: 10, name: "2 cones, point to point" },
1751
+ 11: { code: 11, name: "2 cones, base to base" },
1752
+ 12: { code: 12, name: "Rhombus (diamond)" },
1753
+ 13: { code: 13, name: "2 cones (points upward)" },
1754
+ 14: { code: 14, name: "2 cones (points downward)" },
1755
+ 15: { code: 15, name: "Besom, point up (broom or perch)" },
1756
+ 16: { code: 16, name: "Besom, point down (broom or perch)" },
1757
+ 17: { code: 17, name: "Flag" },
1758
+ 18: { code: 18, name: "Sphere over rhombus" },
1759
+ 19: { code: 19, name: "Square" },
1760
+ 20: { code: 20, name: "Rectangle, horizontal" },
1761
+ 21: { code: 21, name: "Rectangle, vertical" },
1762
+ 22: { code: 22, name: "Trapezium, up" },
1763
+ 23: { code: 23, name: "Trapezium, down" },
1764
+ 24: { code: 24, name: "Triangle, point up" },
1765
+ 25: { code: 25, name: "Triangle, point down" },
1766
+ 26: { code: 26, name: "Circle" },
1767
+ 27: { code: 27, name: "Two upright crosses (one over the other)" },
1768
+ 28: { code: 28, name: "T-shape" },
1769
+ 29: { code: 29, name: "Triangle pointing up over a circle" },
1770
+ 30: { code: 30, name: "Upright cross over a circle" },
1771
+ 31: { code: 31, name: "Rhombus over a circle" },
1772
+ 32: { code: 32, name: "Circle over a triangle pointing up" },
1773
+ 33: { code: 33, name: "Other shape (see INFORM)" }
1774
+ };
1775
+ var TRAFIC_CODES = {
1776
+ 1: { code: 1, name: "Inbound" },
1777
+ 2: { code: 2, name: "Outbound" },
1778
+ 3: { code: 3, name: "One-way" },
1779
+ 4: { code: 4, name: "Two-way" }
1780
+ };
1781
+ var WATLEV_CODES = {
1782
+ 1: { code: 1, name: "Partly submerged at high water" },
1783
+ 2: { code: 2, name: "Always dry" },
1784
+ 3: { code: 3, name: "Always under water/submerged" },
1785
+ 4: { code: 4, name: "Covers and uncovers" },
1786
+ 5: { code: 5, name: "Awash" },
1787
+ 6: { code: 6, name: "Subject to inundation or flooding" },
1788
+ 7: { code: 7, name: "Floating", supplement: true, unverified: true }
1789
+ };
1790
+ var S57_CODELISTS = /* @__PURE__ */ new Map([
1791
+ ["BOYSHP", BOYSHP_CODES],
1792
+ ["CATACH", CATACH_CODES],
1793
+ ["CATCAM", CATCAM_CODES],
1794
+ ["CATCBL", CATCBL_CODES],
1795
+ ["CATCOA", CATCOA_CODES],
1796
+ ["CATCRN", CATCRN_CODES],
1797
+ ["CATDPG", CATDPG_CODES],
1798
+ ["CATFOG", CATFOG_CODES],
1799
+ ["CATHAF", CATHAF_CODES],
1800
+ ["CATLAM", CATLAM_CODES],
1801
+ ["CATLIT", CATLIT_CODES],
1802
+ ["CATLMK", CATLMK_CODES],
1803
+ ["CATMFA", CATMFA_CODES],
1804
+ ["CATOBS", CATOBS_CODES],
1805
+ ["CATPIP", CATPIP_CODES],
1806
+ ["CATREA", CATREA_CODES],
1807
+ ["CATSCF", CATSCF_CODES],
1808
+ ["CATWRK", CATWRK_CODES],
1809
+ ["COLOUR", COLOUR_CODES],
1810
+ ["CONDTN", CONDTN_CODES],
1811
+ ["LITCHR", LITCHR_CODES],
1812
+ ["MARSYS", MARSYS_CODES],
1813
+ ["NATSUR", NATSUR_CODES],
1814
+ ["QUASOU", QUASOU_CODES],
1815
+ ["RESTRN", RESTRN_CODES],
1816
+ ["STATUS", STATUS_CODES],
1817
+ ["TOPSHP", TOPSHP_CODES],
1818
+ ["TRAFIC", TRAFIC_CODES],
1819
+ ["WATLEV", WATLEV_CODES]
1820
+ ]);
1821
+ var S57_DOMAINS = new Map(
1822
+ [...S57_CODELISTS].map(([acronym, list]) => [
1823
+ acronym,
1824
+ new Set(Object.keys(list).map(Number))
1825
+ ])
1826
+ );
1827
+ var nameTableCache = /* @__PURE__ */ new Map();
1828
+ var abbrTableCache = /* @__PURE__ */ new Map();
1829
+ function s57NameTable(acronym) {
1830
+ let cached = nameTableCache.get(acronym);
1831
+ if (cached === void 0) {
1832
+ const out = {};
1833
+ for (const c of Object.values(S57_CODELISTS.get(acronym) ?? {})) out[c.code] = c.name;
1834
+ cached = Object.freeze(out);
1835
+ nameTableCache.set(acronym, cached);
1836
+ }
1837
+ return cached;
1838
+ }
1839
+ function s57AbbrTable(acronym) {
1840
+ let cached = abbrTableCache.get(acronym);
1841
+ if (cached === void 0) {
1842
+ const out = {};
1843
+ for (const c of Object.values(S57_CODELISTS.get(acronym) ?? {})) {
1844
+ if (c.abbr !== void 0) out[c.code] = c.abbr;
1845
+ }
1846
+ cached = Object.freeze(out);
1847
+ abbrTableCache.set(acronym, cached);
1848
+ }
1849
+ return cached;
1850
+ }
1851
+
1852
+ // src/interact/decode.ts
1853
+ function nameAbbrTable(acronym) {
1854
+ const names = s57NameTable(acronym);
1855
+ const abbrs = s57AbbrTable(acronym);
1856
+ const out = {};
1857
+ for (const [code, name] of Object.entries(names)) {
1858
+ const abbr = abbrs[Number(code)];
1859
+ if (abbr !== void 0) out[Number(code)] = { name, abbr };
1860
+ }
1861
+ return out;
1862
+ }
1863
+ var COLOUR_HEX = {
1864
+ 1: "#ffffff",
1865
+ 2: "#333333",
1866
+ 3: "#ef4444",
1867
+ 4: "#22c55e",
1868
+ 5: "#3b82f6",
1869
+ 6: "#eab308",
1870
+ 7: "#9ca3af",
1871
+ 8: "#92400e",
1872
+ 9: "#f59e0b",
1873
+ 10: "#8b5cf6",
1874
+ 11: "#f97316",
1875
+ 12: "#d946ef",
1876
+ 13: "#f472b6"
1877
+ };
1878
+ var LITCHR_TABLE = nameAbbrTable("LITCHR");
1879
+ var COLOUR_TABLE = Object.fromEntries(
1880
+ Object.values(COLOUR_CODES).filter((c) => c.abbr !== void 0 && COLOUR_HEX[c.code] !== void 0).map((c) => [c.code, { name: c.name, abbr: c.abbr, hex: COLOUR_HEX[c.code] }])
1881
+ );
1882
+ var BOYSHP_TABLE = s57NameTable("BOYSHP");
1883
+ var CATLAM_TABLE = s57NameTable("CATLAM");
1884
+ var CATCAM_TABLE = s57NameTable("CATCAM");
1885
+ var CATLMK_TABLE = s57NameTable("CATLMK");
1886
+ var CATFOG_TABLE = s57NameTable("CATFOG");
1887
+ var CATFOG_ABBR_TABLE = s57AbbrTable("CATFOG");
1888
+ var CATFOG_NAUTOPHONE = Object.values(CATFOG_CODES).find(
1889
+ (c) => c.name.toLowerCase() === "nautophone"
1890
+ )?.code;
1891
+ var CATLIT_TABLE = s57NameTable("CATLIT");
1892
+ var TOPSHP_TABLE = s57NameTable("TOPSHP");
1893
+ var STATUS_TABLE = s57NameTable("STATUS");
1894
+ var MARSYS_TABLE = s57NameTable("MARSYS");
1457
1895
  var LAYER_TYPE_MAP = {
1458
1896
  BOYLAT: "Lateral Buoy",
1459
1897
  BOYCAR: "Cardinal Buoy",
@@ -1647,12 +2085,7 @@ var CATBRG_LABELS = {
1647
2085
  11: "Aqueduct",
1648
2086
  12: "Suspension bridge"
1649
2087
  };
1650
- var CONDTN_TABLE = {
1651
- 1: "Under construction",
1652
- 2: "Ruined",
1653
- 3: "Under reclamation",
1654
- 5: "Planned"
1655
- };
2088
+ var CONDTN_TABLE = s57NameTable("CONDTN");
1656
2089
  function parseFirstNum(val) {
1657
2090
  if (val == null) return null;
1658
2091
  const s = String(val);
@@ -1694,185 +2127,21 @@ function decodeBridgeProps(props) {
1694
2127
  sourceDate: props.SORDAT ? String(props.SORDAT) : null
1695
2128
  };
1696
2129
  }
1697
- var CATOBS_TABLE = {
1698
- 1: "Snag / stump",
1699
- 2: "Wellhead",
1700
- 3: "Diffuser",
1701
- 4: "Crib",
1702
- 5: "Fish haven",
1703
- 6: "Foul area",
1704
- 7: "Foul ground",
1705
- 8: "Ice boom",
1706
- 9: "Ground tackle",
1707
- 10: "Boom",
1708
- 11: "Platform"
1709
- };
1710
- var CATWRK_TABLE = {
1711
- 1: "Non-dangerous",
1712
- 2: "Dangerous",
1713
- 3: "Distributed remains",
1714
- 4: "Mast showing",
1715
- 5: "Hull showing"
1716
- };
1717
- var WATLEV_TABLE = {
1718
- 1: "Partly submerged at high water",
1719
- 2: "Always dry",
1720
- 3: "Always submerged",
1721
- 4: "Covers and uncovers",
1722
- 5: "Awash",
1723
- 6: "Subject to inundation / flooding",
1724
- 7: "Floating"
1725
- };
1726
- var CATREA_TABLE = {
1727
- 1: "Offshore safety zone",
1728
- 2: "Anchoring prohibition",
1729
- 3: "Fishing prohibition",
1730
- 4: "Nature reserve",
1731
- 5: "Bird sanctuary",
1732
- 6: "Game preserve",
1733
- 7: "Seal sanctuary",
1734
- 8: "Degaussing range",
1735
- 9: "Military area",
1736
- 10: "Historic wreck",
1737
- 12: "Navigational aid safety zone",
1738
- 14: "No wake zone",
1739
- 18: "Swimming area",
1740
- 19: "Waiting area",
1741
- 20: "Research area",
1742
- 21: "Dredging area",
1743
- 22: "Fish sanctuary",
1744
- 23: "Ecological reserve",
1745
- 24: "No discharge zone",
1746
- 25: "No anchoring area",
1747
- 26: "No fishing area",
1748
- 27: "Speed restriction zone",
1749
- 28: "To be avoided area"
1750
- };
1751
- var RESTRN_TABLE = {
1752
- 1: "Anchoring prohibited",
1753
- 2: "Anchoring restricted",
1754
- 3: "Fishing prohibited",
1755
- 4: "Fishing restricted",
1756
- 5: "Trawling prohibited",
1757
- 6: "Trawling restricted",
1758
- 7: "Entry prohibited",
1759
- 8: "Entry restricted",
1760
- 9: "Dredging prohibited",
1761
- 10: "Dredging restricted",
1762
- 11: "Diving prohibited",
1763
- 12: "Diving restricted",
1764
- 13: "No wake",
1765
- 14: "To be avoided",
1766
- 15: "Construction prohibited",
1767
- 16: "Discharging prohibited",
1768
- 17: "Discharging restricted",
1769
- 18: "Industrial prohibited",
1770
- 19: "Metallic hull vessels prohibited",
1771
- 20: "Navigating prohibited",
1772
- 21: "Speed restricted",
1773
- 24: "Stopping prohibited",
1774
- 25: "Landing prohibited"
1775
- };
1776
- var CATHAF_TABLE = {
1777
- 1: "RoRo terminal",
1778
- 3: "Ferry terminal",
1779
- 4: "Fishing harbour",
1780
- 5: "Yacht harbour / marina",
1781
- 6: "Naval base",
1782
- 7: "Tanker terminal",
1783
- 8: "Passenger terminal",
1784
- 9: "Shipyard",
1785
- 10: "Container terminal",
1786
- 11: "Bulk terminal",
1787
- 12: "Synchrolift",
1788
- 13: "Straddle carrier",
1789
- 14: "Port terminal"
1790
- };
1791
- var CATSCF_TABLE = {
1792
- 1: "Visitors' berth",
1793
- 2: "Nautical club",
1794
- 3: "Boat hoist",
1795
- 4: "Sailmaker",
1796
- 5: "Boatyard",
1797
- 6: "Public inn",
1798
- 7: "Restaurant",
1799
- 8: "Chandler",
1800
- 9: "Provisions",
1801
- 10: "Doctor",
1802
- 11: "Pharmacy",
1803
- 12: "Water tap",
1804
- 13: "Fuel station",
1805
- 14: "Electricity",
1806
- 15: "Bottle gas",
1807
- 16: "Showers",
1808
- 17: "Launderette",
1809
- 18: "Public toilets",
1810
- 19: "Post box"
1811
- };
1812
- var CATCRN_TABLE = {
1813
- 2: "Container crane / gantry",
1814
- 3: "Sheerlegs",
1815
- 4: "Travelling crane"
1816
- };
1817
- var CATACH_TABLE = {
1818
- 1: "Unrestricted anchorage",
1819
- 2: "Deep water anchorage",
1820
- 3: "Tanker anchorage",
1821
- 4: "Explosives anchorage",
1822
- 5: "Quarantine anchorage",
1823
- 6: "Sea-plane anchorage",
1824
- 7: "Small craft anchorage",
1825
- 8: "Small craft mooring area",
1826
- 9: "Anchorage for 24 hours or less"
1827
- };
1828
- var CATDPG_TABLE = {
1829
- 1: "General dumping ground",
1830
- 2: "Chemical waste",
1831
- 3: "Nuclear waste",
1832
- 4: "Explosives",
1833
- 5: "Spoil ground",
1834
- 6: "Vessel dumping ground"
1835
- };
1836
- var CATMFA_TABLE = {
1837
- 1: "Crustaceans",
1838
- 2: "Oysters / mussels",
1839
- 3: "Fish",
1840
- 4: "Seaweed",
1841
- 5: "Pearl culture"
1842
- };
1843
- var CATCBL_TABLE = {
1844
- 1: "Submarine power cable",
1845
- 2: "Submarine transmission cable",
1846
- 3: "Submarine telegraph cable",
1847
- 4: "Submarine telephone cable",
1848
- 5: "Mooring cable",
1849
- 6: "Ferry cable"
1850
- };
1851
- var CATPIP_TABLE = {
1852
- 1: "Pipeline",
1853
- 2: "Outfall pipe",
1854
- 3: "Intake pipe",
1855
- 4: "Sewer",
1856
- 5: "Bubbler system",
1857
- 6: "Supply pipe"
1858
- };
1859
- var TRAFIC_TABLE = {
1860
- 1: "Inbound",
1861
- 2: "Outbound",
1862
- 3: "One-way",
1863
- 4: "Two-way"
1864
- };
1865
- var QUASOU_TABLE = {
1866
- 1: "Depth known",
1867
- 2: "Depth unknown",
1868
- 3: "Doubtful sounding",
1869
- 4: "Unreliable sounding",
1870
- 6: "Least depth known",
1871
- 7: "Least depth unknown",
1872
- 9: "Not regularly maintained",
1873
- 10: "Maintained depth",
1874
- 11: "Not surveyed"
1875
- };
2130
+ var CATOBS_TABLE = s57NameTable("CATOBS");
2131
+ var CATWRK_TABLE = s57NameTable("CATWRK");
2132
+ var WATLEV_TABLE = s57NameTable("WATLEV");
2133
+ var CATREA_TABLE = s57NameTable("CATREA");
2134
+ var RESTRN_TABLE = s57NameTable("RESTRN");
2135
+ var CATHAF_TABLE = s57NameTable("CATHAF");
2136
+ var CATSCF_TABLE = s57NameTable("CATSCF");
2137
+ var CATCRN_TABLE = s57NameTable("CATCRN");
2138
+ var CATACH_TABLE = s57NameTable("CATACH");
2139
+ var CATDPG_TABLE = s57NameTable("CATDPG");
2140
+ var CATMFA_TABLE = s57NameTable("CATMFA");
2141
+ var CATCBL_TABLE = s57NameTable("CATCBL");
2142
+ var CATPIP_TABLE = s57NameTable("CATPIP");
2143
+ var TRAFIC_TABLE = s57NameTable("TRAFIC");
2144
+ var QUASOU_TABLE = s57NameTable("QUASOU");
1876
2145
  function decodeAreaFeatureProps(layerName, props) {
1877
2146
  const rawLayer = layerName.replace(/^enc-/, "").replace(/-(point|line|polygon|midpoint)$/, "");
1878
2147
  const parseCodeLocal = (val) => {
@@ -2335,6 +2604,15 @@ function decodeAreaFeatureProps(layerName, props) {
2335
2604
  if (st && STATUS_TABLE[st]) entries.push({ label: "Status", value: STATUS_TABLE[st] });
2336
2605
  return { type, title: title || type, properties: entries };
2337
2606
  }
2607
+ function catfogCodeFromName(lowercaseName) {
2608
+ if (!lowercaseName) return null;
2609
+ for (const entry of Object.values(CATFOG_CODES)) {
2610
+ const term = entry.name.toLowerCase();
2611
+ if (new RegExp(`\\b${term}\\b`).test(lowercaseName)) return entry.code;
2612
+ }
2613
+ if (/\bnauto\b/.test(lowercaseName)) return CATFOG_NAUTOPHONE ?? null;
2614
+ return null;
2615
+ }
2338
2616
  function parseCode(val) {
2339
2617
  if (val == null) return null;
2340
2618
  let s = String(val).trim();
@@ -2446,14 +2724,7 @@ function decodeNavAidProps(layerName, props, coords) {
2446
2724
  const sigper = props.SIGPER != null ? Number(props.SIGPER) : null;
2447
2725
  const group = parseGroup(props.SIGGRP);
2448
2726
  const nameForFog = String(props.OBJNAM ?? "").toLowerCase();
2449
- let catfogCode = null;
2450
- if (/\bwhistle\b/.test(nameForFog)) catfogCode = 6;
2451
- else if (/\bgong\b/.test(nameForFog)) catfogCode = 8;
2452
- else if (/\bbell\b/.test(nameForFog)) catfogCode = 5;
2453
- else if (/\bhorn\b/.test(nameForFog)) catfogCode = 9;
2454
- else if (/\bsiren\b/.test(nameForFog)) catfogCode = 3;
2455
- else if (/diaphone/.test(nameForFog)) catfogCode = 2;
2456
- else if (/nautophone|nauto/.test(nameForFog)) catfogCode = 4;
2727
+ let catfogCode = catfogCodeFromName(nameForFog);
2457
2728
  if (!catfogCode) catfogCode = parseCode(props.CATFOG);
2458
2729
  const fogSignal2 = catfogCode ? CATFOG_TABLE[catfogCode] ?? null : null;
2459
2730
  const fogSignalAbbr = catfogCode ? CATFOG_ABBR_TABLE[catfogCode] ?? null : null;
@@ -5607,6 +5878,31 @@ var S52_LOOKUP = {
5607
5878
  viewingGroup: 27080,
5608
5879
  scamin: 22e3
5609
5880
  },
5881
+ RADRFL: {
5882
+ objectClass: "RADRFL",
5883
+ name: "Radar Reflector",
5884
+ category: "Navigation Aids",
5885
+ displayCategory: "OTHER",
5886
+ int1Ref: "S6",
5887
+ style: { type: "symbol", paint: {}, layout: { "icon-size": 0.6, "icon-allow-overlap": true }, iconImage: "RADRFL03" },
5888
+ viewingGroup: 27080,
5889
+ scamin: 22e3
5890
+ },
5891
+ // Retroreflecting material fitted to buoys/beacons. 7,506 features across 616
5892
+ // NOAA cells (docs/validation/s52-occurrence-snapshot.json) rendered nothing
5893
+ // until this entry existed. RETRFL02 is the simplified variant — RETRFL01 is
5894
+ // the paper-chart glyph, per the reference manifest descriptions.
5895
+ // int1Ref intentionally omitted: no INT-1 citation for retroreflectors could
5896
+ // be verified against an in-repo source, and the field is optional.
5897
+ RETRFL: {
5898
+ objectClass: "RETRFL",
5899
+ name: "Retroreflector",
5900
+ category: "Navigation Aids",
5901
+ displayCategory: "OTHER",
5902
+ style: { type: "symbol", paint: {}, layout: { "icon-size": 0.6, "icon-allow-overlap": true }, iconImage: "RETRFL02" },
5903
+ viewingGroup: 27080,
5904
+ scamin: 22e3
5905
+ },
5610
5906
  NAVLNE: {
5611
5907
  objectClass: "NAVLNE",
5612
5908
  name: "Navigation Line",
@@ -21151,6 +21447,8 @@ var SYMBOL_MAP = {
21151
21447
  FOGSIG: "FOGSIG01",
21152
21448
  RTPBCN: "RTPBCN02",
21153
21449
  RDOSTA: "RTPBCN02",
21450
+ RADRFL: "RADRFL03",
21451
+ RETRFL: "RETRFL02",
21154
21452
  // Nav aids
21155
21453
  DAYMAR: "DAYTRI01",
21156
21454
  PILPNT: "PILPNT02",
@@ -21604,31 +21902,28 @@ function getLookupEntry(layerName) {
21604
21902
  return S52_LOOKUP[layerName] ?? null;
21605
21903
  }
21606
21904
 
21905
+ // src/s57/match-expression.ts
21906
+ var pairsCache = /* @__PURE__ */ new Map();
21907
+ function codeLabelPairs(acronym, kind) {
21908
+ const key = `${acronym}:${kind}`;
21909
+ let pairs = pairsCache.get(key);
21910
+ if (pairs === void 0) {
21911
+ const table = kind === "abbr" ? s57AbbrTable(acronym) : s57NameTable(acronym);
21912
+ const flat = [];
21913
+ for (const code of Object.keys(table).map(Number).sort((a, b) => a - b)) {
21914
+ flat.push(code, table[code]);
21915
+ }
21916
+ pairs = flat;
21917
+ pairsCache.set(key, pairs);
21918
+ }
21919
+ return pairs;
21920
+ }
21921
+ function s57MatchExpression(acronym, kind, input, fallback = "") {
21922
+ return ["match", input, ...codeLabelPairs(acronym, kind), fallback];
21923
+ }
21924
+
21607
21925
  // src/atlas/labels.ts
21608
- var LITCHR_ABBR = {
21609
- 1: "F",
21610
- 2: "Fl",
21611
- 3: "LFl",
21612
- 4: "Oc",
21613
- 5: "Iso",
21614
- 6: "S.Fl",
21615
- 7: "S.LFl",
21616
- 8: "Al.Oc",
21617
- 9: "Al.LFl",
21618
- 10: "Al.Fl",
21619
- 11: "Al.Gp",
21620
- 12: "Mo",
21621
- 13: "Q",
21622
- 14: "VQ",
21623
- 15: "UQ",
21624
- 16: "Al",
21625
- 17: "Al.F.Fl",
21626
- 25: "Q+LFl",
21627
- 26: "VQ+LFl",
21628
- 27: "UQ+LFl",
21629
- 28: "Al",
21630
- 29: "F.LFl"
21631
- };
21926
+ var LITCHR_ABBR = s57AbbrTable("LITCHR");
21632
21927
  var COLOUR_ABBR = {
21633
21928
  1: "W",
21634
21929
  3: "R",
@@ -22417,27 +22712,11 @@ function getLabelConfig(layerName, opts = {}) {
22417
22712
  }
22418
22713
  };
22419
22714
  case "FOGSIG": {
22420
- const catfogExpr = [
22421
- "match",
22422
- ["to-number", ["coalesce", ["get", "CATFOG"], 0], 0],
22423
- 2,
22424
- "DIA",
22425
- 3,
22426
- "SIREN",
22427
- 4,
22428
- "NAUTO",
22429
- 5,
22430
- "BELL",
22431
- 6,
22432
- "WHIS",
22433
- 7,
22434
- "REED",
22435
- 8,
22436
- "GONG",
22437
- 9,
22438
- "HORN",
22439
- ""
22440
- ];
22715
+ const catfogExpr = s57MatchExpression(
22716
+ "CATFOG",
22717
+ "abbr",
22718
+ ["to-number", ["coalesce", ["get", "CATFOG"], 0], 0]
22719
+ );
22441
22720
  return {
22442
22721
  type: "symbol",
22443
22722
  textField: catfogExpr,
@@ -25993,33 +26272,11 @@ function buildNavAidLabelExpression() {
25993
26272
  ];
25994
26273
  }
25995
26274
  function buildLightLabelExpression() {
25996
- const litchrExpr = [
25997
- "match",
25998
- ["coalesce", ["get", "LITCHR"], 0],
25999
- 1,
26000
- "F",
26001
- 2,
26002
- "Fl",
26003
- 3,
26004
- "LFl",
26005
- 4,
26006
- "Oc",
26007
- 5,
26008
- "Iso",
26009
- 6,
26010
- "S.Fl",
26011
- 7,
26012
- "S.LFl",
26013
- 12,
26014
- "Mo",
26015
- 13,
26016
- "Q",
26017
- 14,
26018
- "VQ",
26019
- 15,
26020
- "UQ",
26021
- ""
26022
- ];
26275
+ const litchrExpr = s57MatchExpression(
26276
+ "LITCHR",
26277
+ "abbr",
26278
+ ["coalesce", ["get", "LITCHR"], 0]
26279
+ );
26023
26280
  const colourExpr = colourCodeCase(
26024
26281
  [
26025
26282
  ["3", " R"],
@@ -27167,6 +27424,20 @@ var CHART_CASCADE_CODES = {
27167
27424
  Approach: ["1", "2", "3", "4"],
27168
27425
  Harbor: ["1", "2", "3", "4", "5", "6"]
27169
27426
  };
27427
+ var CHRT_STYLE_MODES = [
27428
+ "continuous",
27429
+ ...Object.keys(CHART_BAND_CODES).map(
27430
+ (band) => `chart:${band}`
27431
+ )
27432
+ ];
27433
+ function normalizeStyleMode(raw) {
27434
+ if (raw === null || raw === void 0 || raw === "") return "continuous";
27435
+ const lower = raw.toLowerCase();
27436
+ return CHRT_STYLE_MODES.find((mode) => mode.toLowerCase() === lower) ?? null;
27437
+ }
27438
+ function styleModeBand(mode) {
27439
+ return mode === "continuous" ? null : mode.slice("chart:".length);
27440
+ }
27170
27441
  function bandFilterExpression(codes) {
27171
27442
  const list = Array.isArray(codes) ? codes : [codes];
27172
27443
  if (list.length === 1) {
@@ -28185,6 +28456,14 @@ var Chrt = class {
28185
28456
  cells;
28186
28457
  /** Coverage data — list available chart sources */
28187
28458
  coverage;
28459
+ /**
28460
+ * CHRTweather — NOAA-backed marine weather: observed conditions, active
28461
+ * warnings, and the NWS zone forecast. U.S. waters only, and requires the
28462
+ * `weather:read` scope on your key — a chart key does not carry it.
28463
+ *
28464
+ * An empty result from any of these never means calm water.
28465
+ */
28466
+ weather;
28188
28467
  /**
28189
28468
  * CHRToffline — download MBTiles bundles for offline use.
28190
28469
  * Requires `deviceId` in config. Manifest-based budget enforcement
@@ -28216,6 +28495,7 @@ var Chrt = class {
28216
28495
  this.tiles = new TilesEndpoint(this.http, this.tileAuth, tileOpts);
28217
28496
  this.cells = new CellsEndpoint(this.http);
28218
28497
  this.coverage = new CoverageEndpoint(this.http);
28498
+ this.weather = new WeatherEndpoint(this.http);
28219
28499
  this.featuresEp = new FeaturesEndpoint(this.http);
28220
28500
  this.queryEp = new QueryEndpoint(this.http);
28221
28501
  this.offline = new OfflineEndpoint(this.http, config.deviceId, config.manifestPath);
@@ -28495,6 +28775,7 @@ export {
28495
28775
  CHRT_ICON_EXPRESSIONS,
28496
28776
  CHRT_ICON_PREFIX,
28497
28777
  CHRT_SDF_GLYPHS,
28778
+ CHRT_STYLE_MODES,
28498
28779
  Chrt,
28499
28780
  ChrtError,
28500
28781
  DEFAULT_CLICK_TOLERANCE,
@@ -28550,6 +28831,7 @@ export {
28550
28831
  TileAuth,
28551
28832
  TileTokenError,
28552
28833
  WATER_BODY_LAYER_GROUPS,
28834
+ WeatherEndpoint,
28553
28835
  applyChrtSymbolSet,
28554
28836
  applyColorTheme,
28555
28837
  applyCustomStyleSettings,
@@ -28624,6 +28906,7 @@ export {
28624
28906
  lightColor,
28625
28907
  lightFillExpression,
28626
28908
  lightsIconExpression,
28909
+ normalizeStyleMode,
28627
28910
  normalizeTheme,
28628
28911
  paginate,
28629
28912
  parseListCodes,
@@ -28644,6 +28927,7 @@ export {
28644
28927
  sanitizeCustomStyleConfig,
28645
28928
  scaleSizeValue,
28646
28929
  scaminToMinZoom,
28930
+ styleModeBand,
28647
28931
  withinBboxFilter,
28648
28932
  worldMinusBboxPolygon
28649
28933
  };