@airframes/acars-decoder 1.6.7 → 1.6.8

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.mjs CHANGED
@@ -171,6 +171,12 @@ var Label_5Z = class extends DecoderPlugin {
171
171
 
172
172
  // lib/utils/coordinate_utils.ts
173
173
  var CoordinateUtils = class {
174
+ /**
175
+ * Decode a string of coordinates into an object with latitude and longitude in millidegrees
176
+ * @param stringCoords - The string of coordinates to decode
177
+ *
178
+ * @returns An object with latitude and longitude properties
179
+ */
174
180
  static decodeStringCoordinates(stringCoords) {
175
181
  var results = {};
176
182
  const firstChar = stringCoords.substring(0, 1);
@@ -188,6 +194,33 @@ var CoordinateUtils = class {
188
194
  }
189
195
  return results;
190
196
  }
197
+ /**
198
+ * Decode a string of coordinates into an object with latitude and longitude in degrees and decimal minutes
199
+ * @param stringCoords - The string of coordinates to decode
200
+ *
201
+ * @returns An object with latitude and longitude properties
202
+ */
203
+ static decodeStringCoordinatesDecimalMinutes(stringCoords) {
204
+ var results = {};
205
+ const firstChar = stringCoords.substring(0, 1);
206
+ let middleChar = stringCoords.substring(6, 7);
207
+ let longitudeChars = stringCoords.substring(7, 13);
208
+ if (middleChar == " ") {
209
+ middleChar = stringCoords.substring(7, 8);
210
+ longitudeChars = stringCoords.substring(8, 14);
211
+ }
212
+ const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
213
+ const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
214
+ const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
215
+ const lonMin = Number(longitudeChars) % 1e3 / 10;
216
+ if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
217
+ results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
218
+ results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
219
+ } else {
220
+ return;
221
+ }
222
+ return results;
223
+ }
191
224
  static coordinateString(coords) {
192
225
  const latDir = coords.latitude > 0 ? "N" : "S";
193
226
  const lonDir = coords.longitude > 0 ? "E" : "W";
@@ -558,6 +591,96 @@ var Label_20_POS = class extends DecoderPlugin {
558
591
  }
559
592
  };
560
593
 
594
+ // lib/plugins/Label_21_POS.ts
595
+ var Label_21_POS = class extends DecoderPlugin {
596
+ name = "label-21-pos";
597
+ qualifiers() {
598
+ return {
599
+ labels: ["21"],
600
+ preambles: ["POS"]
601
+ };
602
+ }
603
+ decode(message, options = {}) {
604
+ const decodeResult = this.defaultResult();
605
+ decodeResult.decoder.name = this.name;
606
+ decodeResult.formatted.description = "Position Report";
607
+ decodeResult.message = message;
608
+ decodeResult.raw.preamble = message.text.substring(0, 3);
609
+ const content = message.text.substring(3);
610
+ console.log("Content: " + content);
611
+ const fields = content.split(",");
612
+ console.log("Field Count: " + fields.length);
613
+ if (fields.length == 9) {
614
+ processPosition(decodeResult, fields[0].trim());
615
+ processAlt(decodeResult, fields[3]);
616
+ processTemp(decodeResult, fields[6]);
617
+ processArrvApt(decodeResult, fields[8]);
618
+ decodeResult.raw.remaining = [
619
+ fields[1],
620
+ fields[2],
621
+ fields[4],
622
+ fields[5],
623
+ fields[7]
624
+ ].join(",");
625
+ decodeResult.decoded = true;
626
+ decodeResult.decoder.decodeLevel = "partial";
627
+ } else {
628
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
629
+ decodeResult.decoded = false;
630
+ decodeResult.decoder.decodeLevel = "none";
631
+ }
632
+ return decodeResult;
633
+ }
634
+ };
635
+ function processPosition(decodeResult, value) {
636
+ if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
637
+ return false;
638
+ }
639
+ const latDir = value[0] === "N" ? 1 : -1;
640
+ const lonDir = value[8] === "E" ? 1 : -1;
641
+ const position = {
642
+ latitude: latDir * Number(value.substring(1, 7)),
643
+ longitude: lonDir * Number(value.substring(9, 15))
644
+ };
645
+ if (position) {
646
+ decodeResult.raw.position = position;
647
+ decodeResult.formatted.items.push({
648
+ type: "aircraft_position",
649
+ code: "POS",
650
+ label: "Aircraft Position",
651
+ value: CoordinateUtils.coordinateString(position)
652
+ });
653
+ }
654
+ return !!position;
655
+ }
656
+ function processAlt(decodeResult, value) {
657
+ decodeResult.raw.altitude = Number(value);
658
+ decodeResult.formatted.items.push({
659
+ type: "altitude",
660
+ code: "ALT",
661
+ label: "Altitude",
662
+ value: `${decodeResult.raw.altitude} feet`
663
+ });
664
+ }
665
+ function processTemp(decodeResult, value) {
666
+ decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
667
+ decodeResult.formatted.items.push({
668
+ type: "outside_air_temperature",
669
+ code: "OATEMP",
670
+ label: "Outside Air Temperature (C)",
671
+ value: `${decodeResult.raw.outside_air_temperature}`
672
+ });
673
+ }
674
+ function processArrvApt(decodeResult, value) {
675
+ decodeResult.raw.arrival_icao = value;
676
+ decodeResult.formatted.items.push({
677
+ type: "destination",
678
+ code: "DST",
679
+ label: "Destination",
680
+ value: decodeResult.raw.arrival_icao
681
+ });
682
+ }
683
+
561
684
  // lib/plugins/Label_30_Slash_EA.ts
562
685
  var Label_30_Slash_EA = class extends DecoderPlugin {
563
686
  name = "label-30-slash-ea";
@@ -855,7 +978,7 @@ var Label_44_POS = class extends DecoderPlugin {
855
978
  console.log(`Label 44 Position Report: groups`);
856
979
  console.log(results.groups);
857
980
  }
858
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords);
981
+ decodeResult.raw.position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords);
859
982
  decodeResult.raw.flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? "0" : Number(results.groups.flight_level_or_ground);
860
983
  decodeResult.raw.departure_icao = results.groups.departure_icao;
861
984
  decodeResult.raw.arrival_icao = results.groups.arrival_icao;
@@ -870,9 +993,9 @@ var Label_44_POS = class extends DecoderPlugin {
870
993
  }
871
994
  if (decodeResult.raw.position) {
872
995
  decodeResult.formatted.items.push({
873
- type: "position",
996
+ type: "aircraft_position",
874
997
  code: "POS",
875
- label: "Position",
998
+ label: "Aircraft Position",
876
999
  value: CoordinateUtils.coordinateString(decodeResult.raw.position)
877
1000
  });
878
1001
  }
@@ -1180,6 +1303,112 @@ var Label_ColonComma = class extends DecoderPlugin {
1180
1303
  }
1181
1304
  };
1182
1305
 
1306
+ // lib/utils/result_formatter.ts
1307
+ var ResultFormatter = class {
1308
+ static altitude(decodeResult, value) {
1309
+ decodeResult.raw.altitude = value;
1310
+ decodeResult.formatted.items.push({
1311
+ type: "altitude",
1312
+ code: "ALT",
1313
+ label: "Altitude",
1314
+ value: `${decodeResult.raw.altitude} feet`
1315
+ });
1316
+ }
1317
+ static flightNumber(decodeResult, value) {
1318
+ decodeResult.raw.flight_number = value;
1319
+ }
1320
+ static departureAirport(decodeResult, value) {
1321
+ decodeResult.raw.departure_icao = value;
1322
+ decodeResult.formatted.items.push({
1323
+ type: "origin",
1324
+ code: "ORG",
1325
+ label: "Origin",
1326
+ value: decodeResult.raw.departure_icao
1327
+ });
1328
+ }
1329
+ static departureRunway(decodeResult, value) {
1330
+ decodeResult.raw.departure_runway = value;
1331
+ decodeResult.formatted.items.push({
1332
+ type: "runway",
1333
+ code: "DEPRWY",
1334
+ label: "Departure Runway",
1335
+ value: decodeResult.raw.departure_runway
1336
+ });
1337
+ }
1338
+ static arrivalAirport(decodeResult, value) {
1339
+ decodeResult.raw.arrival_icao = value;
1340
+ decodeResult.formatted.items.push({
1341
+ type: "destination",
1342
+ code: "DST",
1343
+ label: "Destination",
1344
+ value: decodeResult.raw.arrival_icao
1345
+ });
1346
+ }
1347
+ static eta(decodeResult, value) {
1348
+ decodeResult.formatted.items.push({
1349
+ type: "eta",
1350
+ code: "ETA",
1351
+ label: "Estimated Time of Arrival",
1352
+ value: value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6)
1353
+ });
1354
+ }
1355
+ static arrivalRunway(decodeResult, value) {
1356
+ decodeResult.raw.arrival_runway = value;
1357
+ decodeResult.formatted.items.push({
1358
+ type: "runway",
1359
+ label: "Arrival Runway",
1360
+ value: decodeResult.raw.arrival_runway
1361
+ });
1362
+ }
1363
+ static currentFuel(decodeResult, value) {
1364
+ decodeResult.raw.fuel_on_board = value;
1365
+ decodeResult.formatted.items.push({
1366
+ type: "fuel_on_board",
1367
+ code: "FOB",
1368
+ label: "Fuel On Board",
1369
+ value: decodeResult.raw.fuel_on_board.toString()
1370
+ });
1371
+ }
1372
+ static remainingFuel(decodeResult, value) {
1373
+ decodeResult.raw.fuel_remaining = value;
1374
+ decodeResult.formatted.items.push({
1375
+ type: "fuel_remaining",
1376
+ label: "Fuel Remaining",
1377
+ value: decodeResult.raw.fuel_remaining.toString()
1378
+ });
1379
+ }
1380
+ static checksum(decodeResult, value) {
1381
+ decodeResult.raw.checksum = Number("0x" + value);
1382
+ decodeResult.formatted.items.push({
1383
+ type: "message_checksum",
1384
+ code: "CHECKSUM",
1385
+ label: "Message Checksum",
1386
+ value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
1387
+ });
1388
+ }
1389
+ static groundspeed(decodeResult, value) {
1390
+ decodeResult.raw.groundspeed = value;
1391
+ decodeResult.formatted.items.push({
1392
+ type: "aircraft_groundspeed",
1393
+ code: "GSPD",
1394
+ label: "Aircraft Groundspeed",
1395
+ value: `${decodeResult.raw.groundspeed}`
1396
+ });
1397
+ }
1398
+ static temperature(decodeResult, value) {
1399
+ decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
1400
+ decodeResult.formatted.items.push({
1401
+ type: "outside_air_temperature",
1402
+ code: "OATEMP",
1403
+ label: "Outside Air Temperature (C)",
1404
+ value: `${decodeResult.raw.outside_air_temperature}`
1405
+ });
1406
+ }
1407
+ static unknown(decodeResult, value) {
1408
+ decodeResult.remaining.text += "," + value;
1409
+ }
1410
+ };
1411
+
1183
1412
  // lib/utils/route_utils.ts
1184
1413
  var RouteUtils = class _RouteUtils {
1185
1414
  static routeToString(route) {
@@ -1220,13 +1449,13 @@ var RouteUtils = class _RouteUtils {
1220
1449
  }
1221
1450
  const waypoint = leg.split(",");
1222
1451
  if (waypoint.length == 2) {
1223
- const position = CoordinateUtils.decodeStringCoordinates(waypoint[1]);
1452
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
1224
1453
  if (position) {
1225
1454
  return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
1226
1455
  }
1227
1456
  }
1228
1457
  if (leg.length == 13 || leg.length == 14) {
1229
- const position = CoordinateUtils.decodeStringCoordinates(leg);
1458
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
1230
1459
  const name = waypoint.length == 2 ? waypoint[0] : "";
1231
1460
  if (position) {
1232
1461
  return { name, latitude: position.latitude, longitude: position.longitude };
@@ -1305,13 +1534,126 @@ var FlightPlanUtils = class _FlightPlanUtils {
1305
1534
  }
1306
1535
  static parseHeader(decodeResult, header) {
1307
1536
  let allKnownFields = true;
1308
- const fields = header.split("/");
1537
+ if (header.startsWith("RF")) {
1538
+ decodeResult.formatted.items.push({
1539
+ type: "status",
1540
+ code: "ROUTE_STATUS",
1541
+ label: "Route Status",
1542
+ value: "Route Filed"
1543
+ });
1544
+ decodeResult.raw.route_status = "RF";
1545
+ if (header.length > 2) {
1546
+ addRoute(decodeResult, header.substring(2));
1547
+ }
1548
+ } else if (header.startsWith("RP")) {
1549
+ decodeResult.raw.route_status = "RP";
1550
+ decodeResult.formatted.items.push({
1551
+ type: "status",
1552
+ code: "ROUTE_STATUS",
1553
+ label: "Route Status",
1554
+ value: "Route Planned"
1555
+ });
1556
+ decodeResult.raw.route_status = header;
1557
+ } else if (header.startsWith("RI")) {
1558
+ decodeResult.raw.route_status = "RI";
1559
+ decodeResult.formatted.items.push({
1560
+ type: "status",
1561
+ code: "ROUTE_STATUS",
1562
+ label: "Route Status",
1563
+ value: "Route Inactive"
1564
+ });
1565
+ } else {
1566
+ decodeResult.remaining.text += header;
1567
+ allKnownFields = false;
1568
+ }
1569
+ return allKnownFields;
1570
+ }
1571
+ };
1572
+ function addArrivalAirport(decodeResult, value) {
1573
+ ResultFormatter.arrivalAirport(decodeResult, value);
1574
+ }
1575
+ function addDepartureAirport(decodeResult, value) {
1576
+ ResultFormatter.departureAirport(decodeResult, value);
1577
+ }
1578
+ function addRunway(decodeResult, value) {
1579
+ if (value.length === 8) {
1580
+ ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
1581
+ }
1582
+ ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
1583
+ }
1584
+ function addRoute(decodeResult, value) {
1585
+ const route = value.split(".");
1586
+ decodeResult.raw.route = { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) };
1587
+ decodeResult.formatted.items.push({
1588
+ type: "aircraft_route",
1589
+ code: "ROUTE",
1590
+ label: "Aircraft Route",
1591
+ value: RouteUtils.routeToString(decodeResult.raw.route)
1592
+ });
1593
+ }
1594
+ function addProcedure(decodeResult, value, type) {
1595
+ if (decodeResult.raw.procedures === void 0) {
1596
+ decodeResult.raw.procedures = [];
1597
+ }
1598
+ const data = value.split(".");
1599
+ let waypoints;
1600
+ if (data.length > 1) {
1601
+ waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1602
+ }
1603
+ const route = { name: data[0], waypoints };
1604
+ decodeResult.raw.procedures.push({ type, route });
1605
+ const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
1606
+ let procedureValue = route.name;
1607
+ decodeResult.formatted.items.push({
1608
+ type: `procedure`,
1609
+ code: "proc",
1610
+ label: `${procedureName} Procedure`,
1611
+ value: RouteUtils.routeToString(route)
1612
+ });
1613
+ }
1614
+ function addCompanyRoute(decodeResult, value) {
1615
+ const segments = value.split(".");
1616
+ const parens_idx = segments[0].indexOf("(");
1617
+ let name;
1618
+ let runway;
1619
+ if (parens_idx === -1) {
1620
+ name = segments[0];
1621
+ } else {
1622
+ name = segments[0].slice(0, parens_idx);
1623
+ runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
1624
+ }
1625
+ let waypoints;
1626
+ if (segments.length > 1) {
1627
+ waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1628
+ }
1629
+ decodeResult.raw.company_route = {
1630
+ name,
1631
+ runway,
1632
+ waypoints
1633
+ };
1634
+ decodeResult.formatted.items.push({
1635
+ type: "company_route",
1636
+ code: "CR",
1637
+ label: "Company Route",
1638
+ value: RouteUtils.routeToString(decodeResult.raw.company_route)
1639
+ });
1640
+ }
1641
+
1642
+ // lib/utils/h1_helper.ts
1643
+ var H1Helper = class {
1644
+ static decodeH1Message(decodeResult, message) {
1645
+ let allKnownFields = true;
1646
+ const checksum = message.slice(-4);
1647
+ const data = message.slice(0, message.length - 4);
1648
+ const fields = data.split("/");
1309
1649
  allKnownFields = allKnownFields && parseMessageType(decodeResult, fields[0]);
1310
1650
  for (let i = 1; i < fields.length; ++i) {
1311
1651
  if (fields[i].startsWith("FN")) {
1312
1652
  decodeResult.raw.flight_number = fields[i].substring(2);
1313
1653
  } else if (fields[i].startsWith("SN")) {
1314
1654
  decodeResult.raw.serial_number = fields[i].substring(2);
1655
+ } else if (fields[i].startsWith("DC")) {
1656
+ processDC(decodeResult, fields[i].substring(2).split(","));
1315
1657
  } else if (fields[i].startsWith("TS")) {
1316
1658
  const ts = fields[i].substring(2).split(",");
1317
1659
  let time = DateTimeUtils.convertDateTimeToEpoch(ts[0], ts[1]);
@@ -1319,69 +1661,101 @@ var FlightPlanUtils = class _FlightPlanUtils {
1319
1661
  const date = ts[1].substring(2, 4) + ts[1].substring(0, 2) + ts[1].substring(4, 6);
1320
1662
  time = DateTimeUtils.convertDateTimeToEpoch(ts[0], date);
1321
1663
  }
1664
+ decodeResult.raw.message_date = ts[1];
1322
1665
  decodeResult.raw.message_timestamp = time;
1323
1666
  } else if (fields[i].startsWith("PS")) {
1324
- const pos = fields[i].substring(2);
1325
- allKnownFields == allKnownFields && processPosition(decodeResult, pos);
1667
+ const pos = processPS(decodeResult, fields[i].substring(2).split(","));
1668
+ allKnownFields == allKnownFields && pos;
1326
1669
  } else if (fields[i].startsWith("DT")) {
1327
- const icao = fields[i].substring(2);
1328
- decodeResult.raw.arrival_icao = icao;
1329
- decodeResult.formatted.items.push({
1330
- type: "destination",
1331
- code: "DST",
1332
- label: "Destination",
1333
- value: decodeResult.raw.arrival_icao
1334
- });
1670
+ const data2 = fields[i].substring(2).split(",");
1671
+ const dt = processDT(decodeResult, data2);
1672
+ allKnownFields = allKnownFields && dt;
1335
1673
  } else if (fields[i].startsWith("ID")) {
1336
- const tail = fields[i].substring(2);
1337
- decodeResult.raw.tail = tail;
1674
+ const data2 = fields[i].substring(2).split(",");
1675
+ decodeResult.raw.tail = data2[0];
1338
1676
  decodeResult.formatted.items.push({
1339
1677
  type: "tail",
1678
+ code: "TAIL",
1340
1679
  label: "Tail",
1341
1680
  value: decodeResult.raw.tail
1342
1681
  });
1343
- } else if (fields[i].startsWith("RF")) {
1344
- decodeResult.formatted.items.push({
1345
- type: "status",
1346
- code: "ROUTE_STATUS",
1347
- label: "Route Status",
1348
- value: "Route Filed"
1349
- });
1350
- decodeResult.raw.route_status = "RF";
1351
- if (fields[i].length > 2) {
1352
- addRoute(decodeResult, fields[i].substring(2));
1682
+ if (data2.length > 1) {
1683
+ decodeResult.raw.flight_number = data2[1];
1353
1684
  }
1354
- } else if (fields[i] == "RP") {
1355
- decodeResult.raw.route_status = "RP";
1356
- decodeResult.formatted.items.push({
1357
- type: "status",
1358
- code: "ROUTE_STATUS",
1359
- label: "Route Status",
1360
- value: "Route Planned"
1361
- });
1362
- decodeResult.raw.route_status = fields[i];
1363
- } else if (fields[i] == "RI") {
1364
- decodeResult.raw.route_status = "RI";
1365
- decodeResult.formatted.items.push({
1366
- type: "status",
1367
- code: "ROUTE_STATUS",
1368
- label: "Route Status",
1369
- value: "Route Inactive"
1370
- });
1685
+ if (data2.length > 2) {
1686
+ allKnownFields = false;
1687
+ decodeResult.remaining.text += "," + data2.slice(2).join(",");
1688
+ }
1689
+ } else if (fields[i].startsWith("LR")) {
1690
+ const data2 = fields[i].substring(2).split(",");
1691
+ const lr = processLR(decodeResult, data2);
1692
+ allKnownFields = allKnownFields && lr;
1693
+ } else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
1694
+ const fp = FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
1695
+ allKnownFields = allKnownFields && fp;
1696
+ } else if (fields[i].startsWith("PR")) {
1697
+ allKnownFields = false;
1698
+ decodeResult.remaining.text += "/" + fields[i];
1699
+ } else if (fields[i].startsWith("PS")) {
1700
+ allKnownFields = false;
1701
+ decodeResult.remaining.text += fields[i];
1371
1702
  } else {
1372
1703
  decodeResult.remaining.text += "/" + fields[i];
1373
1704
  allKnownFields = false;
1374
1705
  }
1375
1706
  }
1707
+ if (decodeResult.formatted.items.length > 0) {
1708
+ ResultFormatter.checksum(decodeResult, checksum);
1709
+ }
1376
1710
  return allKnownFields;
1377
1711
  }
1378
1712
  };
1713
+ function processDT(decodeResult, data) {
1714
+ let allKnownFields = true;
1715
+ if (!decodeResult.raw.arrival_icao) {
1716
+ ResultFormatter.arrivalAirport(decodeResult, data[0]);
1717
+ } else if (decodeResult.raw.arrival_icao != data[0]) {
1718
+ decodeResult.remaining.text += "/" + data;
1719
+ }
1720
+ if (data.length > 1) {
1721
+ ResultFormatter.arrivalRunway(decodeResult, data[1]);
1722
+ }
1723
+ if (data.length > 2) {
1724
+ ResultFormatter.currentFuel(decodeResult, Number(data[2]));
1725
+ }
1726
+ if (data.length > 3) {
1727
+ ResultFormatter.eta(decodeResult, data[3]);
1728
+ }
1729
+ if (data.length > 4) {
1730
+ ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
1731
+ }
1732
+ if (data.length > 5) {
1733
+ allKnownFields = false;
1734
+ decodeResult.remaining.text += "," + data.slice(5).join(",");
1735
+ }
1736
+ return allKnownFields;
1737
+ }
1738
+ function processLR(decodeResult, data) {
1739
+ let allKnownFields = true;
1740
+ if (data.length === 19) {
1741
+ ResultFormatter.unknown(decodeResult, data[1]);
1742
+ ResultFormatter.flightNumber(decodeResult, data[2]);
1743
+ ResultFormatter.departureAirport(decodeResult, data[3]);
1744
+ ResultFormatter.arrivalAirport(decodeResult, data[4]);
1745
+ ResultFormatter.arrivalRunway(decodeResult, data[5]);
1746
+ ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
1747
+ allKnownFields = false;
1748
+ } else {
1749
+ allKnownFields = false;
1750
+ }
1751
+ return allKnownFields;
1752
+ }
1379
1753
  function parseMessageType(decodeResult, messageType) {
1380
1754
  let decoded = true;
1381
1755
  const parts = messageType.split("#");
1382
1756
  if (parts.length == 1) {
1383
1757
  if (parts[0].startsWith("POS") && parts[0].length !== 3 && !parts[0].startsWith("POS/")) {
1384
- decoded = processPosition(decodeResult, parts[0].substring(3));
1758
+ decoded = processPosition2(decodeResult, parts[0].substring(3).split(","));
1385
1759
  }
1386
1760
  return decoded;
1387
1761
  } else if (parts.length == 2) {
@@ -1391,7 +1765,7 @@ function parseMessageType(decodeResult, messageType) {
1391
1765
  decodeResult.remaining.text += "#" + parts[1].substring(0, 3);
1392
1766
  }
1393
1767
  if (parts[1].substring(3, 6) === "POS" && parts[1].length !== 6 && parts[1].substring(3, 7) !== "POS/") {
1394
- decoded = processPosition(decodeResult, parts[1].substring(6));
1768
+ decoded = processPosition2(decodeResult, parts[1].substring(6).split(","));
1395
1769
  }
1396
1770
  decodeResult.raw.message_type = messageType;
1397
1771
  return decoded;
@@ -1399,8 +1773,21 @@ function parseMessageType(decodeResult, messageType) {
1399
1773
  decodeResult.remaining.text += messageType;
1400
1774
  return false;
1401
1775
  }
1402
- function processPosition(decodeResult, value) {
1403
- const position = CoordinateUtils.decodeStringCoordinates(value);
1776
+ function processDC(decodeResult, data) {
1777
+ decodeResult.raw.message_date = data[0];
1778
+ if (data.length === 1) {
1779
+ } else if (data.length === 2) {
1780
+ const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
1781
+ const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
1782
+ decodeResult.raw.message_timestamp = time;
1783
+ } else {
1784
+ return false;
1785
+ }
1786
+ return true;
1787
+ }
1788
+ function processPS(decodeResult, data) {
1789
+ let allKnownFields = true;
1790
+ const position = CoordinateUtils.decodeStringCoordinates(data[0]);
1404
1791
  if (position) {
1405
1792
  decodeResult.raw.position = position;
1406
1793
  decodeResult.formatted.items.push({
@@ -1409,46 +1796,76 @@ function processPosition(decodeResult, value) {
1409
1796
  label: "Aircraft Position",
1410
1797
  value: CoordinateUtils.coordinateString(position)
1411
1798
  });
1412
- }
1413
- return !!position;
1414
- }
1415
- function addArrivalAirport(decodeResult, value) {
1416
- decodeResult.raw.arrival_icao = value;
1417
- decodeResult.formatted.items.push({
1418
- type: "destination",
1419
- code: "DST",
1420
- label: "Destination",
1421
- value: decodeResult.raw.arrival_icao
1422
- });
1423
- }
1424
- function addDepartureAirport(decodeResult, value) {
1425
- decodeResult.raw.departure_icao = value;
1426
- decodeResult.formatted.items.push({
1427
- type: "origin",
1428
- code: "ORG",
1429
- label: "Origin",
1430
- value: decodeResult.raw.departure_icao
1431
- });
1799
+ } else {
1800
+ allKnownFields = false;
1801
+ }
1802
+ console.log("PS data.length: ", data.length);
1803
+ console.log("PS data: ", data);
1804
+ if (data.length === 9) {
1805
+ processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
1806
+ ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
1807
+ ResultFormatter.temperature(decodeResult, data[6]);
1808
+ ResultFormatter.unknown(decodeResult, data[7]);
1809
+ ResultFormatter.unknown(decodeResult, data[8]);
1810
+ }
1811
+ if (data.length === 14) {
1812
+ ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
1813
+ processRoute(decodeResult, data[4], data[2], data[6], data[5], void 0);
1814
+ ResultFormatter.temperature(decodeResult, data[7]);
1815
+ ResultFormatter.groundspeed(decodeResult, Number(data[10]));
1816
+ ResultFormatter.unknown(decodeResult, data[1]);
1817
+ ResultFormatter.unknown(decodeResult, data[8]);
1818
+ ResultFormatter.unknown(decodeResult, data[9]);
1819
+ ResultFormatter.unknown(decodeResult, data.slice(11).join(","));
1820
+ }
1821
+ allKnownFields = false;
1822
+ return allKnownFields;
1432
1823
  }
1433
- function addRunway(decodeResult, value) {
1434
- if (value.length === 8) {
1435
- decodeResult.raw.arrival_runway = value.substring(4, 7);
1824
+ function processPosition2(decodeResult, data) {
1825
+ let allKnownFields = true;
1826
+ const position = CoordinateUtils.decodeStringCoordinates(data[0]);
1827
+ if (position) {
1828
+ decodeResult.raw.position = position;
1436
1829
  decodeResult.formatted.items.push({
1437
- type: "runway",
1438
- label: "Arrival Runway",
1439
- value: decodeResult.raw.arrival_runway
1830
+ type: "aircraft_position",
1831
+ code: "POS",
1832
+ label: "Aircraft Position",
1833
+ value: CoordinateUtils.coordinateString(position)
1440
1834
  });
1441
- }
1442
- decodeResult.raw.departure_runway = value.substring(0, 3);
1443
- decodeResult.formatted.items.push({
1444
- type: "runway",
1445
- label: "Departure Runway",
1446
- value: decodeResult.raw.departure_runway
1447
- });
1835
+ } else {
1836
+ allKnownFields = false;
1837
+ }
1838
+ console.log("data.length: ", data.length);
1839
+ console.log("data: ", data);
1840
+ if (data.length >= 10) {
1841
+ ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
1842
+ processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
1843
+ ResultFormatter.temperature(decodeResult, data[7]);
1844
+ ResultFormatter.unknown(decodeResult, data[8]);
1845
+ ResultFormatter.unknown(decodeResult, data[9]);
1846
+ }
1847
+ if (data.length >= 14) {
1848
+ ResultFormatter.groundspeed(decodeResult, Number(data[10]));
1849
+ ResultFormatter.unknown(decodeResult, data[11]);
1850
+ ResultFormatter.unknown(decodeResult, data[12]);
1851
+ ResultFormatter.unknown(decodeResult, data[13]);
1852
+ }
1853
+ allKnownFields = false;
1854
+ return allKnownFields;
1448
1855
  }
1449
- function addRoute(decodeResult, value) {
1450
- const route = value.split(".");
1451
- decodeResult.raw.route = { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) };
1856
+ function processRoute(decodeResult, last, time, next, eta, then, date) {
1857
+ const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
1858
+ const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
1859
+ const timeFormat = date ? "epoch" : "tod";
1860
+ const lastWaypoint = RouteUtils.getWaypoint(last);
1861
+ lastWaypoint.time = lastTime;
1862
+ lastWaypoint.timeFormat = timeFormat;
1863
+ const nextWaypoint = RouteUtils.getWaypoint(next);
1864
+ nextWaypoint.time = nextTime;
1865
+ nextWaypoint.timeFormat = timeFormat;
1866
+ const thenWaypoint = RouteUtils.getWaypoint(then || "?");
1867
+ const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
1868
+ decodeResult.raw.route = { waypoints };
1452
1869
  decodeResult.formatted.items.push({
1453
1870
  type: "aircraft_route",
1454
1871
  code: "ROUTE",
@@ -1456,53 +1873,6 @@ function addRoute(decodeResult, value) {
1456
1873
  value: RouteUtils.routeToString(decodeResult.raw.route)
1457
1874
  });
1458
1875
  }
1459
- function addProcedure(decodeResult, value, type) {
1460
- if (decodeResult.raw.procedures === void 0) {
1461
- decodeResult.raw.procedures = [];
1462
- }
1463
- const data = value.split(".");
1464
- let waypoints;
1465
- if (data.length > 1) {
1466
- waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1467
- }
1468
- const route = { name: data[0], waypoints };
1469
- decodeResult.raw.procedures.push({ type, route });
1470
- const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
1471
- let procedureValue = route.name;
1472
- decodeResult.formatted.items.push({
1473
- type: `procedure`,
1474
- code: "proc",
1475
- label: `${procedureName} Procedure`,
1476
- value: RouteUtils.routeToString(route)
1477
- });
1478
- }
1479
- function addCompanyRoute(decodeResult, value) {
1480
- const segments = value.split(".");
1481
- const parens_idx = segments[0].indexOf("(");
1482
- let name;
1483
- let runway;
1484
- if (parens_idx === -1) {
1485
- name = segments[0];
1486
- } else {
1487
- name = segments[0].slice(0, parens_idx);
1488
- runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
1489
- }
1490
- let waypoints;
1491
- if (segments.length > 1) {
1492
- waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1493
- }
1494
- decodeResult.raw.company_route = {
1495
- name,
1496
- runway,
1497
- waypoints
1498
- };
1499
- decodeResult.formatted.items.push({
1500
- type: "company_route",
1501
- code: "CR",
1502
- label: "Company Route",
1503
- value: RouteUtils.routeToString(decodeResult.raw.company_route)
1504
- });
1505
- }
1506
1876
 
1507
1877
  // lib/plugins/Label_H1_FPN.ts
1508
1878
  var Label_H1_FPN = class extends DecoderPlugin {
@@ -1518,15 +1888,12 @@ var Label_H1_FPN = class extends DecoderPlugin {
1518
1888
  decodeResult.decoder.name = this.name;
1519
1889
  decodeResult.formatted.description = "Flight Plan";
1520
1890
  decodeResult.message = message;
1891
+ decodeResult.remaining.text = "";
1521
1892
  const msg = message.text.replace(/\n|\r/g, "");
1522
- const checksum = msg.slice(-4);
1523
- const data = msg.slice(0, msg.length - 4).split(":");
1524
- if (data.length > 1) {
1525
- const fulllyDecoded = FlightPlanUtils.processFlightPlan(decodeResult, data);
1526
- addChecksum(decodeResult, checksum);
1527
- decodeResult.decoded = true;
1528
- decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
1529
- } else {
1893
+ const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, msg);
1894
+ decodeResult.decoded = true;
1895
+ decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
1896
+ if (decodeResult.formatted.items.length === 0) {
1530
1897
  if (options?.debug) {
1531
1898
  console.log(`Decoder: Unknown H1 message: ${message.text}`);
1532
1899
  }
@@ -1537,15 +1904,6 @@ var Label_H1_FPN = class extends DecoderPlugin {
1537
1904
  return decodeResult;
1538
1905
  }
1539
1906
  };
1540
- function addChecksum(decodeResult, value) {
1541
- decodeResult.raw.checksum = Number("0x" + value);
1542
- decodeResult.formatted.items.push({
1543
- type: "message_checksum",
1544
- code: "CHECKSUM",
1545
- label: "Message Checksum",
1546
- value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
1547
- });
1548
- }
1549
1907
 
1550
1908
  // lib/plugins/Label_H1_OHMA.ts
1551
1909
  import * as zlib from "minizlib";
@@ -1571,13 +1929,18 @@ var Label_H1_OHMA = class extends DecoderPlugin {
1571
1929
  decompress.flush(zlib.constants.Z_SYNC_FLUSH);
1572
1930
  const result = decompress.read();
1573
1931
  const jsonText = result.toString();
1574
- const json = JSON.parse(jsonText);
1575
1932
  let formattedMsg;
1576
- if (json.message.startsWith("{")) {
1577
- const ohmaMsg = JSON.parse(json.message);
1933
+ let jsonMessage;
1934
+ try {
1935
+ jsonMessage = JSON.parse(jsonText).message;
1936
+ } catch {
1937
+ jsonMessage = jsonText;
1938
+ }
1939
+ try {
1940
+ const ohmaMsg = JSON.parse(jsonMessage);
1578
1941
  formattedMsg = JSON.stringify(ohmaMsg, null, 2);
1579
- } else {
1580
- formattedMsg = json.message;
1942
+ } catch {
1943
+ formattedMsg = jsonMessage;
1581
1944
  }
1582
1945
  decodeResult.decoded = true;
1583
1946
  decodeResult.decoder.decodeLevel = "full";
@@ -1616,225 +1979,20 @@ var Label_H1_POS = class extends DecoderPlugin {
1616
1979
  decodeResult.formatted.description = "Position Report";
1617
1980
  decodeResult.message = message;
1618
1981
  decodeResult.remaining.text = "";
1619
- const checksum = message.text.slice(-4);
1620
- const header = findHeader(message.text.slice(0, -4));
1621
- const decoded = FlightPlanUtils.processFlightPlan(decodeResult, header.split(":"));
1622
- const parts = message.text.replace(header, "").slice(0, -4).split(",");
1623
- if (parts.length == 1) {
1624
- if (decoded) {
1625
- processChecksum(decodeResult, checksum);
1626
- decodeResult.decoded = true;
1627
- decodeResult.decoder.decodeLevel = "full";
1628
- } else if (decodeResult.remaining.text.length > 0) {
1629
- processChecksum(decodeResult, checksum);
1630
- decodeResult.decoded = true;
1631
- decodeResult.decoder.decodeLevel = "partial";
1632
- } else {
1633
- decodeResult.decoded = false;
1634
- decodeResult.decoder.decodeLevel = "none";
1635
- }
1636
- } else if (parts.length === 10) {
1637
- processAlt(decodeResult, parts[3]);
1638
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
1639
- processTemp(decodeResult, parts[7]);
1640
- processUnknown(decodeResult, parts[8]);
1641
- processUnknown(decodeResult, parts[9]);
1642
- processChecksum(decodeResult, checksum);
1643
- decodeResult.decoded = true;
1644
- decodeResult.decoder.decodeLevel = "partial";
1645
- } else if (parts.length === 11) {
1646
- processAlt(decodeResult, parts[3]);
1647
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], parts[10]);
1648
- processTemp(decodeResult, parts[7]);
1649
- processUnknown(decodeResult, parts[8]);
1650
- processUnknown(decodeResult, parts[9]);
1651
- processChecksum(decodeResult, checksum);
1652
- decodeResult.decoded = true;
1653
- decodeResult.decoder.decodeLevel = "partial";
1654
- } else if (parts.length === 12) {
1655
- const date = parts[11].substring(2, 4) + parts[11].substring(0, 2) + parts[11].substring(4, 6);
1656
- processUnknown(decodeResult, parts[3]);
1657
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6], date);
1658
- processTemp(decodeResult, parts[7]);
1659
- processUnknown(decodeResult, parts[8]);
1660
- processUnknown(decodeResult, parts[9]);
1661
- processUnknown(decodeResult, parts[10]);
1662
- processChecksum(decodeResult, checksum);
1663
- decodeResult.decoded = true;
1664
- decodeResult.decoder.decodeLevel = "partial";
1665
- } else if (parts.length === 14) {
1666
- processAlt(decodeResult, parts[3]);
1667
- processRoute(decodeResult, parts[1], parts[2], parts[4], parts[5], parts[6]);
1668
- processTemp(decodeResult, parts[7]);
1669
- processUnknown(decodeResult, parts[8]);
1670
- processUnknown(decodeResult, parts[9]);
1671
- processGndspd(decodeResult, parts[10]);
1672
- processUnknown(decodeResult, parts[11]);
1673
- processUnknown(decodeResult, parts[12]);
1674
- processUnknown(decodeResult, parts[13]);
1675
- processChecksum(decodeResult, checksum);
1676
- decodeResult.decoded = true;
1677
- decodeResult.decoder.decodeLevel = "partial";
1678
- } else if (parts.length === 15) {
1679
- decodeResult.raw.flight_number = parts[1];
1680
- let date = void 0;
1681
- if (parts[2].startsWith("/DC")) {
1682
- date = parts[2].substring(3);
1683
- } else {
1684
- processUnknown(decodeResult, parts[2]);
1685
- }
1686
- processUnknown(decodeResult, parts[3]);
1687
- const fields = parts[4].split("/");
1688
- for (let i = 0; i < fields.length; ++i) {
1689
- const field = fields[i];
1690
- if (field.startsWith("PS")) {
1691
- processPosition2(decodeResult, field.substring(2));
1692
- } else {
1693
- if (i === 0) {
1694
- processUnknown(decodeResult, field);
1695
- } else {
1696
- processUnknown(decodeResult, "/" + field);
1697
- }
1698
- }
1699
- }
1700
- processRoute(decodeResult, parts[7], parts[5], parts[9], parts[8], void 0, date);
1701
- processAlt(decodeResult, parts[6]);
1702
- processTemp(decodeResult, parts[10]);
1703
- processUnknown(decodeResult, parts[11]);
1704
- processUnknown(decodeResult, parts[12]);
1705
- processUnknown(decodeResult, parts[13]);
1706
- processUnknown(decodeResult, parts[14]);
1707
- processChecksum(decodeResult, checksum);
1708
- decodeResult.decoded = true;
1709
- decodeResult.decoder.decodeLevel = "partial";
1710
- } else if (parts.length === 21) {
1711
- processRunway(decodeResult, parts[1]);
1712
- processUnknown(decodeResult, parts.slice(2, 11).join(","));
1713
- processTemp(decodeResult, parts[11]);
1714
- processUnknown(decodeResult, parts.slice(12, 20).join(","));
1715
- FlightPlanUtils.processFlightPlan(decodeResult, parts[20].split(":"));
1716
- processChecksum(decodeResult, checksum);
1717
- decodeResult.decoded = true;
1718
- decodeResult.decoder.decodeLevel = "partial";
1719
- } else if (parts.length === 32) {
1720
- processRunway(decodeResult, parts[1]);
1721
- const time = parts[2];
1722
- processUnknown(decodeResult, parts[3]);
1723
- const past = parts[4];
1724
- processUnknown(decodeResult, parts[5]);
1725
- const eta = parts[6];
1726
- const next = parts[7];
1727
- processUnknown(decodeResult, parts.slice(8, 14).join(","));
1728
- processUnknown(decodeResult, parts[16]);
1729
- processUnknown(decodeResult, parts[17]);
1730
- processUnknown(decodeResult, parts[18]);
1731
- processGndspd(decodeResult, parts[19]);
1732
- processUnknown(decodeResult, parts[20]);
1733
- processUnknown(decodeResult, parts[21]);
1734
- processAlt(decodeResult, parts[22]);
1735
- processUnknown(decodeResult, parts.slice(23, 31).join(","));
1736
- const allProcessed = FlightPlanUtils.processFlightPlan(decodeResult, (parts[31] + checksum).split(":"));
1737
- processRoute(decodeResult, past, time, next, eta);
1738
- decodeResult.decoded = true;
1739
- decodeResult.decoder.decodeLevel = "partial";
1740
- } else {
1741
- if (options.debug) {
1982
+ const fulllyDecoded = H1Helper.decodeH1Message(decodeResult, message.text);
1983
+ decodeResult.decoded = true;
1984
+ decodeResult.decoder.decodeLevel = fulllyDecoded ? "full" : "partial";
1985
+ if (decodeResult.formatted.items.length === 0) {
1986
+ if (options?.debug) {
1742
1987
  console.log(`Decoder: Unknown H1 message: ${message.text}`);
1743
1988
  }
1744
- decodeResult.remaining.text += message.text;
1989
+ decodeResult.remaining.text = message.text;
1745
1990
  decodeResult.decoded = false;
1746
1991
  decodeResult.decoder.decodeLevel = "none";
1747
1992
  }
1748
1993
  return decodeResult;
1749
1994
  }
1750
1995
  };
1751
- function processUnknown(decodeResult, value) {
1752
- decodeResult.remaining.text += "," + value;
1753
- }
1754
- function processPosition2(decodeResult, value) {
1755
- const position = CoordinateUtils.decodeStringCoordinates(value);
1756
- if (position) {
1757
- decodeResult.raw.position = position;
1758
- decodeResult.formatted.items.push({
1759
- type: "aircraft_position",
1760
- code: "POS",
1761
- label: "Aircraft Position",
1762
- value: CoordinateUtils.coordinateString(position)
1763
- });
1764
- }
1765
- }
1766
- function processAlt(decodeResult, value) {
1767
- decodeResult.raw.altitude = Number(value) * 100;
1768
- decodeResult.formatted.items.push({
1769
- type: "altitude",
1770
- code: "ALT",
1771
- label: "Altitude",
1772
- value: `${decodeResult.raw.altitude} feet`
1773
- });
1774
- }
1775
- function processTemp(decodeResult, value) {
1776
- decodeResult.raw.outside_air_temperature = Number(value.substring(1)) * (value.charAt(0) === "M" ? -1 : 1);
1777
- decodeResult.formatted.items.push({
1778
- type: "outside_air_temperature",
1779
- code: "OATEMP",
1780
- label: "Outside Air Temperature (C)",
1781
- value: `${decodeResult.raw.outside_air_temperature}`
1782
- });
1783
- }
1784
- function processRunway(decodeResult, value) {
1785
- decodeResult.raw.arrival_runway = value.replace("RW", "");
1786
- decodeResult.formatted.items.push({
1787
- type: "runway",
1788
- label: "Arrival Runway",
1789
- value: decodeResult.raw.arrival_runway
1790
- });
1791
- }
1792
- function processGndspd(decodeResult, value) {
1793
- decodeResult.raw.groundspeed = Number(value);
1794
- decodeResult.formatted.items.push({
1795
- type: "aircraft_groundspeed",
1796
- code: "GSPD",
1797
- label: "Aircraft Groundspeed",
1798
- value: `${decodeResult.raw.groundspeed}`
1799
- });
1800
- }
1801
- function processRoute(decodeResult, last, time, next, eta, then, date) {
1802
- const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
1803
- const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
1804
- const timeFormat = date ? "epoch" : "tod";
1805
- const lastWaypoint = RouteUtils.getWaypoint(last);
1806
- lastWaypoint.time = lastTime;
1807
- lastWaypoint.timeFormat = timeFormat;
1808
- const nextWaypoint = RouteUtils.getWaypoint(next);
1809
- nextWaypoint.time = nextTime;
1810
- nextWaypoint.timeFormat = timeFormat;
1811
- const thenWaypoint = RouteUtils.getWaypoint(then || "?");
1812
- const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
1813
- decodeResult.raw.route = { waypoints };
1814
- decodeResult.formatted.items.push({
1815
- type: "aircraft_route",
1816
- code: "ROUTE",
1817
- label: "Aircraft Route",
1818
- value: RouteUtils.routeToString(decodeResult.raw.route)
1819
- });
1820
- }
1821
- function processChecksum(decodeResult, value) {
1822
- decodeResult.raw.checksum = Number("0x" + value);
1823
- decodeResult.formatted.items.push({
1824
- type: "message_checksum",
1825
- code: "CHECKSUM",
1826
- label: "Message Checksum",
1827
- value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
1828
- });
1829
- }
1830
- function findHeader(text) {
1831
- const parts = text.split(",");
1832
- const header = parts[0];
1833
- if (header.indexOf("/TS") === -1) {
1834
- return header;
1835
- }
1836
- return parts[0] + "," + parts[1];
1837
- }
1838
1996
 
1839
1997
  // lib/plugins/Label_H1_WRN.ts
1840
1998
  var Label_H1_WRN = class extends DecoderPlugin {
@@ -1857,16 +2015,16 @@ var Label_H1_WRN = class extends DecoderPlugin {
1857
2015
  for (let i = 1; i < fields.length; i++) {
1858
2016
  const field = fields[i];
1859
2017
  if (field.startsWith("PN")) {
1860
- processUnknown2(decodeResult, "/" + field);
2018
+ processUnknown(decodeResult, "/" + field);
1861
2019
  } else {
1862
- processUnknown2(decodeResult, "/" + field);
2020
+ processUnknown(decodeResult, "/" + field);
1863
2021
  }
1864
2022
  }
1865
2023
  const data = parts[1].substring(0, 20);
1866
2024
  const msg = parts[1].substring(20);
1867
2025
  const datetime = data.substring(0, 12);
1868
2026
  const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
1869
- processUnknown2(decodeResult, data.substring(12));
2027
+ processUnknown(decodeResult, data.substring(12));
1870
2028
  decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
1871
2029
  decodeResult.raw.warning_message = msg;
1872
2030
  decodeResult.formatted.items.push({
@@ -1888,7 +2046,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
1888
2046
  return decodeResult;
1889
2047
  }
1890
2048
  };
1891
- function processUnknown2(decodeResult, value) {
2049
+ function processUnknown(decodeResult, value) {
1892
2050
  decodeResult.remaining.text += value;
1893
2051
  }
1894
2052
 
@@ -2989,6 +3147,7 @@ var MessageDecoder = class {
2989
3147
  this.registerPlugin(new Label_15_FST(this));
2990
3148
  this.registerPlugin(new Label_16_N_Space(this));
2991
3149
  this.registerPlugin(new Label_20_POS(this));
3150
+ this.registerPlugin(new Label_21_POS(this));
2992
3151
  this.registerPlugin(new Label_30_Slash_EA(this));
2993
3152
  this.registerPlugin(new Label_44_ETA(this));
2994
3153
  this.registerPlugin(new Label_44_IN(this));