@airframes/acars-decoder 1.6.17 → 1.6.19

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
@@ -28,12 +28,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // index.ts
31
- var acars_decoder_typescript_exports = {};
32
- __export(acars_decoder_typescript_exports, {
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
33
  IcaoDecoder: () => IcaoDecoder,
34
34
  MessageDecoder: () => MessageDecoder
35
35
  });
36
- module.exports = __toCommonJS(acars_decoder_typescript_exports);
36
+ module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // lib/IcaoDecoder.ts
39
39
  var IcaoDecoder = class {
@@ -378,6 +378,9 @@ var ResultFormatter = class {
378
378
  });
379
379
  }
380
380
  static altitude(decodeResult, value) {
381
+ if (isNaN(value)) {
382
+ return;
383
+ }
381
384
  decodeResult.raw.altitude = value;
382
385
  decodeResult.formatted.items.push({
383
386
  type: "altitude",
@@ -387,6 +390,9 @@ var ResultFormatter = class {
387
390
  });
388
391
  }
389
392
  static flightNumber(decodeResult, value) {
393
+ if (value.length === 0) {
394
+ return;
395
+ }
390
396
  decodeResult.raw.flight_number = value;
391
397
  decodeResult.formatted.items.push({
392
398
  type: "flight_number",
@@ -534,6 +540,9 @@ var ResultFormatter = class {
534
540
  });
535
541
  }
536
542
  static temperature(decodeResult, value) {
543
+ if (value.length === 0) {
544
+ return;
545
+ }
537
546
  decodeResult.raw.outside_air_temperature = Number(value.replace("M", "-").replace("P", "+"));
538
547
  decodeResult.formatted.items.push({
539
548
  type: "outside_air_temperature",
@@ -1261,47 +1270,13 @@ var Label_16_N_Space = class extends DecoderPlugin {
1261
1270
  }
1262
1271
  };
1263
1272
 
1264
- // lib/plugins/Label_1M_Slash.ts
1265
- var Label_1M_Slash = class extends DecoderPlugin {
1266
- name = "label-1m-slash";
1267
- qualifiers() {
1268
- return {
1269
- labels: ["1M"],
1270
- preambles: ["/"]
1271
- };
1272
- }
1273
- decode(message, options = {}) {
1274
- const decodeResult = this.defaultResult();
1275
- decodeResult.decoder.name = this.name;
1276
- decodeResult.formatted.description = "ETA Report";
1277
- decodeResult.message = message;
1278
- const results = message.text.split(/\n|\//).slice(1);
1279
- if (results) {
1280
- if (options.debug) {
1281
- console.log(`Label 1M ETA: results`);
1282
- console.log(results);
1283
- }
1284
- decodeResult.raw.flight_number = results[0];
1285
- ResultFormatter.departureAirport(decodeResult, results[3]);
1286
- ResultFormatter.arrivalAirport(decodeResult, results[4]);
1287
- ResultFormatter.alternateAirport(decodeResult, results[5]);
1288
- ResultFormatter.arrivalRunway(decodeResult, results[8].replace(results[4], ""));
1289
- const yymmdd = results[2];
1290
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertDateTimeToEpoch(results[7] + "00", yymmdd.substring(2, 4) + yymmdd.substring(4, 6) + yymmdd.substring(0, 2)), "epoch");
1291
- }
1292
- decodeResult.decoded = true;
1293
- decodeResult.decoder.decodeLevel = "partial";
1294
- return decodeResult;
1295
- }
1296
- };
1297
-
1298
- // lib/plugins/Label_1L_3-line.ts
1299
- var Label_1L_3Line = class extends DecoderPlugin {
1300
- // eslint-disable-line camelcase
1301
- name = "label-1l-3-line";
1273
+ // lib/plugins/Label_16_POSA1.ts
1274
+ var Label_16_POSA1 = class extends DecoderPlugin {
1275
+ name = "label-16-posa1";
1302
1276
  qualifiers() {
1303
1277
  return {
1304
- labels: ["1L"]
1278
+ labels: ["16"],
1279
+ preambles: ["POSA1"]
1305
1280
  };
1306
1281
  }
1307
1282
  decode(message, options = {}) {
@@ -1309,88 +1284,39 @@ var Label_1L_3Line = class extends DecoderPlugin {
1309
1284
  decodeResult.decoder.name = this.name;
1310
1285
  decodeResult.formatted.description = "Position Report";
1311
1286
  decodeResult.message = message;
1312
- const lines = message.text.split("\r\n");
1313
- if (lines.length !== 3) {
1287
+ const fields = message.text.split(",");
1288
+ if (fields.length !== 11 || !fields[0].startsWith("POSA1")) {
1314
1289
  if (options.debug) {
1315
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1290
+ console.log(`Decoder: Unknown 16 message: ${message.text}`);
1316
1291
  }
1317
1292
  decodeResult.remaining.text = message.text;
1318
1293
  decodeResult.decoded = false;
1319
1294
  decodeResult.decoder.decodeLevel = "none";
1320
1295
  return decodeResult;
1321
1296
  }
1322
- const parts = message.text.replaceAll("\r\n", "/").split("/");
1323
- const data = /* @__PURE__ */ new Map();
1324
- data.set("", parts[0]);
1325
- for (let i = 1; i < parts.length; i++) {
1326
- const part = parts[i].split(" ");
1327
- data.set(part[0], part.slice(1).join(" "));
1328
- }
1329
- const dep = data.get("DEP");
1330
- if (dep) {
1331
- ResultFormatter.departureAirport(decodeResult, dep);
1332
- data.delete("DEP");
1333
- }
1334
- const des = data.get("DES");
1335
- if (des) {
1336
- ResultFormatter.arrivalAirport(decodeResult, des);
1337
- data.delete("DES");
1338
- }
1339
- const eta = data.get("ETA");
1340
- if (eta) {
1341
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
1342
- data.delete("ETA");
1343
- }
1344
- const alt = data.get("ALT");
1345
- if (alt) {
1346
- ResultFormatter.altitude(decodeResult, Number(alt));
1347
- data.delete("ALT");
1348
- }
1349
- const fn = data.get("FN");
1350
- if (fn) {
1351
- ResultFormatter.flightNumber(decodeResult, fn);
1352
- data.delete("FN");
1353
- }
1354
- const day = data.get("DAY");
1355
- const utc = data.get("UTC");
1356
- if (day && utc) {
1357
- decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
1358
- data.delete("DAY");
1359
- data.delete("UTC");
1360
- }
1361
- const lat = data.get("LAT");
1362
- const lon = data.get("LON");
1363
- if (lat && lon) {
1364
- ResultFormatter.position(decodeResult, {
1365
- latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
1366
- longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
1367
- });
1368
- data.delete("LAT");
1369
- data.delete("LON");
1370
- }
1371
- let remaining = "";
1372
- for (const [key, value] of data.entries()) {
1373
- if (key === "") {
1374
- remaining += value;
1375
- } else {
1376
- remaining += `/${key} ${value}`;
1377
- }
1378
- }
1379
- decodeResult.remaining.text = remaining;
1297
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(fields[0].substring(5)));
1298
+ const waypoint = fields[1].trim();
1299
+ const time = DateTimeUtils.convertHHMMSSToTod(fields[2]);
1300
+ ResultFormatter.altitude(decodeResult, Number(fields[3]) * 100);
1301
+ const nextWaypoint = fields[4].trim();
1302
+ const nextTime = DateTimeUtils.convertHHMMSSToTod(fields[5]);
1303
+ ResultFormatter.unknownArr(decodeResult, fields.slice(6), ",");
1304
+ ResultFormatter.route(decodeResult, { waypoints: [
1305
+ { name: waypoint, time, timeFormat: "tod" },
1306
+ { name: nextWaypoint, time: nextTime, timeFormat: "tod" }
1307
+ ] });
1380
1308
  decodeResult.decoded = true;
1381
1309
  decodeResult.decoder.decodeLevel = "partial";
1382
1310
  return decodeResult;
1383
1311
  }
1384
1312
  };
1385
1313
 
1386
- // lib/plugins/Label_1L_070.ts
1387
- var Label_1L_070 = class extends DecoderPlugin {
1388
- // eslint-disable-line camelcase
1389
- name = "label-1l-070";
1314
+ // lib/plugins/Label_16_TOD.ts
1315
+ var Label_16_TOD = class extends DecoderPlugin {
1316
+ name = "label-16-tod";
1390
1317
  qualifiers() {
1391
1318
  return {
1392
- labels: ["1L"],
1393
- preambles: ["000000070"]
1319
+ labels: ["16"]
1394
1320
  };
1395
1321
  }
1396
1322
  decode(message, options = {}) {
@@ -1398,340 +1324,574 @@ var Label_1L_070 = class extends DecoderPlugin {
1398
1324
  decodeResult.decoder.name = this.name;
1399
1325
  decodeResult.formatted.description = "Position Report";
1400
1326
  decodeResult.message = message;
1401
- if (!message.text.startsWith("000000070")) {
1327
+ const fields = message.text.split(",");
1328
+ const time = DateTimeUtils.convertHHMMSSToTod(fields[0]);
1329
+ if (fields.length !== 5 || Number.isNaN(time)) {
1402
1330
  if (options.debug) {
1403
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1331
+ console.log(`Decoder: Unknown 16 message: ${message.text}`);
1404
1332
  }
1405
1333
  decodeResult.remaining.text = message.text;
1406
1334
  decodeResult.decoded = false;
1407
1335
  decodeResult.decoder.decodeLevel = "none";
1408
1336
  return decodeResult;
1409
1337
  }
1410
- const parts = message.text.substring(9).split(",");
1411
- if (parts.length !== 7) {
1412
- if (options.debug) {
1413
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1414
- }
1415
- decodeResult.remaining.text = message.text;
1416
- decodeResult.decoded = false;
1417
- decodeResult.decoder.decodeLevel = "none";
1418
- return decodeResult;
1338
+ ResultFormatter.time_of_day(decodeResult, time);
1339
+ if (fields[1] !== "") {
1340
+ ResultFormatter.altitude(decodeResult, Number(fields[1]));
1419
1341
  }
1420
- ResultFormatter.departureAirport(decodeResult, parts[0]);
1421
- ResultFormatter.arrivalAirport(decodeResult, parts[1]);
1422
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
1423
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
1342
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1343
+ ResultFormatter.unknown(decodeResult, fields[3]);
1344
+ const temp = fields[4].split("/");
1345
+ const posFields = temp[0].split(" ");
1424
1346
  ResultFormatter.position(decodeResult, {
1425
- latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
1426
- longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
1347
+ latitude: CoordinateUtils.getDirection(posFields[0]) * Number(posFields[1]),
1348
+ longitude: CoordinateUtils.getDirection(posFields[2]) * Number(posFields[3])
1427
1349
  });
1428
- decodeResult.remaining.text = parts[6];
1350
+ if (temp.length > 1) {
1351
+ ResultFormatter.flightNumber(decodeResult, temp[1]);
1352
+ }
1429
1353
  decodeResult.decoded = true;
1430
1354
  decodeResult.decoder.decodeLevel = "partial";
1431
1355
  return decodeResult;
1432
1356
  }
1433
1357
  };
1434
1358
 
1435
- // lib/plugins/Label_1L_660.ts
1436
- var Label_1L_660 = class extends DecoderPlugin {
1437
- // eslint-disable-line camelcase
1438
- name = "label-1l-660";
1439
- qualifiers() {
1440
- return {
1441
- labels: ["1L"],
1442
- preambles: ["000000660"]
1443
- };
1444
- }
1445
- decode(message, options = {}) {
1446
- const decodeResult = this.defaultResult();
1447
- decodeResult.decoder.name = this.name;
1448
- decodeResult.formatted.description = "Position Report";
1449
- decodeResult.message = message;
1450
- if (!message.text.startsWith("000000660")) {
1451
- if (options.debug) {
1452
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1359
+ // lib/utils/flight_plan_utils.ts
1360
+ var FlightPlanUtils = class _FlightPlanUtils {
1361
+ /**
1362
+ * Processes flight plan data
1363
+ *
1364
+ * Expected format is [header, key1, val1, ... keyN, valN]
1365
+ *
1366
+ * @param decodeResult - results
1367
+ * @param data - original message split by ':'
1368
+ * @returns whether all fields were processed or not
1369
+ */
1370
+ static processFlightPlan(decodeResult, data) {
1371
+ let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
1372
+ for (let i = 1; i < data.length; i += 2) {
1373
+ const key = data[i];
1374
+ const value = data[i + 1];
1375
+ switch (key) {
1376
+ case "A":
1377
+ addProcedure(decodeResult, value, "arrival");
1378
+ break;
1379
+ case "AA":
1380
+ addArrivalAirport(decodeResult, value);
1381
+ break;
1382
+ case "AP":
1383
+ addProcedure(decodeResult, value, "approach");
1384
+ break;
1385
+ case "CR":
1386
+ addCompanyRoute(decodeResult, value);
1387
+ break;
1388
+ case "D":
1389
+ addProcedure(decodeResult, value, "departure");
1390
+ break;
1391
+ case "DA":
1392
+ addDepartureAirport(decodeResult, value);
1393
+ break;
1394
+ case "F":
1395
+ addRoute(decodeResult, value);
1396
+ break;
1397
+ case "R":
1398
+ addRunway(decodeResult, value);
1399
+ break;
1400
+ // case 'WS': // something about routes, has altitude, so current parsing won't work
1401
+ // break;
1402
+ default:
1403
+ if (allKnownFields) {
1404
+ decodeResult.remaining.text = "";
1405
+ allKnownFields = false;
1406
+ }
1407
+ decodeResult.remaining.text += `:${key}:${value}`;
1408
+ decodeResult.decoder.decodeLevel = "partial";
1453
1409
  }
1454
- decodeResult.remaining.text = message.text;
1455
- decodeResult.decoded = false;
1456
- decodeResult.decoder.decodeLevel = "none";
1457
- return decodeResult;
1458
1410
  }
1459
- const parts = message.text.substring(9).split(",");
1460
- if (parts.length !== 5) {
1461
- if (options.debug) {
1462
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1411
+ return allKnownFields;
1412
+ }
1413
+ static parseHeader(decodeResult, header) {
1414
+ let allKnownFields = true;
1415
+ if (header.startsWith("RF")) {
1416
+ decodeResult.formatted.items.push({
1417
+ type: "status",
1418
+ code: "ROUTE_STATUS",
1419
+ label: "Route Status",
1420
+ value: "Route Filed"
1421
+ });
1422
+ decodeResult.raw.route_status = "RF";
1423
+ if (header.length > 2) {
1424
+ addRoute(decodeResult, header.substring(2));
1463
1425
  }
1464
- decodeResult.remaining.text = message.text;
1465
- decodeResult.decoded = false;
1466
- decodeResult.decoder.decodeLevel = "none";
1467
- return decodeResult;
1468
- }
1469
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(parts[0]);
1470
- if (position) {
1471
- ResultFormatter.position(decodeResult, position);
1426
+ } else if (header.startsWith("RP")) {
1427
+ decodeResult.raw.route_status = "RP";
1428
+ decodeResult.formatted.items.push({
1429
+ type: "status",
1430
+ code: "ROUTE_STATUS",
1431
+ label: "Route Status",
1432
+ value: "Route Planned"
1433
+ });
1434
+ decodeResult.raw.route_status = header;
1435
+ } else if (header.startsWith("RI")) {
1436
+ decodeResult.raw.route_status = "RI";
1437
+ decodeResult.formatted.items.push({
1438
+ type: "status",
1439
+ code: "ROUTE_STATUS",
1440
+ label: "Route Status",
1441
+ value: "Route Inactive"
1442
+ });
1443
+ } else {
1444
+ decodeResult.remaining.text += header;
1445
+ allKnownFields = false;
1472
1446
  }
1473
- const hhmmss = parts[1].substring(0, 6);
1474
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmmss));
1475
- const fl = parts[1].substring(6, 9);
1476
- ResultFormatter.altitude(decodeResult, Number(fl) * 100);
1477
- const next = parts[1].substring(9);
1478
- ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
1479
- decodeResult.remaining.text = parts.slice(2).join(",");
1480
- decodeResult.decoded = true;
1481
- decodeResult.decoder.decodeLevel = "partial";
1482
- return decodeResult;
1447
+ return allKnownFields;
1483
1448
  }
1484
1449
  };
1485
-
1486
- // lib/plugins/Label_1L_Slash.ts
1487
- var Label_1L_Slash = class extends DecoderPlugin {
1488
- // eslint-disable-line camelcase
1489
- name = "label-1l-1-line";
1490
- qualifiers() {
1491
- return {
1492
- labels: ["1L"],
1493
- preambles: ["+", "-"]
1494
- };
1450
+ function addArrivalAirport(decodeResult, value) {
1451
+ ResultFormatter.arrivalAirport(decodeResult, value);
1452
+ }
1453
+ function addDepartureAirport(decodeResult, value) {
1454
+ ResultFormatter.departureAirport(decodeResult, value);
1455
+ }
1456
+ function addRunway(decodeResult, value) {
1457
+ if (value.length === 8) {
1458
+ ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
1495
1459
  }
1496
- decode(message, options = {}) {
1497
- const decodeResult = this.defaultResult();
1498
- decodeResult.decoder.name = this.name;
1499
- decodeResult.formatted.description = "Position Report";
1500
- decodeResult.message = message;
1501
- const parts = message.text.split("/");
1502
- if (parts.length !== 7) {
1503
- if (options.debug) {
1504
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1505
- }
1506
- decodeResult.remaining.text = message.text;
1460
+ ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
1461
+ }
1462
+ function addRoute(decodeResult, value) {
1463
+ const route = value.split(".");
1464
+ ResultFormatter.route(decodeResult, { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) });
1465
+ }
1466
+ function addProcedure(decodeResult, value, type) {
1467
+ if (decodeResult.raw.procedures === void 0) {
1468
+ decodeResult.raw.procedures = [];
1469
+ }
1470
+ const data = value.split(".");
1471
+ let waypoints;
1472
+ if (data.length > 1) {
1473
+ waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1474
+ }
1475
+ const route = { name: data[0], waypoints };
1476
+ decodeResult.raw.procedures.push({ type, route });
1477
+ const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
1478
+ let procedureValue = route.name;
1479
+ decodeResult.formatted.items.push({
1480
+ type: `procedure`,
1481
+ code: "proc",
1482
+ label: `${procedureName} Procedure`,
1483
+ value: RouteUtils.routeToString(route)
1484
+ });
1485
+ }
1486
+ function addCompanyRoute(decodeResult, value) {
1487
+ const segments = value.split(".");
1488
+ const parens_idx = segments[0].indexOf("(");
1489
+ let name;
1490
+ let runway;
1491
+ if (parens_idx === -1) {
1492
+ name = segments[0];
1493
+ } else {
1494
+ name = segments[0].slice(0, parens_idx);
1495
+ runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
1496
+ }
1497
+ let waypoints;
1498
+ if (segments.length > 1) {
1499
+ waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
1500
+ }
1501
+ decodeResult.raw.company_route = {
1502
+ name,
1503
+ runway,
1504
+ waypoints
1505
+ };
1506
+ decodeResult.formatted.items.push({
1507
+ type: "company_route",
1508
+ code: "CR",
1509
+ label: "Company Route",
1510
+ value: RouteUtils.routeToString(decodeResult.raw.company_route)
1511
+ });
1512
+ }
1513
+
1514
+ // lib/utils/h1_helper.ts
1515
+ var H1Helper = class _H1Helper {
1516
+ static decodeH1Message(decodeResult, message) {
1517
+ const checksum = message.slice(-4);
1518
+ const data = message.slice(0, message.length - 4);
1519
+ const fields = data.split("/");
1520
+ const canDecode = parseMessageType(decodeResult, fields[0]);
1521
+ if (!canDecode) {
1507
1522
  decodeResult.decoded = false;
1508
1523
  decodeResult.decoder.decodeLevel = "none";
1509
- return decodeResult;
1524
+ return false;
1510
1525
  }
1511
- const data = /* @__PURE__ */ new Map();
1512
- data.set("LAT", parts[0].replaceAll(" ", ""));
1513
- data.set("LON", parts[1].replaceAll(" ", ""));
1514
- for (let i = 2; i < parts.length; i++) {
1515
- const part = parts[i].split(" ");
1516
- data.set(part[0], part.slice(1).join(" "));
1526
+ for (let i = 1; i < fields.length; ++i) {
1527
+ if (fields[i].startsWith("FN")) {
1528
+ decodeResult.raw.flight_number = fields[i].substring(2);
1529
+ } else if (fields[i].startsWith("SN")) {
1530
+ decodeResult.raw.serial_number = fields[i].substring(2);
1531
+ } else if (fields[i].startsWith("DC")) {
1532
+ processDC(decodeResult, fields[i].substring(2).split(","));
1533
+ } else if (fields[i].startsWith("TS")) {
1534
+ _H1Helper.processTS(decodeResult, fields[i].substring(2).split(","));
1535
+ } else if (fields[i].startsWith("PS")) {
1536
+ _H1Helper.processPS(decodeResult, fields[i].substring(2).split(","));
1537
+ } else if (fields[i].startsWith("DT")) {
1538
+ const data2 = fields[i].substring(2).split(",");
1539
+ processDT(decodeResult, data2);
1540
+ } else if (fields[i].startsWith("ID")) {
1541
+ processIdentification(decodeResult, fields[i].substring(2).split(","));
1542
+ } else if (fields[i].startsWith("LR")) {
1543
+ const data2 = fields[i].substring(2).split(",");
1544
+ processLR(decodeResult, data2);
1545
+ } else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
1546
+ FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
1547
+ } else if (fields[i].startsWith("PR")) {
1548
+ ResultFormatter.unknown(decodeResult, fields[i], "/");
1549
+ } else if (fields[i].startsWith("AF")) {
1550
+ processAirField(decodeResult, fields[i].substring(2).split(","));
1551
+ } else if (fields[i].startsWith("TD")) {
1552
+ processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
1553
+ } else if (fields[i].startsWith("FX")) {
1554
+ ResultFormatter.freetext(decodeResult, fields[i].substring(2));
1555
+ } else if (fields[i].startsWith("ET")) {
1556
+ if (fields[i].length === 7) {
1557
+ ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 3)));
1558
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3)));
1559
+ } else if (fields[i].length === 8) {
1560
+ ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 4)));
1561
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4)));
1562
+ } else {
1563
+ ResultFormatter.unknown(decodeResult, fields[i], "/");
1564
+ }
1565
+ } else if (fields[i].startsWith("WD")) {
1566
+ processWindData(decodeResult, fields[i].substring(2));
1567
+ } else {
1568
+ ResultFormatter.unknown(decodeResult, fields[i], "/");
1569
+ }
1517
1570
  }
1518
- const position = {
1519
- latitude: Number(data.get("LAT")),
1520
- longitude: Number(data.get("LON"))
1521
- };
1522
- data.delete("LAT");
1523
- data.delete("LON");
1524
- ResultFormatter.position(decodeResult, position);
1525
- const utc = data.get("UTC");
1526
- if (utc) {
1527
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(utc));
1528
- data.delete("UTC");
1571
+ if (decodeResult.formatted.items.length > 0) {
1572
+ ResultFormatter.checksum(decodeResult, checksum);
1529
1573
  }
1530
- const alt = data.get("ALT");
1531
- if (alt) {
1532
- ResultFormatter.altitude(decodeResult, Number(alt));
1533
- data.delete("ALT");
1574
+ return true;
1575
+ }
1576
+ static processPS(decodeResult, data) {
1577
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
1578
+ if (position) {
1579
+ decodeResult.raw.position = position;
1580
+ decodeResult.formatted.items.push({
1581
+ type: "aircraft_position",
1582
+ code: "POS",
1583
+ label: "Aircraft Position",
1584
+ value: CoordinateUtils.coordinateString(position)
1585
+ });
1534
1586
  }
1535
- const fob = data.get("FOB");
1536
- if (fob) {
1537
- ResultFormatter.currentFuel(decodeResult, Number(fob));
1538
- data.delete("FOB");
1587
+ if (data.length === 9) {
1588
+ processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
1589
+ ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
1590
+ ResultFormatter.temperature(decodeResult, data[6]);
1591
+ ResultFormatter.unknown(decodeResult, data[7]);
1592
+ ResultFormatter.unknown(decodeResult, data[8]);
1539
1593
  }
1540
- const eta = data.get("ETA");
1541
- if (eta) {
1542
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
1543
- data.delete("ETA");
1594
+ if (data.length === 14) {
1595
+ ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
1596
+ processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
1597
+ ResultFormatter.temperature(decodeResult, data[7]);
1598
+ ResultFormatter.unknownArr(decodeResult, data.slice(8));
1544
1599
  }
1545
- let remaining = "";
1546
- for (const [key, value] of data.entries()) {
1547
- remaining += `/${key} ${value}`;
1600
+ }
1601
+ static processPosition(decodeResult, data) {
1602
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
1603
+ if (position) {
1604
+ ResultFormatter.position(decodeResult, position);
1548
1605
  }
1549
- decodeResult.remaining.text = remaining;
1550
- decodeResult.decoded = true;
1551
- decodeResult.decoder.decodeLevel = "partial";
1552
- return decodeResult;
1606
+ if (data.length >= 10) {
1607
+ ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
1608
+ processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
1609
+ ResultFormatter.temperature(decodeResult, data[7]);
1610
+ ResultFormatter.unknown(decodeResult, data[8]);
1611
+ ResultFormatter.unknown(decodeResult, data[9]);
1612
+ }
1613
+ if (data.length >= 14) {
1614
+ ResultFormatter.unknownArr(decodeResult, data.slice(10));
1615
+ }
1616
+ }
1617
+ static processTS(decodeResult, data) {
1618
+ let time = DateTimeUtils.convertDateTimeToEpoch(data[0], data[1]);
1619
+ if (Number.isNaN(time)) {
1620
+ const date = data[1].substring(2, 4) + data[1].substring(0, 2) + data[1].substring(4, 6);
1621
+ time = DateTimeUtils.convertDateTimeToEpoch(data[0], date);
1622
+ }
1623
+ decodeResult.raw.message_date = data[1];
1624
+ decodeResult.raw.message_timestamp = time;
1553
1625
  }
1554
1626
  };
1555
-
1556
- // lib/plugins/Label_20_POS.ts
1557
- var Label_20_POS = class extends DecoderPlugin {
1558
- name = "label-20-pos";
1559
- qualifiers() {
1560
- return {
1561
- labels: ["20"],
1562
- preambles: ["POS"]
1563
- };
1627
+ function processAirField(decodeResult, data) {
1628
+ if (data.length === 2) {
1629
+ ResultFormatter.departureAirport(decodeResult, data[0]);
1630
+ ResultFormatter.arrivalAirport(decodeResult, data[1]);
1631
+ } else {
1632
+ ResultFormatter.unknown(decodeResult, data.join(","), "AF/");
1564
1633
  }
1565
- decode(message, options = {}) {
1566
- const decodeResult = this.defaultResult();
1567
- decodeResult.decoder.name = this.name;
1568
- decodeResult.formatted.description = "Position Report";
1569
- decodeResult.message = message;
1570
- decodeResult.raw.preamble = message.text.substring(0, 3);
1571
- const content = message.text.substring(3);
1572
- const fields = content.split(",");
1573
- if (fields.length == 11) {
1574
- if (options.debug) {
1575
- console.log(`DEBUG: ${this.name}: Variation 1 detected`);
1576
- }
1577
- const rawCoords = fields[0];
1578
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(rawCoords));
1579
- decodeResult.decoded = true;
1580
- decodeResult.decoder.decodeLevel = "full";
1581
- } else if (fields.length == 5) {
1582
- if (options.debug) {
1583
- console.log(`DEBUG: ${this.name}: Variation 2 detected`);
1584
- }
1585
- const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
1586
- if (position) {
1587
- ResultFormatter.position(decodeResult, position);
1588
- }
1589
- decodeResult.decoded = true;
1590
- decodeResult.decoder.decodeLevel = "full";
1591
- } else {
1592
- if (options.debug) {
1593
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
1634
+ }
1635
+ function processTimeOfDeparture(decodeResult, data) {
1636
+ if (data.length === 2) {
1637
+ decodeResult.raw.plannedDepartureTime = data[0];
1638
+ decodeResult.formatted.items.push({
1639
+ type: "ptd",
1640
+ code: "ptd",
1641
+ label: "Planned Departure Time",
1642
+ value: `YYYY-MM-${data[0].substring(0, 2)}T${data[0].substring(2, 4)}:${data[0].substring(4)}:00Z`
1643
+ });
1644
+ decodeResult.raw.plannedDepartureTime = data[1];
1645
+ decodeResult.formatted.items.push({
1646
+ type: "etd",
1647
+ code: "etd",
1648
+ label: "Estimated Departure Time",
1649
+ value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
1650
+ });
1651
+ } else {
1652
+ ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
1653
+ }
1654
+ }
1655
+ function processIdentification(decodeResult, data) {
1656
+ ResultFormatter.tail(decodeResult, data[0]);
1657
+ if (data.length > 1) {
1658
+ ResultFormatter.flightNumber(decodeResult, data[1]);
1659
+ }
1660
+ if (data.length > 2) {
1661
+ decodeResult.raw.mission_number = data[2];
1662
+ }
1663
+ }
1664
+ function processDT(decodeResult, data) {
1665
+ if (!decodeResult.raw.arrival_icao) {
1666
+ ResultFormatter.arrivalAirport(decodeResult, data[0]);
1667
+ } else if (decodeResult.raw.arrival_icao != data[0]) {
1668
+ ResultFormatter.unknownArr(decodeResult, data);
1669
+ }
1670
+ if (data.length > 1) {
1671
+ ResultFormatter.arrivalRunway(decodeResult, data[1]);
1672
+ }
1673
+ if (data.length > 2) {
1674
+ ResultFormatter.currentFuel(decodeResult, Number(data[2]));
1675
+ }
1676
+ if (data.length > 3) {
1677
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[3]));
1678
+ }
1679
+ if (data.length > 4) {
1680
+ ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
1681
+ }
1682
+ if (data.length > 5) {
1683
+ ResultFormatter.unknownArr(decodeResult, data);
1684
+ }
1685
+ }
1686
+ function processLR(decodeResult, data) {
1687
+ if (data.length === 19) {
1688
+ ResultFormatter.unknown(decodeResult, data[1]);
1689
+ ResultFormatter.flightNumber(decodeResult, data[2]);
1690
+ ResultFormatter.departureAirport(decodeResult, data[3]);
1691
+ ResultFormatter.arrivalAirport(decodeResult, data[4]);
1692
+ ResultFormatter.arrivalRunway(decodeResult, data[5]);
1693
+ ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
1694
+ } else {
1695
+ ResultFormatter.unknown(decodeResult, data.join(","));
1696
+ }
1697
+ }
1698
+ function parseMessageType(decodeResult, messageType) {
1699
+ const parts = messageType.split("#");
1700
+ if (parts.length == 1) {
1701
+ if (parts[0].startsWith("POS")) {
1702
+ H1Helper.processPosition(decodeResult, parts[0].substring(3).split(","));
1703
+ return processMessageType(decodeResult, "POS");
1704
+ } else if (parts[0].length === 13) {
1705
+ if (processMessageType(decodeResult, parts[0].substring(10))) {
1706
+ ResultFormatter.unknown(decodeResult, parts[0].substring(0, 4));
1707
+ ResultFormatter.flightNumber(decodeResult, parts[0].slice(4, 10));
1708
+ return true;
1594
1709
  }
1595
- decodeResult.decoded = false;
1596
- decodeResult.decoder.decodeLevel = "none";
1597
1710
  }
1598
- return decodeResult;
1711
+ return processMessageType(decodeResult, parts[0].substring(0, 3));
1712
+ } else if (parts.length == 2) {
1713
+ if (parts[0].length > 0) {
1714
+ ResultFormatter.unknown(decodeResult, parts[0].substring(0, 4));
1715
+ ResultFormatter.flightNumber(decodeResult, parts[0].substring(4));
1716
+ ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
1717
+ }
1718
+ const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
1719
+ if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
1720
+ H1Helper.processPosition(decodeResult, parts[1].substring(6).split(","));
1721
+ }
1722
+ return processMessageType(decodeResult, type);
1723
+ } else {
1724
+ ResultFormatter.unknown(decodeResult, messageType);
1725
+ return false;
1599
1726
  }
1600
- };
1727
+ }
1728
+ function processMessageType(decodeResult, type) {
1729
+ if (type === "FPN") {
1730
+ decodeResult.formatted.description = "Flight Plan";
1731
+ } else if (type === "FTX") {
1732
+ decodeResult.formatted.description = "Free Text";
1733
+ } else if (type === "INI") {
1734
+ decodeResult.formatted.description = "Flight Plan Initial Report";
1735
+ } else if (type === "POS") {
1736
+ decodeResult.formatted.description = "Position Report";
1737
+ } else if (type === "PRG") {
1738
+ decodeResult.formatted.description = "Progress Report";
1739
+ } else if (type === "PWI") {
1740
+ decodeResult.formatted.description = "Weather Report";
1741
+ } else {
1742
+ decodeResult.formatted.description = "Unknown H1 Message";
1743
+ return false;
1744
+ }
1745
+ return true;
1746
+ }
1747
+ function processDC(decodeResult, data) {
1748
+ decodeResult.raw.message_date = data[0];
1749
+ if (data.length === 1) {
1750
+ } else if (data.length === 2) {
1751
+ const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
1752
+ const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
1753
+ decodeResult.raw.message_timestamp = time;
1754
+ }
1755
+ }
1756
+ function processRoute(decodeResult, last, time, next, eta, then, date) {
1757
+ const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
1758
+ const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
1759
+ const timeFormat = date ? "epoch" : "tod";
1760
+ const lastWaypoint = RouteUtils.getWaypoint(last);
1761
+ lastWaypoint.time = lastTime;
1762
+ lastWaypoint.timeFormat = timeFormat;
1763
+ const nextWaypoint = RouteUtils.getWaypoint(next);
1764
+ nextWaypoint.time = nextTime;
1765
+ nextWaypoint.timeFormat = timeFormat;
1766
+ const thenWaypoint = RouteUtils.getWaypoint(then || "?");
1767
+ const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
1768
+ decodeResult.raw.route = { waypoints };
1769
+ decodeResult.formatted.items.push({
1770
+ type: "aircraft_route",
1771
+ code: "ROUTE",
1772
+ label: "Aircraft Route",
1773
+ value: RouteUtils.routeToString(decodeResult.raw.route)
1774
+ });
1775
+ }
1776
+ function processWindData(decodeResult, message) {
1777
+ if (decodeResult.raw.wind_data === void 0) {
1778
+ decodeResult.raw.wind_data = [];
1779
+ }
1780
+ const flightLevel = Number(message.slice(0, 3));
1781
+ const fields = message.slice(4).split(".");
1782
+ fields.forEach((field) => {
1783
+ const data = field.split(",");
1784
+ const waypoint = data[0];
1785
+ const windData = data[1];
1786
+ const windDirection = Number(windData.slice(0, 3));
1787
+ const windSpeed = Number(windData.slice(3));
1788
+ if (data.length === 3) {
1789
+ const tempData = data[2];
1790
+ const tempFlightLevel = Number(tempData.slice(0, 3));
1791
+ const tempString = tempData.slice(3);
1792
+ const tempDegrees = Number(tempString.substring(1)) * (tempString.charAt(0) === "M" ? -1 : 1);
1793
+ decodeResult.raw.wind_data.push({
1794
+ waypoint,
1795
+ flightLevel,
1796
+ windDirection,
1797
+ windSpeed,
1798
+ temperature: {
1799
+ flightLevel: tempFlightLevel,
1800
+ degreesC: tempDegrees
1801
+ }
1802
+ });
1803
+ decodeResult.formatted.items.push({
1804
+ type: "wind_data",
1805
+ code: "WIND",
1806
+ label: "Wind Data",
1807
+ value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt, ${tempDegrees}\xB0C at FL${tempFlightLevel}`
1808
+ });
1809
+ } else {
1810
+ decodeResult.raw.wind_data.push({
1811
+ waypoint,
1812
+ flightLevel,
1813
+ windDirection,
1814
+ windSpeed
1815
+ });
1816
+ decodeResult.formatted.items.push({
1817
+ type: "wind_data",
1818
+ code: "WIND",
1819
+ label: "Wind Data",
1820
+ value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt`
1821
+ });
1822
+ }
1823
+ });
1824
+ }
1601
1825
 
1602
- // lib/plugins/Label_21_POS.ts
1603
- var Label_21_POS = class extends DecoderPlugin {
1604
- name = "label-21-pos";
1826
+ // lib/plugins/Label_1J_2J_FTX.ts
1827
+ var Label_1J_2J_FTX = class extends DecoderPlugin {
1828
+ name = "label-1j-2j-ftx";
1605
1829
  qualifiers() {
1606
1830
  return {
1607
- labels: ["21"],
1608
- preambles: ["POS"]
1831
+ labels: ["1J", "2J"]
1609
1832
  };
1610
1833
  }
1611
1834
  decode(message, options = {}) {
1612
- const decodeResult = this.defaultResult();
1835
+ let decodeResult = this.defaultResult();
1613
1836
  decodeResult.decoder.name = this.name;
1614
- decodeResult.formatted.description = "Position Report";
1615
1837
  decodeResult.message = message;
1616
- decodeResult.raw.preamble = message.text.substring(0, 3);
1617
- const content = message.text.substring(3);
1618
- const fields = content.split(",");
1619
- if (fields.length == 9) {
1620
- processPosition(decodeResult, fields[0].trim());
1621
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1622
- ResultFormatter.altitude(decodeResult, Number(fields[3]));
1623
- ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
1624
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[7]));
1625
- ResultFormatter.arrivalAirport(decodeResult, fields[8]);
1626
- ResultFormatter.unknownArr(decodeResult, [fields[1], fields[4], fields[5]]);
1627
- decodeResult.decoded = true;
1628
- decodeResult.decoder.decodeLevel = "partial";
1629
- } else {
1838
+ const msg = message.text.replace(/\n|\r/g, "");
1839
+ const decoded = H1Helper.decodeH1Message(decodeResult, msg);
1840
+ decodeResult.decoded = decoded;
1841
+ decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
1842
+ if (decodeResult.formatted.items.length === 0) {
1630
1843
  if (options.debug) {
1631
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
1844
+ console.log(`Decoder: Unknown 1J/2J message: ${message.text}`);
1632
1845
  }
1846
+ ResultFormatter.unknown(decodeResult, message.text);
1633
1847
  decodeResult.decoded = false;
1634
1848
  decodeResult.decoder.decodeLevel = "none";
1635
1849
  }
1636
1850
  return decodeResult;
1637
1851
  }
1638
1852
  };
1639
- function processPosition(decodeResult, value) {
1640
- if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
1641
- return;
1642
- }
1643
- const latDir = value[0] === "N" ? 1 : -1;
1644
- const lonDir = value[8] === "E" ? 1 : -1;
1645
- const position = {
1646
- latitude: latDir * Number(value.substring(1, 7)),
1647
- longitude: lonDir * Number(value.substring(9, 15))
1648
- };
1649
- ResultFormatter.position(decodeResult, position);
1650
- }
1651
1853
 
1652
- // lib/plugins/Label_22_OFF.ts
1653
- var Label_22_OFF = class extends DecoderPlugin {
1654
- name = "label-22-off";
1854
+ // lib/plugins/Label_1M_Slash.ts
1855
+ var Label_1M_Slash = class extends DecoderPlugin {
1856
+ name = "label-1m-slash";
1655
1857
  qualifiers() {
1656
1858
  return {
1657
- labels: ["22"],
1658
- preambles: ["OFF"]
1859
+ labels: ["1M"],
1860
+ preambles: ["/"]
1659
1861
  };
1660
1862
  }
1661
1863
  decode(message, options = {}) {
1662
1864
  const decodeResult = this.defaultResult();
1663
1865
  decodeResult.decoder.name = this.name;
1664
- decodeResult.formatted.description = "Takeoff Report";
1866
+ decodeResult.formatted.description = "ETA Report";
1665
1867
  decodeResult.message = message;
1666
- if (message.text.startsWith("OFF01")) {
1667
- const fields = message.text.substring(5).split("/");
1668
- if (fields.length != 2) {
1669
- decodeResult.decoded = false;
1670
- decodeResult.decoder.decodeLevel = "none";
1671
- return decodeResult;
1672
- }
1673
- ResultFormatter.flightNumber(decodeResult, fields[0]);
1674
- ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
1675
- ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
1676
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)));
1677
- ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
1678
- ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
1679
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
1680
- ResultFormatter.unknown(decodeResult, fields[1].substring(22));
1681
- decodeResult.decoded = true;
1682
- decodeResult.decoder.decodeLevel = "partial";
1683
- } else if (message.text.startsWith("OFF02\r\n")) {
1684
- const fields = message.text.substring(7).split(",");
1685
- if (fields.length != 4) {
1686
- decodeResult.decoded = false;
1687
- decodeResult.decoder.decodeLevel = "none";
1688
- return decodeResult;
1689
- }
1690
- ResultFormatter.departureAirport(decodeResult, fields[0]);
1691
- ResultFormatter.arrivalAirport(decodeResult, fields[1]);
1692
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1693
- ResultFormatter.unknown(decodeResult, fields[3]);
1694
- decodeResult.decoded = true;
1695
- decodeResult.decoder.decodeLevel = "partial";
1696
- } else if (message.text.startsWith("OFF02")) {
1697
- const fields = message.text.substring(5).split("/");
1698
- if (fields.length != 2) {
1699
- decodeResult.decoded = false;
1700
- decodeResult.decoder.decodeLevel = "none";
1701
- return decodeResult;
1702
- }
1703
- ResultFormatter.flightNumber(decodeResult, fields[0]);
1704
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(fields[1].substring(0, 14));
1705
- if (position) {
1706
- ResultFormatter.position(decodeResult, position);
1707
- }
1708
- ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
1709
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)));
1710
- ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
1711
- ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
1712
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)));
1713
- ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
1714
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)));
1715
- decodeResult.decoded = true;
1716
- decodeResult.decoder.decodeLevel = "partial";
1717
- } else {
1868
+ const results = message.text.split(/\n|\//).slice(1);
1869
+ if (results) {
1718
1870
  if (options.debug) {
1719
- console.log(`DEBUG: ${this.name}: Unknown variation.`);
1871
+ console.log(`Label 1M ETA: results`);
1872
+ console.log(results);
1720
1873
  }
1721
- decodeResult.decoded = false;
1722
- decodeResult.decoder.decodeLevel = "none";
1874
+ decodeResult.raw.flight_number = results[0];
1875
+ ResultFormatter.departureAirport(decodeResult, results[3]);
1876
+ ResultFormatter.arrivalAirport(decodeResult, results[4]);
1877
+ ResultFormatter.alternateAirport(decodeResult, results[5]);
1878
+ ResultFormatter.arrivalRunway(decodeResult, results[8].replace(results[4], ""));
1879
+ const yymmdd = results[2];
1880
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertDateTimeToEpoch(results[7] + "00", yymmdd.substring(2, 4) + yymmdd.substring(4, 6) + yymmdd.substring(0, 2)), "epoch");
1723
1881
  }
1882
+ decodeResult.decoded = true;
1883
+ decodeResult.decoder.decodeLevel = "partial";
1724
1884
  return decodeResult;
1725
1885
  }
1726
1886
  };
1727
1887
 
1728
- // lib/plugins/Label_22_POS.ts
1729
- var Label_22_POS = class extends DecoderPlugin {
1730
- name = "label-22-pos";
1888
+ // lib/plugins/Label_1L_3-line.ts
1889
+ var Label_1L_3Line = class extends DecoderPlugin {
1890
+ // eslint-disable-line camelcase
1891
+ name = "label-1l-3-line";
1731
1892
  qualifiers() {
1732
1893
  return {
1733
- labels: ["22"],
1734
- preambles: ["N", "S"]
1894
+ labels: ["1L"]
1735
1895
  };
1736
1896
  }
1737
1897
  decode(message, options = {}) {
@@ -1739,39 +1899,88 @@ var Label_22_POS = class extends DecoderPlugin {
1739
1899
  decodeResult.decoder.name = this.name;
1740
1900
  decodeResult.formatted.description = "Position Report";
1741
1901
  decodeResult.message = message;
1742
- const fields = message.text.split(",");
1743
- if (fields.length !== 11) {
1902
+ const lines = message.text.split("\r\n");
1903
+ if (lines.length !== 3) {
1744
1904
  if (options.debug) {
1745
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`);
1905
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1746
1906
  }
1907
+ decodeResult.remaining.text = message.text;
1747
1908
  decodeResult.decoded = false;
1748
1909
  decodeResult.decoder.decodeLevel = "none";
1749
1910
  return decodeResult;
1750
1911
  }
1751
- const latStr = fields[0].substring(1, 8);
1752
- const lonStr = fields[0].substring(9);
1753
- const lat = Number(latStr) / 1e4;
1754
- const lon = Number(lonStr) / 1e4;
1755
- ResultFormatter.position(decodeResult, {
1756
- latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
1757
- longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
1758
- });
1759
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1760
- ResultFormatter.altitude(decodeResult, Number(fields[3]));
1761
- ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
1912
+ const parts = message.text.replaceAll("\r\n", "/").split("/");
1913
+ const data = /* @__PURE__ */ new Map();
1914
+ data.set("", parts[0]);
1915
+ for (let i = 1; i < parts.length; i++) {
1916
+ const part = parts[i].split(" ");
1917
+ data.set(part[0], part.slice(1).join(" "));
1918
+ }
1919
+ const dep = data.get("DEP");
1920
+ if (dep) {
1921
+ ResultFormatter.departureAirport(decodeResult, dep);
1922
+ data.delete("DEP");
1923
+ }
1924
+ const des = data.get("DES");
1925
+ if (des) {
1926
+ ResultFormatter.arrivalAirport(decodeResult, des);
1927
+ data.delete("DES");
1928
+ }
1929
+ const eta = data.get("ETA");
1930
+ if (eta) {
1931
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
1932
+ data.delete("ETA");
1933
+ }
1934
+ const alt = data.get("ALT");
1935
+ if (alt) {
1936
+ ResultFormatter.altitude(decodeResult, Number(alt));
1937
+ data.delete("ALT");
1938
+ }
1939
+ const fn = data.get("FN");
1940
+ if (fn) {
1941
+ ResultFormatter.flightNumber(decodeResult, fn);
1942
+ data.delete("FN");
1943
+ }
1944
+ const day = data.get("DAY");
1945
+ const utc = data.get("UTC");
1946
+ if (day && utc) {
1947
+ decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
1948
+ data.delete("DAY");
1949
+ data.delete("UTC");
1950
+ }
1951
+ const lat = data.get("LAT");
1952
+ const lon = data.get("LON");
1953
+ if (lat && lon) {
1954
+ ResultFormatter.position(decodeResult, {
1955
+ latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
1956
+ longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
1957
+ });
1958
+ data.delete("LAT");
1959
+ data.delete("LON");
1960
+ }
1961
+ let remaining = "";
1962
+ for (const [key, value] of data.entries()) {
1963
+ if (key === "") {
1964
+ remaining += value;
1965
+ } else {
1966
+ remaining += `/${key} ${value}`;
1967
+ }
1968
+ }
1969
+ decodeResult.remaining.text = remaining;
1762
1970
  decodeResult.decoded = true;
1763
1971
  decodeResult.decoder.decodeLevel = "partial";
1764
1972
  return decodeResult;
1765
1973
  }
1766
1974
  };
1767
1975
 
1768
- // lib/plugins/Label_24_Slash.ts
1769
- var Label_24_Slash = class extends DecoderPlugin {
1770
- name = "label-24-slash";
1976
+ // lib/plugins/Label_1L_070.ts
1977
+ var Label_1L_070 = class extends DecoderPlugin {
1978
+ // eslint-disable-line camelcase
1979
+ name = "label-1l-070";
1771
1980
  qualifiers() {
1772
1981
  return {
1773
- labels: ["24"],
1774
- preambles: ["/"]
1982
+ labels: ["1L"],
1983
+ preambles: ["000000070"]
1775
1984
  };
1776
1985
  }
1777
1986
  decode(message, options = {}) {
@@ -1779,271 +1988,340 @@ var Label_24_Slash = class extends DecoderPlugin {
1779
1988
  decodeResult.decoder.name = this.name;
1780
1989
  decodeResult.formatted.description = "Position Report";
1781
1990
  decodeResult.message = message;
1782
- const fields = message.text.split("/");
1783
- if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
1784
- const mmddyy = fields[1].substring(4, 6) + fields[1].substring(2, 4) + fields[1].substring(0, 2);
1785
- const hhmmss = fields[2] + "00";
1786
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(hhmmss, mmddyy);
1787
- ResultFormatter.flightNumber(decodeResult, fields[3]);
1788
- ResultFormatter.altitude(decodeResult, Number(fields[4]));
1789
- const lat = fields[5];
1790
- const lon = fields[6];
1791
- const position = {
1792
- latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
1793
- longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
1794
- };
1795
- ResultFormatter.position(decodeResult, position);
1796
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8]));
1797
- ResultFormatter.unknown(decodeResult, fields[7]);
1798
- decodeResult.decoded = true;
1799
- decodeResult.decoder.decodeLevel = "partial";
1800
- } else {
1991
+ if (!message.text.startsWith("000000070")) {
1801
1992
  if (options.debug) {
1802
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`);
1993
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1994
+ }
1995
+ decodeResult.remaining.text = message.text;
1996
+ decodeResult.decoded = false;
1997
+ decodeResult.decoder.decodeLevel = "none";
1998
+ return decodeResult;
1999
+ }
2000
+ const parts = message.text.substring(9).split(",");
2001
+ if (parts.length !== 7) {
2002
+ if (options.debug) {
2003
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1803
2004
  }
2005
+ decodeResult.remaining.text = message.text;
1804
2006
  decodeResult.decoded = false;
1805
2007
  decodeResult.decoder.decodeLevel = "none";
2008
+ return decodeResult;
1806
2009
  }
2010
+ ResultFormatter.departureAirport(decodeResult, parts[0]);
2011
+ ResultFormatter.arrivalAirport(decodeResult, parts[1]);
2012
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
2013
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
2014
+ ResultFormatter.position(decodeResult, {
2015
+ latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
2016
+ longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
2017
+ });
2018
+ decodeResult.remaining.text = parts[6];
2019
+ decodeResult.decoded = true;
2020
+ decodeResult.decoder.decodeLevel = "partial";
1807
2021
  return decodeResult;
1808
2022
  }
1809
2023
  };
1810
2024
 
1811
- // lib/plugins/Label_30_Slash_EA.ts
1812
- var Label_30_Slash_EA = class extends DecoderPlugin {
1813
- name = "label-30-slash-ea";
2025
+ // lib/plugins/Label_1L_660.ts
2026
+ var Label_1L_660 = class extends DecoderPlugin {
2027
+ // eslint-disable-line camelcase
2028
+ name = "label-1l-660";
1814
2029
  qualifiers() {
1815
2030
  return {
1816
- labels: ["30"],
1817
- preambles: ["/EA"]
2031
+ labels: ["1L"],
2032
+ preambles: ["000000660"]
1818
2033
  };
1819
2034
  }
1820
2035
  decode(message, options = {}) {
1821
2036
  const decodeResult = this.defaultResult();
1822
2037
  decodeResult.decoder.name = this.name;
1823
- decodeResult.formatted.description = "ETA Report";
2038
+ decodeResult.formatted.description = "Position Report";
1824
2039
  decodeResult.message = message;
1825
- const results = message.text.split(/\n|\//).slice(1);
1826
- if (results) {
2040
+ if (!message.text.startsWith("000000660")) {
1827
2041
  if (options.debug) {
1828
- console.log(`Label 30 EA: results`);
1829
- console.log(results);
2042
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1830
2043
  }
2044
+ decodeResult.remaining.text = message.text;
2045
+ decodeResult.decoded = false;
2046
+ decodeResult.decoder.decodeLevel = "none";
2047
+ return decodeResult;
1831
2048
  }
1832
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4)));
1833
- if (results[1].substring(0, 2) === "DS") {
1834
- ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
1835
- ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
1836
- } else {
1837
- ResultFormatter.unknown(decodeResult, "/".concat(results[1], "/", results[2]));
2049
+ const parts = message.text.substring(9).split(",");
2050
+ if (parts.length !== 5) {
2051
+ if (options.debug) {
2052
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
2053
+ }
2054
+ decodeResult.remaining.text = message.text;
2055
+ decodeResult.decoded = false;
2056
+ decodeResult.decoder.decodeLevel = "none";
2057
+ return decodeResult;
2058
+ }
2059
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(parts[0]);
2060
+ if (position) {
2061
+ ResultFormatter.position(decodeResult, position);
1838
2062
  }
2063
+ const hhmmss = parts[1].substring(0, 6);
2064
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmmss));
2065
+ const fl = parts[1].substring(6, 9);
2066
+ ResultFormatter.altitude(decodeResult, Number(fl) * 100);
2067
+ const next = parts[1].substring(9);
2068
+ ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
2069
+ decodeResult.remaining.text = parts.slice(2).join(",");
1839
2070
  decodeResult.decoded = true;
1840
2071
  decodeResult.decoder.decodeLevel = "partial";
1841
2072
  return decodeResult;
1842
2073
  }
1843
2074
  };
1844
2075
 
1845
- // lib/plugins/Label_44_ETA.ts
1846
- var Label_44_ETA = class extends DecoderPlugin {
1847
- name = "label-44-eta";
2076
+ // lib/plugins/Label_1L_Slash.ts
2077
+ var Label_1L_Slash = class extends DecoderPlugin {
2078
+ // eslint-disable-line camelcase
2079
+ name = "label-1l-1-line";
1848
2080
  qualifiers() {
1849
2081
  return {
1850
- labels: ["44"],
1851
- preambles: ["00ETA01", "00ETA02", "00ETA03", "ETA01", "ETA02", "ETA03"]
2082
+ labels: ["1L"],
2083
+ preambles: ["+", "-"]
1852
2084
  };
1853
2085
  }
1854
2086
  decode(message, options = {}) {
1855
2087
  const decodeResult = this.defaultResult();
1856
2088
  decodeResult.decoder.name = this.name;
1857
- decodeResult.formatted.description = "ETA Report";
2089
+ decodeResult.formatted.description = "Position Report";
1858
2090
  decodeResult.message = message;
1859
- const data = message.text.split(",");
1860
- if (data.length >= 9) {
1861
- if (options.debug) {
1862
- console.log(`Label 44 ETA Report: groups`);
1863
- console.log(data);
1864
- }
1865
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
1866
- ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
1867
- ResultFormatter.departureAirport(decodeResult, data[3]);
1868
- ResultFormatter.arrivalAirport(decodeResult, data[4]);
1869
- ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
1870
- ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
1871
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
1872
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[7]));
1873
- const fuel = Number(data[8]);
1874
- if (!isNaN(fuel)) {
1875
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
1876
- }
1877
- if (data.length > 9) {
1878
- ResultFormatter.unknownArr(decodeResult, data.slice(9));
1879
- }
1880
- } else {
2091
+ const parts = message.text.split("/");
2092
+ if (parts.length !== 7) {
1881
2093
  if (options.debug) {
1882
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2094
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1883
2095
  }
1884
- ResultFormatter.unknown(decodeResult, message.text);
2096
+ decodeResult.remaining.text = message.text;
1885
2097
  decodeResult.decoded = false;
1886
2098
  decodeResult.decoder.decodeLevel = "none";
1887
2099
  return decodeResult;
1888
2100
  }
2101
+ const data = /* @__PURE__ */ new Map();
2102
+ data.set("LAT", parts[0].replaceAll(" ", ""));
2103
+ data.set("LON", parts[1].replaceAll(" ", ""));
2104
+ for (let i = 2; i < parts.length; i++) {
2105
+ const part = parts[i].split(" ");
2106
+ data.set(part[0], part.slice(1).join(" "));
2107
+ }
2108
+ const position = {
2109
+ latitude: Number(data.get("LAT")),
2110
+ longitude: Number(data.get("LON"))
2111
+ };
2112
+ data.delete("LAT");
2113
+ data.delete("LON");
2114
+ ResultFormatter.position(decodeResult, position);
2115
+ const utc = data.get("UTC");
2116
+ if (utc) {
2117
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(utc));
2118
+ data.delete("UTC");
2119
+ }
2120
+ const alt = data.get("ALT");
2121
+ if (alt) {
2122
+ ResultFormatter.altitude(decodeResult, Number(alt));
2123
+ data.delete("ALT");
2124
+ }
2125
+ const fob = data.get("FOB");
2126
+ if (fob) {
2127
+ ResultFormatter.currentFuel(decodeResult, Number(fob));
2128
+ data.delete("FOB");
2129
+ }
2130
+ const eta = data.get("ETA");
2131
+ if (eta) {
2132
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
2133
+ data.delete("ETA");
2134
+ }
2135
+ let remaining = "";
2136
+ for (const [key, value] of data.entries()) {
2137
+ remaining += `/${key} ${value}`;
2138
+ }
2139
+ decodeResult.remaining.text = remaining;
1889
2140
  decodeResult.decoded = true;
1890
- decodeResult.decoder.decodeLevel = "full";
2141
+ decodeResult.decoder.decodeLevel = "partial";
1891
2142
  return decodeResult;
1892
2143
  }
1893
2144
  };
1894
2145
 
1895
- // lib/plugins/Label_44_IN.ts
1896
- var Label_44_IN = class extends DecoderPlugin {
1897
- name = "label-44-in";
2146
+ // lib/plugins/Label_20_POS.ts
2147
+ var Label_20_POS = class extends DecoderPlugin {
2148
+ name = "label-20-pos";
1898
2149
  qualifiers() {
1899
2150
  return {
1900
- labels: ["44"],
1901
- preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
2151
+ labels: ["20"],
2152
+ preambles: ["POS"]
1902
2153
  };
1903
2154
  }
1904
2155
  decode(message, options = {}) {
1905
2156
  const decodeResult = this.defaultResult();
1906
2157
  decodeResult.decoder.name = this.name;
1907
- decodeResult.formatted.description = "In Air Report";
2158
+ decodeResult.formatted.description = "Position Report";
1908
2159
  decodeResult.message = message;
1909
- const data = message.text.split(",");
1910
- if (data.length >= 7) {
2160
+ decodeResult.raw.preamble = message.text.substring(0, 3);
2161
+ const content = message.text.substring(3);
2162
+ const fields = content.split(",");
2163
+ if (fields.length == 11) {
1911
2164
  if (options.debug) {
1912
- console.log(`Label 44 In Air Report: groups`);
1913
- console.log(data);
2165
+ console.log(`DEBUG: ${this.name}: Variation 1 detected`);
1914
2166
  }
1915
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
1916
- ResultFormatter.departureAirport(decodeResult, data[2]);
1917
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
1918
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
1919
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
1920
- ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
1921
- const fuel = Number(data[6]);
1922
- if (!isNaN(fuel)) {
1923
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2167
+ const rawCoords = fields[0];
2168
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(rawCoords));
2169
+ decodeResult.decoded = true;
2170
+ decodeResult.decoder.decodeLevel = "full";
2171
+ } else if (fields.length == 5) {
2172
+ if (options.debug) {
2173
+ console.log(`DEBUG: ${this.name}: Variation 2 detected`);
1924
2174
  }
1925
- if (data.length > 7) {
1926
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
2175
+ const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
2176
+ if (position) {
2177
+ ResultFormatter.position(decodeResult, position);
1927
2178
  }
2179
+ decodeResult.decoded = true;
2180
+ decodeResult.decoder.decodeLevel = "full";
1928
2181
  } else {
1929
2182
  if (options.debug) {
1930
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2183
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
1931
2184
  }
1932
- ResultFormatter.unknown(decodeResult, message.text);
1933
2185
  decodeResult.decoded = false;
1934
2186
  decodeResult.decoder.decodeLevel = "none";
1935
- return decodeResult;
1936
2187
  }
1937
- decodeResult.decoded = true;
1938
- decodeResult.decoder.decodeLevel = "full";
1939
2188
  return decodeResult;
1940
2189
  }
1941
2190
  };
1942
2191
 
1943
- // lib/plugins/Label_44_OFF.ts
1944
- var Label_44_OFF = class extends DecoderPlugin {
1945
- name = "label-44-off";
2192
+ // lib/plugins/Label_21_POS.ts
2193
+ var Label_21_POS = class extends DecoderPlugin {
2194
+ name = "label-21-pos";
1946
2195
  qualifiers() {
1947
2196
  return {
1948
- labels: ["44"],
1949
- preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
2197
+ labels: ["21"],
2198
+ preambles: ["POS"]
1950
2199
  };
1951
2200
  }
1952
2201
  decode(message, options = {}) {
1953
2202
  const decodeResult = this.defaultResult();
1954
2203
  decodeResult.decoder.name = this.name;
1955
- decodeResult.formatted.description = "Off Runway Report";
2204
+ decodeResult.formatted.description = "Position Report";
1956
2205
  decodeResult.message = message;
1957
- const data = message.text.split(",");
1958
- if (data.length >= 8) {
1959
- if (options.debug) {
1960
- console.log(`Label 44 Off Runway Report: groups`);
1961
- console.log(data);
1962
- }
1963
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
1964
- ResultFormatter.departureAirport(decodeResult, data[2]);
1965
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
1966
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
1967
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
1968
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
1969
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
1970
- const fuel = Number(data[7]);
1971
- if (!isNaN(fuel)) {
1972
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
1973
- }
1974
- if (data.length > 8) {
1975
- ResultFormatter.unknownArr(decodeResult, data.slice(8));
1976
- }
2206
+ decodeResult.raw.preamble = message.text.substring(0, 3);
2207
+ const content = message.text.substring(3);
2208
+ const fields = content.split(",");
2209
+ if (fields.length == 9) {
2210
+ processPosition(decodeResult, fields[0].trim());
2211
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
2212
+ ResultFormatter.altitude(decodeResult, Number(fields[3]));
2213
+ ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
2214
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[7]));
2215
+ ResultFormatter.arrivalAirport(decodeResult, fields[8]);
2216
+ ResultFormatter.unknownArr(decodeResult, [fields[1], fields[4], fields[5]]);
2217
+ decodeResult.decoded = true;
2218
+ decodeResult.decoder.decodeLevel = "partial";
1977
2219
  } else {
1978
2220
  if (options.debug) {
1979
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2221
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
1980
2222
  }
1981
- ResultFormatter.unknown(decodeResult, message.text);
1982
2223
  decodeResult.decoded = false;
1983
2224
  decodeResult.decoder.decodeLevel = "none";
1984
- return decodeResult;
1985
2225
  }
1986
- decodeResult.decoded = true;
1987
- decodeResult.decoder.decodeLevel = "full";
1988
2226
  return decodeResult;
1989
2227
  }
1990
2228
  };
2229
+ function processPosition(decodeResult, value) {
2230
+ if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
2231
+ return;
2232
+ }
2233
+ const latDir = value[0] === "N" ? 1 : -1;
2234
+ const lonDir = value[8] === "E" ? 1 : -1;
2235
+ const position = {
2236
+ latitude: latDir * Number(value.substring(1, 7)),
2237
+ longitude: lonDir * Number(value.substring(9, 15))
2238
+ };
2239
+ ResultFormatter.position(decodeResult, position);
2240
+ }
1991
2241
 
1992
- // lib/plugins/Label_44_ON.ts
1993
- var Label_44_ON = class extends DecoderPlugin {
1994
- name = "label-44-on";
2242
+ // lib/plugins/Label_22_OFF.ts
2243
+ var Label_22_OFF = class extends DecoderPlugin {
2244
+ name = "label-22-off";
1995
2245
  qualifiers() {
1996
2246
  return {
1997
- labels: ["44"],
1998
- preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
2247
+ labels: ["22"],
2248
+ preambles: ["OFF"]
1999
2249
  };
2000
2250
  }
2001
2251
  decode(message, options = {}) {
2002
2252
  const decodeResult = this.defaultResult();
2003
2253
  decodeResult.decoder.name = this.name;
2004
- decodeResult.formatted.description = "On Runway Report";
2254
+ decodeResult.formatted.description = "Takeoff Report";
2005
2255
  decodeResult.message = message;
2006
- const data = message.text.split(",");
2007
- if (data.length >= 7) {
2008
- if (options.debug) {
2009
- console.log(`Label 44 On Runway Report: groups`);
2010
- console.log(data);
2256
+ if (message.text.startsWith("OFF01")) {
2257
+ const fields = message.text.substring(5).split("/");
2258
+ if (fields.length != 2) {
2259
+ decodeResult.decoded = false;
2260
+ decodeResult.decoder.decodeLevel = "none";
2261
+ return decodeResult;
2011
2262
  }
2012
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2013
- ResultFormatter.departureAirport(decodeResult, data[2]);
2014
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
2015
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
2016
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
2017
- ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
2018
- const fuel = Number(data[6]);
2019
- if (!isNaN(fuel)) {
2020
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2263
+ ResultFormatter.flightNumber(decodeResult, fields[0]);
2264
+ ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
2265
+ ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
2266
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)));
2267
+ ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
2268
+ ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
2269
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
2270
+ ResultFormatter.unknown(decodeResult, fields[1].substring(22));
2271
+ decodeResult.decoded = true;
2272
+ decodeResult.decoder.decodeLevel = "partial";
2273
+ } else if (message.text.startsWith("OFF02\r\n")) {
2274
+ const fields = message.text.substring(7).split(",");
2275
+ if (fields.length != 4) {
2276
+ decodeResult.decoded = false;
2277
+ decodeResult.decoder.decodeLevel = "none";
2278
+ return decodeResult;
2021
2279
  }
2022
- if (data.length > 7) {
2023
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
2280
+ ResultFormatter.departureAirport(decodeResult, fields[0]);
2281
+ ResultFormatter.arrivalAirport(decodeResult, fields[1]);
2282
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
2283
+ ResultFormatter.unknown(decodeResult, fields[3]);
2284
+ decodeResult.decoded = true;
2285
+ decodeResult.decoder.decodeLevel = "partial";
2286
+ } else if (message.text.startsWith("OFF02")) {
2287
+ const fields = message.text.substring(5).split("/");
2288
+ if (fields.length != 2) {
2289
+ decodeResult.decoded = false;
2290
+ decodeResult.decoder.decodeLevel = "none";
2291
+ return decodeResult;
2024
2292
  }
2293
+ ResultFormatter.flightNumber(decodeResult, fields[0]);
2294
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(fields[1].substring(0, 14));
2295
+ if (position) {
2296
+ ResultFormatter.position(decodeResult, position);
2297
+ }
2298
+ ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
2299
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)));
2300
+ ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
2301
+ ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
2302
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)));
2303
+ ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
2304
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)));
2305
+ decodeResult.decoded = true;
2306
+ decodeResult.decoder.decodeLevel = "partial";
2025
2307
  } else {
2026
2308
  if (options.debug) {
2027
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2309
+ console.log(`DEBUG: ${this.name}: Unknown variation.`);
2028
2310
  }
2029
- ResultFormatter.unknown(decodeResult, message.text);
2030
2311
  decodeResult.decoded = false;
2031
2312
  decodeResult.decoder.decodeLevel = "none";
2032
- return decodeResult;
2033
2313
  }
2034
- decodeResult.decoded = true;
2035
- decodeResult.decoder.decodeLevel = "full";
2036
2314
  return decodeResult;
2037
2315
  }
2038
2316
  };
2039
2317
 
2040
- // lib/plugins/Label_44_POS.ts
2041
- var Label_44_POS = class extends DecoderPlugin {
2042
- name = "label-44-pos";
2318
+ // lib/plugins/Label_22_POS.ts
2319
+ var Label_22_POS = class extends DecoderPlugin {
2320
+ name = "label-22-pos";
2043
2321
  qualifiers() {
2044
2322
  return {
2045
- labels: ["44"],
2046
- preambles: ["00POS01", "00POS02", "00POS03", "POS01", "POS02", "POS03"]
2323
+ labels: ["22"],
2324
+ preambles: ["N", "S"]
2047
2325
  };
2048
2326
  }
2049
2327
  decode(message, options = {}) {
@@ -2051,701 +2329,740 @@ var Label_44_POS = class extends DecoderPlugin {
2051
2329
  decodeResult.decoder.name = this.name;
2052
2330
  decodeResult.formatted.description = "Position Report";
2053
2331
  decodeResult.message = message;
2054
- const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
2055
- const results = message.text.match(regex);
2056
- if (results?.groups) {
2332
+ const fields = message.text.split(",");
2333
+ if (fields.length !== 11) {
2057
2334
  if (options.debug) {
2058
- console.log(`Label 44 Position Report: groups`);
2059
- console.log(results.groups);
2060
- }
2061
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords));
2062
- const flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? 0 : Number(results.groups.flight_level_or_ground);
2063
- ResultFormatter.month(decodeResult, Number(results.groups.current_date.substring(0, 2)));
2064
- ResultFormatter.day(decodeResult, Number(results.groups.current_date.substring(2, 4)));
2065
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.current_time + "00"));
2066
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.eta_time + "00"));
2067
- if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
2068
- decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
2335
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`);
2069
2336
  }
2070
- ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
2071
- ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
2072
- ResultFormatter.altitude(decodeResult, flight_level * 100);
2337
+ decodeResult.decoded = false;
2338
+ decodeResult.decoder.decodeLevel = "none";
2339
+ return decodeResult;
2073
2340
  }
2341
+ const latStr = fields[0].substring(1, 8);
2342
+ const lonStr = fields[0].substring(9);
2343
+ const lat = Number(latStr) / 1e4;
2344
+ const lon = Number(lonStr) / 1e4;
2345
+ ResultFormatter.position(decodeResult, {
2346
+ latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
2347
+ longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
2348
+ });
2349
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
2350
+ ResultFormatter.altitude(decodeResult, Number(fields[3]));
2351
+ ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
2074
2352
  decodeResult.decoded = true;
2075
- decodeResult.decoder.decodeLevel = "full";
2353
+ decodeResult.decoder.decodeLevel = "partial";
2076
2354
  return decodeResult;
2077
2355
  }
2078
2356
  };
2079
2357
 
2080
- // lib/plugins/Label_4A.ts
2081
- var Label_4A = class extends DecoderPlugin {
2082
- name = "label-4a";
2358
+ // lib/plugins/Label_2P_FM3.ts
2359
+ var Label_2P_FM3 = class extends DecoderPlugin {
2360
+ name = "label-2p-fm3";
2083
2361
  qualifiers() {
2084
2362
  return {
2085
- labels: ["4A"]
2363
+ labels: ["2P"]
2086
2364
  };
2087
2365
  }
2088
2366
  decode(message, options = {}) {
2089
- const decodeResult = this.defaultResult();
2367
+ let decodeResult = this.defaultResult();
2090
2368
  decodeResult.decoder.name = this.name;
2369
+ decodeResult.formatted.description = "Flight Report";
2091
2370
  decodeResult.message = message;
2092
- decodeResult.formatted.description = "Latest New Format";
2093
- let text = message.text;
2094
- if (text.match(/^M\d{2}A\w{6}/)) {
2095
- ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
2096
- text = text.substring(10);
2097
- }
2098
- decodeResult.decoded = true;
2099
- const fields = text.split(",");
2100
- if (fields.length === 11) {
2101
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
2102
- ResultFormatter.tail(decodeResult, fields[2].replace(".", ""));
2103
- if (fields[3])
2104
- ResultFormatter.callsign(decodeResult, fields[3]);
2105
- ResultFormatter.departureAirport(decodeResult, fields[4]);
2106
- ResultFormatter.arrivalAirport(decodeResult, fields[5]);
2107
- ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
2108
- ResultFormatter.unknownArr(decodeResult, fields.slice(8));
2109
- } else if (fields.length === 6) {
2110
- if (fields[0].match(/^[NS]/)) {
2111
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13)));
2112
- let wp1 = {
2113
- name: fields[0].substring(13).trim(),
2114
- time: DateTimeUtils.convertHHMMSSToTod(fields[1].substring(0, 6)),
2115
- timeFormat: "tod"
2116
- };
2117
- ResultFormatter.altitude(decodeResult, Number(fields[1].substring(6, 9)) * 100);
2118
- let wp2 = {
2119
- name: fields[1].substring(9).trim(),
2120
- time: DateTimeUtils.convertHHMMSSToTod(fields[2]),
2121
- timeFormat: "tod"
2122
- };
2123
- ResultFormatter.route(decodeResult, { waypoints: [wp1, wp2] });
2124
- ResultFormatter.temperature(decodeResult, fields[3]);
2125
- ResultFormatter.unknownArr(decodeResult, fields.slice(4));
2371
+ const parts = message.text.split(",");
2372
+ if (parts.length === 7) {
2373
+ const header = parts[0].split("FM3 ");
2374
+ if (header.length == 0) {
2375
+ ResultFormatter.unknown(decodeResult, message.text);
2376
+ decodeResult.decoded = false;
2377
+ decodeResult.decoder.decodeLevel = "none";
2378
+ return decodeResult;
2379
+ }
2380
+ if (header[0].length > 0) {
2381
+ ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
2382
+ ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
2383
+ }
2384
+ console.log(header[1]);
2385
+ if (header[1].length === 4) {
2386
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
2126
2387
  } else {
2127
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
2128
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1]));
2129
- ResultFormatter.unknown(decodeResult, fields[2]);
2130
- ResultFormatter.altitude(decodeResult, Number(fields[3]));
2131
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates((fields[4] + fields[5]).replace(/[ \.]/g, "")));
2388
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
2389
+ }
2390
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[1]));
2391
+ const lat = parts[2].replaceAll(" ", "");
2392
+ const lon = parts[3].replaceAll(" ", "");
2393
+ if (lat[0] === "N" || lat[0] === "S") {
2394
+ ResultFormatter.position(decodeResult, {
2395
+ latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
2396
+ longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
2397
+ });
2398
+ } else {
2399
+ ResultFormatter.position(decodeResult, { latitude: Number(lat), longitude: Number(lon) });
2132
2400
  }
2401
+ ResultFormatter.altitude(decodeResult, Number(parts[4]));
2402
+ ResultFormatter.unknown(decodeResult, parts[5]);
2403
+ ResultFormatter.unknown(decodeResult, parts[6]);
2404
+ decodeResult.decoded = true;
2405
+ decodeResult.decoder.decodeLevel = "partial";
2133
2406
  } else {
2407
+ if (options.debug) {
2408
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
2409
+ }
2410
+ ResultFormatter.unknown(decodeResult, message.text);
2134
2411
  decodeResult.decoded = false;
2135
- ResultFormatter.unknown(decodeResult, text);
2136
- }
2137
- if (decodeResult.decoded) {
2138
- if (!decodeResult.remaining.text)
2139
- decodeResult.decoder.decodeLevel = "full";
2140
- else
2141
- decodeResult.decoder.decodeLevel = "partial";
2142
- } else {
2143
2412
  decodeResult.decoder.decodeLevel = "none";
2144
2413
  }
2145
2414
  return decodeResult;
2146
2415
  }
2147
2416
  };
2148
2417
 
2149
- // lib/plugins/Label_4A_01.ts
2150
- var Label_4A_01 = class extends DecoderPlugin {
2151
- name = "label-4a-01";
2418
+ // lib/plugins/Label_2P_FM4.ts
2419
+ var Label_2P_FM4 = class extends DecoderPlugin {
2420
+ name = "label-2p-fm4";
2152
2421
  qualifiers() {
2153
2422
  return {
2154
- labels: ["4A"],
2155
- preambles: ["01"]
2423
+ labels: ["2P"]
2156
2424
  };
2157
2425
  }
2158
2426
  decode(message, options = {}) {
2159
- const decodeResult = this.defaultResult();
2427
+ let decodeResult = this.defaultResult();
2160
2428
  decodeResult.decoder.name = this.name;
2429
+ decodeResult.formatted.description = "Flight Report";
2161
2430
  decodeResult.message = message;
2162
- decodeResult.formatted.description = "Latest New Format";
2163
- decodeResult.decoded = true;
2164
- let rgx = message.text.match(/^01([A-Z]{2})([A-Z]{2})\s*(\w+)\/(\d{6})([A-Z]{4})([A-Z]{4})\r\n([+-]\s*\d+)(\d{3}\.\d)([+-]\s*\d+\.\d)/);
2165
- if (rgx) {
2166
- ResultFormatter.state_change(decodeResult, rgx[1], rgx[2]);
2167
- ResultFormatter.callsign(decodeResult, rgx[3]);
2168
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(rgx[4] + "00"));
2169
- ResultFormatter.departureAirport(decodeResult, rgx[5]);
2170
- ResultFormatter.arrivalAirport(decodeResult, rgx[6]);
2171
- ResultFormatter.altitude(decodeResult, Number(rgx[7].replace(/ /g, "")));
2172
- ResultFormatter.unknown(decodeResult, rgx[8]);
2173
- ResultFormatter.temperature(decodeResult, rgx[9].replace(/ /g, ""));
2431
+ const parts = message.text.split(",");
2432
+ if (parts.length === 10) {
2433
+ const header = parts[0].split("FM4");
2434
+ if (header.length == 0) {
2435
+ ResultFormatter.unknown(decodeResult, message.text);
2436
+ decodeResult.decoded = false;
2437
+ decodeResult.decoder.decodeLevel = "none";
2438
+ return decodeResult;
2439
+ }
2440
+ if (header[0].length > 0) {
2441
+ ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
2442
+ ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
2443
+ }
2444
+ ResultFormatter.departureAirport(decodeResult, header[1]);
2445
+ ResultFormatter.arrivalAirport(decodeResult, parts[1]);
2446
+ ResultFormatter.day(decodeResult, Number(parts[2].substring(0, 2)));
2447
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2].substring(2)));
2448
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
2449
+ ResultFormatter.position(decodeResult, { latitude: Number(parts[4].replaceAll(" ", "")), longitude: Number(parts[5].replaceAll(" ", "")) });
2450
+ ResultFormatter.altitude(decodeResult, Number(parts[6]));
2451
+ ResultFormatter.heading(decodeResult, Number(parts[7]));
2452
+ ResultFormatter.unknown(decodeResult, parts[8]);
2453
+ ResultFormatter.unknown(decodeResult, parts[9]);
2454
+ decodeResult.decoded = true;
2455
+ decodeResult.decoder.decodeLevel = "partial";
2174
2456
  } else {
2175
- decodeResult.decoded = false;
2457
+ if (options.debug) {
2458
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
2459
+ }
2176
2460
  ResultFormatter.unknown(decodeResult, message.text);
2177
- }
2178
- if (decodeResult.decoded) {
2179
- if (!decodeResult.remaining.text)
2180
- decodeResult.decoder.decodeLevel = "full";
2181
- else
2182
- decodeResult.decoder.decodeLevel = "partial";
2183
- } else {
2461
+ decodeResult.decoded = false;
2184
2462
  decodeResult.decoder.decodeLevel = "none";
2185
2463
  }
2186
2464
  return decodeResult;
2187
2465
  }
2188
2466
  };
2189
2467
 
2190
- // lib/plugins/Label_4A_DIS.ts
2191
- var Label_4A_DIS = class extends DecoderPlugin {
2192
- name = "label-4a-dis";
2468
+ // lib/plugins/Label_2P_FM5.ts
2469
+ var Label_2P_FM5 = class extends DecoderPlugin {
2470
+ name = "label-2p-fm5";
2193
2471
  qualifiers() {
2194
2472
  return {
2195
- labels: ["4A"],
2196
- preambles: ["DIS"]
2473
+ labels: ["2P"]
2197
2474
  };
2198
2475
  }
2199
2476
  decode(message, options = {}) {
2200
- const decodeResult = this.defaultResult();
2477
+ let decodeResult = this.defaultResult();
2201
2478
  decodeResult.decoder.name = this.name;
2479
+ decodeResult.formatted.description = "Flight Report";
2202
2480
  decodeResult.message = message;
2203
- decodeResult.formatted.description = "Latest New Format";
2204
- decodeResult.decoded = true;
2205
- const fields = message.text.split(",");
2206
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(2) + "00"));
2207
- ResultFormatter.callsign(decodeResult, fields[2]);
2208
- ResultFormatter.freetext(decodeResult, fields.slice(3).join(""));
2209
- if (decodeResult.decoded) {
2210
- if (!decodeResult.remaining.text)
2211
- decodeResult.decoder.decodeLevel = "full";
2212
- else
2213
- decodeResult.decoder.decodeLevel = "partial";
2481
+ const parts = message.text.split(",");
2482
+ if (parts.length === 12) {
2483
+ const header = parts[0].split("FM5 ");
2484
+ if (header.length == 0) {
2485
+ ResultFormatter.unknown(decodeResult, message.text);
2486
+ decodeResult.decoded = false;
2487
+ decodeResult.decoder.decodeLevel = "none";
2488
+ return decodeResult;
2489
+ }
2490
+ ResultFormatter.departureAirport(decodeResult, header[1]);
2491
+ ResultFormatter.arrivalAirport(decodeResult, parts[1]);
2492
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
2493
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
2494
+ ResultFormatter.position(decodeResult, { latitude: Number(parts[4].replaceAll(" ", "")), longitude: Number(parts[5].replaceAll(" ", "")) });
2495
+ ResultFormatter.altitude(decodeResult, Number(parts[6]));
2496
+ ResultFormatter.unknown(decodeResult, parts[7]);
2497
+ ResultFormatter.unknown(decodeResult, parts[8]);
2498
+ ResultFormatter.unknown(decodeResult, parts[9]);
2499
+ ResultFormatter.flightNumber(decodeResult, parts[10].trim());
2500
+ ResultFormatter.unknown(decodeResult, parts[11]);
2501
+ decodeResult.decoded = true;
2502
+ decodeResult.decoder.decodeLevel = "partial";
2214
2503
  } else {
2504
+ if (options.debug) {
2505
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
2506
+ }
2507
+ ResultFormatter.unknown(decodeResult, message.text);
2508
+ decodeResult.decoded = false;
2215
2509
  decodeResult.decoder.decodeLevel = "none";
2216
2510
  }
2217
2511
  return decodeResult;
2218
2512
  }
2219
2513
  };
2220
2514
 
2221
- // lib/plugins/Label_4A_DOOR.ts
2222
- var Label_4A_DOOR = class extends DecoderPlugin {
2223
- name = "label-4a-door";
2515
+ // lib/plugins/Label_2P_POS.ts
2516
+ var Label_2P_POS = class extends DecoderPlugin {
2517
+ name = "label-2p-pos";
2224
2518
  qualifiers() {
2225
2519
  return {
2226
- labels: ["4A"],
2227
- preambles: ["DOOR"]
2520
+ labels: ["2P"]
2228
2521
  };
2229
2522
  }
2230
2523
  decode(message, options = {}) {
2231
- const decodeResult = this.defaultResult();
2524
+ let decodeResult = this.defaultResult();
2232
2525
  decodeResult.decoder.name = this.name;
2233
2526
  decodeResult.message = message;
2234
- decodeResult.formatted.description = "Latest New Format";
2235
- decodeResult.decoded = true;
2236
- const fields = message.text.split(" ");
2237
- if (fields.length === 3) {
2238
- ResultFormatter.door_event(decodeResult, fields[0].split("/")[1], fields[1]);
2239
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2] + "00"));
2240
- } else {
2241
- decodeResult.decoded = false;
2527
+ const msg = message.text.replace(/\n|\r/g, "");
2528
+ const decoded = H1Helper.decodeH1Message(decodeResult, msg);
2529
+ decodeResult.decoded = decoded;
2530
+ decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
2531
+ if (decodeResult.formatted.items.length === 0) {
2532
+ if (options.debug) {
2533
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
2534
+ }
2242
2535
  ResultFormatter.unknown(decodeResult, message.text);
2243
- }
2244
- if (decodeResult.decoded) {
2245
- if (!decodeResult.remaining.text)
2246
- decodeResult.decoder.decodeLevel = "full";
2247
- else
2248
- decodeResult.decoder.decodeLevel = "partial";
2249
- } else {
2536
+ decodeResult.decoded = false;
2250
2537
  decodeResult.decoder.decodeLevel = "none";
2251
2538
  }
2252
2539
  return decodeResult;
2253
2540
  }
2254
2541
  };
2255
2542
 
2256
- // lib/plugins/Label_4A_Slash_01.ts
2257
- var Label_4A_Slash_01 = class extends DecoderPlugin {
2258
- name = "label-4a-slash-01";
2543
+ // lib/plugins/Label_24_Slash.ts
2544
+ var Label_24_Slash = class extends DecoderPlugin {
2545
+ name = "label-24-slash";
2259
2546
  qualifiers() {
2260
2547
  return {
2261
- labels: ["4A"],
2262
- preambles: ["/01"]
2548
+ labels: ["24"],
2549
+ preambles: ["/"]
2263
2550
  };
2264
2551
  }
2265
2552
  decode(message, options = {}) {
2266
2553
  const decodeResult = this.defaultResult();
2267
2554
  decodeResult.decoder.name = this.name;
2555
+ decodeResult.formatted.description = "Position Report";
2268
2556
  decodeResult.message = message;
2269
- decodeResult.formatted.description = "Latest New Format";
2270
- decodeResult.decoded = true;
2271
- if (message.text.length === 5 && message.text.substring(0, 4) === "/01-") {
2272
- ResultFormatter.unknown(decodeResult, message.text.substring(4));
2273
- } else {
2274
- decodeResult.decoded = false;
2275
- ResultFormatter.unknown(decodeResult, message.text);
2276
- }
2277
- if (decodeResult.decoded) {
2278
- if (!decodeResult.remaining.text)
2279
- decodeResult.decoder.decodeLevel = "full";
2280
- else
2281
- decodeResult.decoder.decodeLevel = "partial";
2557
+ const fields = message.text.split("/");
2558
+ if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
2559
+ const mmddyy = fields[1].substring(4, 6) + fields[1].substring(2, 4) + fields[1].substring(0, 2);
2560
+ const hhmmss = fields[2] + "00";
2561
+ decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(hhmmss, mmddyy);
2562
+ ResultFormatter.flightNumber(decodeResult, fields[3]);
2563
+ ResultFormatter.altitude(decodeResult, Number(fields[4]));
2564
+ const lat = fields[5];
2565
+ const lon = fields[6];
2566
+ const position = {
2567
+ latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
2568
+ longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
2569
+ };
2570
+ ResultFormatter.position(decodeResult, position);
2571
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8]));
2572
+ ResultFormatter.unknown(decodeResult, fields[7]);
2573
+ decodeResult.decoded = true;
2574
+ decodeResult.decoder.decodeLevel = "partial";
2282
2575
  } else {
2576
+ if (options.debug) {
2577
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`);
2578
+ }
2579
+ decodeResult.decoded = false;
2283
2580
  decodeResult.decoder.decodeLevel = "none";
2284
2581
  }
2285
2582
  return decodeResult;
2286
2583
  }
2287
2584
  };
2288
2585
 
2289
- // lib/utils/flight_plan_utils.ts
2290
- var FlightPlanUtils = class _FlightPlanUtils {
2291
- /**
2292
- * Processes flight plan data
2293
- *
2294
- * Expected format is [header, key1, val1, ... keyN, valN]
2295
- *
2296
- * @param decodeResult - results
2297
- * @param data - original message split by ':'
2298
- * @returns whether all fields were processed or not
2299
- */
2300
- static processFlightPlan(decodeResult, data) {
2301
- let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
2302
- for (let i = 1; i < data.length; i += 2) {
2303
- const key = data[i];
2304
- const value = data[i + 1];
2305
- switch (key) {
2306
- case "A":
2307
- addProcedure(decodeResult, value, "arrival");
2308
- break;
2309
- case "AA":
2310
- addArrivalAirport(decodeResult, value);
2311
- break;
2312
- case "AP":
2313
- addProcedure(decodeResult, value, "approach");
2314
- break;
2315
- case "CR":
2316
- addCompanyRoute(decodeResult, value);
2317
- break;
2318
- case "D":
2319
- addProcedure(decodeResult, value, "departure");
2320
- break;
2321
- case "DA":
2322
- addDepartureAirport(decodeResult, value);
2323
- break;
2324
- case "F":
2325
- addRoute(decodeResult, value);
2326
- break;
2327
- case "R":
2328
- addRunway(decodeResult, value);
2329
- break;
2330
- // case 'WS': // something about routes, has altitude, so current parsing won't work
2331
- // break;
2332
- default:
2333
- if (allKnownFields) {
2334
- decodeResult.remaining.text = "";
2335
- allKnownFields = false;
2336
- }
2337
- decodeResult.remaining.text += `:${key}:${value}`;
2338
- decodeResult.decoder.decodeLevel = "partial";
2339
- }
2340
- }
2341
- return allKnownFields;
2586
+ // lib/plugins/Label_30_Slash_EA.ts
2587
+ var Label_30_Slash_EA = class extends DecoderPlugin {
2588
+ name = "label-30-slash-ea";
2589
+ qualifiers() {
2590
+ return {
2591
+ labels: ["30"],
2592
+ preambles: ["/EA"]
2593
+ };
2342
2594
  }
2343
- static parseHeader(decodeResult, header) {
2344
- let allKnownFields = true;
2345
- if (header.startsWith("RF")) {
2346
- decodeResult.formatted.items.push({
2347
- type: "status",
2348
- code: "ROUTE_STATUS",
2349
- label: "Route Status",
2350
- value: "Route Filed"
2351
- });
2352
- decodeResult.raw.route_status = "RF";
2353
- if (header.length > 2) {
2354
- addRoute(decodeResult, header.substring(2));
2595
+ decode(message, options = {}) {
2596
+ const decodeResult = this.defaultResult();
2597
+ decodeResult.decoder.name = this.name;
2598
+ decodeResult.formatted.description = "ETA Report";
2599
+ decodeResult.message = message;
2600
+ const results = message.text.split(/\n|\//).slice(1);
2601
+ if (results) {
2602
+ if (options.debug) {
2603
+ console.log(`Label 30 EA: results`);
2604
+ console.log(results);
2355
2605
  }
2356
- } else if (header.startsWith("RP")) {
2357
- decodeResult.raw.route_status = "RP";
2358
- decodeResult.formatted.items.push({
2359
- type: "status",
2360
- code: "ROUTE_STATUS",
2361
- label: "Route Status",
2362
- value: "Route Planned"
2363
- });
2364
- decodeResult.raw.route_status = header;
2365
- } else if (header.startsWith("RI")) {
2366
- decodeResult.raw.route_status = "RI";
2367
- decodeResult.formatted.items.push({
2368
- type: "status",
2369
- code: "ROUTE_STATUS",
2370
- label: "Route Status",
2371
- value: "Route Inactive"
2372
- });
2606
+ }
2607
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4)));
2608
+ if (results[1].substring(0, 2) === "DS") {
2609
+ ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
2610
+ ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
2373
2611
  } else {
2374
- decodeResult.remaining.text += header;
2375
- allKnownFields = false;
2612
+ ResultFormatter.unknown(decodeResult, "/".concat(results[1], "/", results[2]));
2376
2613
  }
2377
- return allKnownFields;
2614
+ decodeResult.decoded = true;
2615
+ decodeResult.decoder.decodeLevel = "partial";
2616
+ return decodeResult;
2378
2617
  }
2379
2618
  };
2380
- function addArrivalAirport(decodeResult, value) {
2381
- ResultFormatter.arrivalAirport(decodeResult, value);
2382
- }
2383
- function addDepartureAirport(decodeResult, value) {
2384
- ResultFormatter.departureAirport(decodeResult, value);
2385
- }
2386
- function addRunway(decodeResult, value) {
2387
- if (value.length === 8) {
2388
- ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
2389
- }
2390
- ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
2391
- }
2392
- function addRoute(decodeResult, value) {
2393
- const route = value.split(".");
2394
- ResultFormatter.route(decodeResult, { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) });
2395
- }
2396
- function addProcedure(decodeResult, value, type) {
2397
- if (decodeResult.raw.procedures === void 0) {
2398
- decodeResult.raw.procedures = [];
2399
- }
2400
- const data = value.split(".");
2401
- let waypoints;
2402
- if (data.length > 1) {
2403
- waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
2404
- }
2405
- const route = { name: data[0], waypoints };
2406
- decodeResult.raw.procedures.push({ type, route });
2407
- const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
2408
- let procedureValue = route.name;
2409
- decodeResult.formatted.items.push({
2410
- type: `procedure`,
2411
- code: "proc",
2412
- label: `${procedureName} Procedure`,
2413
- value: RouteUtils.routeToString(route)
2414
- });
2415
- }
2416
- function addCompanyRoute(decodeResult, value) {
2417
- const segments = value.split(".");
2418
- const parens_idx = segments[0].indexOf("(");
2419
- let name;
2420
- let runway;
2421
- if (parens_idx === -1) {
2422
- name = segments[0];
2423
- } else {
2424
- name = segments[0].slice(0, parens_idx);
2425
- runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
2426
- }
2427
- let waypoints;
2428
- if (segments.length > 1) {
2429
- waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
2430
- }
2431
- decodeResult.raw.company_route = {
2432
- name,
2433
- runway,
2434
- waypoints
2435
- };
2436
- decodeResult.formatted.items.push({
2437
- type: "company_route",
2438
- code: "CR",
2439
- label: "Company Route",
2440
- value: RouteUtils.routeToString(decodeResult.raw.company_route)
2441
- });
2442
- }
2443
2619
 
2444
- // lib/utils/h1_helper.ts
2445
- var H1Helper = class _H1Helper {
2446
- static decodeH1Message(decodeResult, message) {
2447
- const checksum = message.slice(-4);
2448
- const data = message.slice(0, message.length - 4);
2449
- const fields = data.split("/");
2450
- const canDecode = parseMessageType(decodeResult, fields[0]);
2451
- if (!canDecode) {
2620
+ // lib/plugins/Label_44_ETA.ts
2621
+ var Label_44_ETA = class extends DecoderPlugin {
2622
+ name = "label-44-eta";
2623
+ qualifiers() {
2624
+ return {
2625
+ labels: ["44"],
2626
+ preambles: ["00ETA01", "00ETA02", "00ETA03", "ETA01", "ETA02", "ETA03"]
2627
+ };
2628
+ }
2629
+ decode(message, options = {}) {
2630
+ const decodeResult = this.defaultResult();
2631
+ decodeResult.decoder.name = this.name;
2632
+ decodeResult.formatted.description = "ETA Report";
2633
+ decodeResult.message = message;
2634
+ const data = message.text.split(",");
2635
+ if (data.length >= 9) {
2636
+ if (options.debug) {
2637
+ console.log(`Label 44 ETA Report: groups`);
2638
+ console.log(data);
2639
+ }
2640
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2641
+ ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
2642
+ ResultFormatter.departureAirport(decodeResult, data[3]);
2643
+ ResultFormatter.arrivalAirport(decodeResult, data[4]);
2644
+ ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
2645
+ ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
2646
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
2647
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[7]));
2648
+ const fuel = Number(data[8]);
2649
+ if (!isNaN(fuel)) {
2650
+ ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2651
+ }
2652
+ if (data.length > 9) {
2653
+ ResultFormatter.unknownArr(decodeResult, data.slice(9));
2654
+ }
2655
+ } else {
2656
+ if (options.debug) {
2657
+ console.log(`Decoder: Unknown 44 message: ${message.text}`);
2658
+ }
2659
+ ResultFormatter.unknown(decodeResult, message.text);
2452
2660
  decodeResult.decoded = false;
2453
2661
  decodeResult.decoder.decodeLevel = "none";
2454
- return;
2455
- }
2456
- for (let i = 1; i < fields.length; ++i) {
2457
- if (fields[i].startsWith("FN")) {
2458
- decodeResult.raw.flight_number = fields[i].substring(2);
2459
- } else if (fields[i].startsWith("SN")) {
2460
- decodeResult.raw.serial_number = fields[i].substring(2);
2461
- } else if (fields[i].startsWith("DC")) {
2462
- processDC(decodeResult, fields[i].substring(2).split(","));
2463
- } else if (fields[i].startsWith("TS")) {
2464
- _H1Helper.processTS(decodeResult, fields[i].substring(2).split(","));
2465
- } else if (fields[i].startsWith("PS")) {
2466
- _H1Helper.processPS(decodeResult, fields[i].substring(2).split(","));
2467
- } else if (fields[i].startsWith("DT")) {
2468
- const data2 = fields[i].substring(2).split(",");
2469
- processDT(decodeResult, data2);
2470
- } else if (fields[i].startsWith("ID")) {
2471
- processIdentification(decodeResult, fields[i].substring(2).split(","));
2472
- } else if (fields[i].startsWith("LR")) {
2473
- const data2 = fields[i].substring(2).split(",");
2474
- processLR(decodeResult, data2);
2475
- } else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
2476
- FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
2477
- } else if (fields[i].startsWith("PR")) {
2478
- ResultFormatter.unknown(decodeResult, fields[i], "/");
2479
- } else if (fields[i].startsWith("AF")) {
2480
- processAirField(decodeResult, fields[i].substring(2).split(","));
2481
- } else if (fields[i].startsWith("TD")) {
2482
- processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
2483
- } else if (fields[i].startsWith("FX")) {
2484
- ResultFormatter.freetext(decodeResult, fields[i].substring(2));
2485
- } else if (fields[i].startsWith("ET")) {
2486
- if (fields[i].length === 7) {
2487
- ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 3)));
2488
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3)));
2489
- } else if (fields[i].length === 8) {
2490
- ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 4)));
2491
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4)));
2492
- } else {
2493
- ResultFormatter.unknown(decodeResult, fields[i], "/");
2494
- }
2495
- } else if (fields[i].startsWith("WD")) {
2496
- processWindData(decodeResult, fields[i].substring(2));
2497
- } else {
2498
- ResultFormatter.unknown(decodeResult, fields[i], "/");
2499
- }
2500
- }
2501
- if (decodeResult.formatted.items.length > 0) {
2502
- ResultFormatter.checksum(decodeResult, checksum);
2503
- }
2504
- return true;
2505
- }
2506
- static processPS(decodeResult, data) {
2507
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
2508
- if (position) {
2509
- decodeResult.raw.position = position;
2510
- decodeResult.formatted.items.push({
2511
- type: "aircraft_position",
2512
- code: "POS",
2513
- label: "Aircraft Position",
2514
- value: CoordinateUtils.coordinateString(position)
2515
- });
2516
- }
2517
- if (data.length === 9) {
2518
- processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
2519
- ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
2520
- ResultFormatter.temperature(decodeResult, data[6]);
2521
- ResultFormatter.unknown(decodeResult, data[7]);
2522
- ResultFormatter.unknown(decodeResult, data[8]);
2523
- }
2524
- if (data.length === 14) {
2525
- ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
2526
- processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
2527
- ResultFormatter.temperature(decodeResult, data[7]);
2528
- ResultFormatter.unknownArr(decodeResult, data.slice(8));
2662
+ return decodeResult;
2529
2663
  }
2664
+ decodeResult.decoded = true;
2665
+ decodeResult.decoder.decodeLevel = "full";
2666
+ return decodeResult;
2530
2667
  }
2531
- static processPosition(decodeResult, data) {
2532
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
2533
- if (position) {
2534
- ResultFormatter.position(decodeResult, position);
2535
- }
2536
- if (data.length >= 10) {
2537
- ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
2538
- processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
2539
- ResultFormatter.temperature(decodeResult, data[7]);
2540
- ResultFormatter.unknown(decodeResult, data[8]);
2541
- ResultFormatter.unknown(decodeResult, data[9]);
2542
- }
2543
- if (data.length >= 14) {
2544
- ResultFormatter.unknownArr(decodeResult, data.slice(10));
2545
- }
2668
+ };
2669
+
2670
+ // lib/plugins/Label_44_IN.ts
2671
+ var Label_44_IN = class extends DecoderPlugin {
2672
+ name = "label-44-in";
2673
+ qualifiers() {
2674
+ return {
2675
+ labels: ["44"],
2676
+ preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
2677
+ };
2546
2678
  }
2547
- static processTS(decodeResult, data) {
2548
- let time = DateTimeUtils.convertDateTimeToEpoch(data[0], data[1]);
2549
- if (Number.isNaN(time)) {
2550
- const date = data[1].substring(2, 4) + data[1].substring(0, 2) + data[1].substring(4, 6);
2551
- time = DateTimeUtils.convertDateTimeToEpoch(data[0], date);
2679
+ decode(message, options = {}) {
2680
+ const decodeResult = this.defaultResult();
2681
+ decodeResult.decoder.name = this.name;
2682
+ decodeResult.formatted.description = "In Air Report";
2683
+ decodeResult.message = message;
2684
+ const data = message.text.split(",");
2685
+ if (data.length >= 7) {
2686
+ if (options.debug) {
2687
+ console.log(`Label 44 In Air Report: groups`);
2688
+ console.log(data);
2689
+ }
2690
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2691
+ ResultFormatter.departureAirport(decodeResult, data[2]);
2692
+ ResultFormatter.arrivalAirport(decodeResult, data[3]);
2693
+ ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
2694
+ ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
2695
+ ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
2696
+ const fuel = Number(data[6]);
2697
+ if (!isNaN(fuel)) {
2698
+ ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2699
+ }
2700
+ if (data.length > 7) {
2701
+ ResultFormatter.unknownArr(decodeResult, data.slice(7));
2702
+ }
2703
+ } else {
2704
+ if (options.debug) {
2705
+ console.log(`Decoder: Unknown 44 message: ${message.text}`);
2706
+ }
2707
+ ResultFormatter.unknown(decodeResult, message.text);
2708
+ decodeResult.decoded = false;
2709
+ decodeResult.decoder.decodeLevel = "none";
2710
+ return decodeResult;
2552
2711
  }
2553
- decodeResult.raw.message_date = data[1];
2554
- decodeResult.raw.message_timestamp = time;
2712
+ decodeResult.decoded = true;
2713
+ decodeResult.decoder.decodeLevel = "full";
2714
+ return decodeResult;
2555
2715
  }
2556
2716
  };
2557
- function processAirField(decodeResult, data) {
2558
- if (data.length === 2) {
2559
- ResultFormatter.departureAirport(decodeResult, data[0]);
2560
- ResultFormatter.arrivalAirport(decodeResult, data[1]);
2561
- } else {
2562
- ResultFormatter.unknown(decodeResult, data.join(","), "AF/");
2563
- }
2564
- }
2565
- function processTimeOfDeparture(decodeResult, data) {
2566
- if (data.length === 2) {
2567
- decodeResult.raw.plannedDepartureTime = data[0];
2568
- decodeResult.formatted.items.push({
2569
- type: "ptd",
2570
- code: "ptd",
2571
- label: "Planned Departure Time",
2572
- value: `YYYY-MM-${data[0].substring(0, 2)}T${data[0].substring(2, 4)}:${data[0].substring(4)}:00Z`
2573
- });
2574
- decodeResult.raw.plannedDepartureTime = data[1];
2575
- decodeResult.formatted.items.push({
2576
- type: "etd",
2577
- code: "etd",
2578
- label: "Estimated Departure Time",
2579
- value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
2580
- });
2581
- } else {
2582
- ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
2583
- }
2584
- }
2585
- function processIdentification(decodeResult, data) {
2586
- ResultFormatter.tail(decodeResult, data[0]);
2587
- if (data.length > 1) {
2588
- decodeResult.raw.flight_number = data[1];
2717
+
2718
+ // lib/plugins/Label_44_OFF.ts
2719
+ var Label_44_OFF = class extends DecoderPlugin {
2720
+ name = "label-44-off";
2721
+ qualifiers() {
2722
+ return {
2723
+ labels: ["44"],
2724
+ preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
2725
+ };
2589
2726
  }
2590
- if (data.length > 2) {
2591
- decodeResult.raw.mission_number = data[2];
2727
+ decode(message, options = {}) {
2728
+ const decodeResult = this.defaultResult();
2729
+ decodeResult.decoder.name = this.name;
2730
+ decodeResult.formatted.description = "Off Runway Report";
2731
+ decodeResult.message = message;
2732
+ const data = message.text.split(",");
2733
+ if (data.length >= 8) {
2734
+ if (options.debug) {
2735
+ console.log(`Label 44 Off Runway Report: groups`);
2736
+ console.log(data);
2737
+ }
2738
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2739
+ ResultFormatter.departureAirport(decodeResult, data[2]);
2740
+ ResultFormatter.arrivalAirport(decodeResult, data[3]);
2741
+ ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
2742
+ ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
2743
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
2744
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
2745
+ const fuel = Number(data[7]);
2746
+ if (!isNaN(fuel)) {
2747
+ ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2748
+ }
2749
+ if (data.length > 8) {
2750
+ ResultFormatter.unknownArr(decodeResult, data.slice(8));
2751
+ }
2752
+ } else {
2753
+ if (options.debug) {
2754
+ console.log(`Decoder: Unknown 44 message: ${message.text}`);
2755
+ }
2756
+ ResultFormatter.unknown(decodeResult, message.text);
2757
+ decodeResult.decoded = false;
2758
+ decodeResult.decoder.decodeLevel = "none";
2759
+ return decodeResult;
2760
+ }
2761
+ decodeResult.decoded = true;
2762
+ decodeResult.decoder.decodeLevel = "full";
2763
+ return decodeResult;
2592
2764
  }
2593
- }
2594
- function processDT(decodeResult, data) {
2595
- if (!decodeResult.raw.arrival_icao) {
2596
- ResultFormatter.arrivalAirport(decodeResult, data[0]);
2597
- } else if (decodeResult.raw.arrival_icao != data[0]) {
2598
- ResultFormatter.unknownArr(decodeResult, data);
2765
+ };
2766
+
2767
+ // lib/plugins/Label_44_ON.ts
2768
+ var Label_44_ON = class extends DecoderPlugin {
2769
+ name = "label-44-on";
2770
+ qualifiers() {
2771
+ return {
2772
+ labels: ["44"],
2773
+ preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
2774
+ };
2599
2775
  }
2600
- if (data.length > 1) {
2601
- ResultFormatter.arrivalRunway(decodeResult, data[1]);
2776
+ decode(message, options = {}) {
2777
+ const decodeResult = this.defaultResult();
2778
+ decodeResult.decoder.name = this.name;
2779
+ decodeResult.formatted.description = "On Runway Report";
2780
+ decodeResult.message = message;
2781
+ const data = message.text.split(",");
2782
+ if (data.length >= 7) {
2783
+ if (options.debug) {
2784
+ console.log(`Label 44 On Runway Report: groups`);
2785
+ console.log(data);
2786
+ }
2787
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2788
+ ResultFormatter.departureAirport(decodeResult, data[2]);
2789
+ ResultFormatter.arrivalAirport(decodeResult, data[3]);
2790
+ ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
2791
+ ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
2792
+ ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
2793
+ const fuel = Number(data[6]);
2794
+ if (!isNaN(fuel)) {
2795
+ ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2796
+ }
2797
+ if (data.length > 7) {
2798
+ ResultFormatter.unknownArr(decodeResult, data.slice(7));
2799
+ }
2800
+ } else {
2801
+ if (options.debug) {
2802
+ console.log(`Decoder: Unknown 44 message: ${message.text}`);
2803
+ }
2804
+ ResultFormatter.unknown(decodeResult, message.text);
2805
+ decodeResult.decoded = false;
2806
+ decodeResult.decoder.decodeLevel = "none";
2807
+ return decodeResult;
2808
+ }
2809
+ decodeResult.decoded = true;
2810
+ decodeResult.decoder.decodeLevel = "full";
2811
+ return decodeResult;
2602
2812
  }
2603
- if (data.length > 2) {
2604
- ResultFormatter.currentFuel(decodeResult, Number(data[2]));
2813
+ };
2814
+
2815
+ // lib/plugins/Label_44_POS.ts
2816
+ var Label_44_POS = class extends DecoderPlugin {
2817
+ name = "label-44-pos";
2818
+ qualifiers() {
2819
+ return {
2820
+ labels: ["44"],
2821
+ preambles: ["00POS01", "00POS02", "00POS03", "POS01", "POS02", "POS03"]
2822
+ };
2605
2823
  }
2606
- if (data.length > 3) {
2607
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[3]));
2824
+ decode(message, options = {}) {
2825
+ const decodeResult = this.defaultResult();
2826
+ decodeResult.decoder.name = this.name;
2827
+ decodeResult.formatted.description = "Position Report";
2828
+ decodeResult.message = message;
2829
+ const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
2830
+ const results = message.text.match(regex);
2831
+ if (results?.groups) {
2832
+ if (options.debug) {
2833
+ console.log(`Label 44 Position Report: groups`);
2834
+ console.log(results.groups);
2835
+ }
2836
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords));
2837
+ const flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? 0 : Number(results.groups.flight_level_or_ground);
2838
+ ResultFormatter.month(decodeResult, Number(results.groups.current_date.substring(0, 2)));
2839
+ ResultFormatter.day(decodeResult, Number(results.groups.current_date.substring(2, 4)));
2840
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.current_time + "00"));
2841
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.eta_time + "00"));
2842
+ if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
2843
+ decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
2844
+ }
2845
+ ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
2846
+ ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
2847
+ ResultFormatter.altitude(decodeResult, flight_level * 100);
2848
+ }
2849
+ decodeResult.decoded = true;
2850
+ decodeResult.decoder.decodeLevel = "full";
2851
+ return decodeResult;
2608
2852
  }
2609
- if (data.length > 4) {
2610
- ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
2853
+ };
2854
+
2855
+ // lib/plugins/Label_4A.ts
2856
+ var Label_4A = class extends DecoderPlugin {
2857
+ name = "label-4a";
2858
+ qualifiers() {
2859
+ return {
2860
+ labels: ["4A"]
2861
+ };
2611
2862
  }
2612
- if (data.length > 5) {
2613
- ResultFormatter.unknownArr(decodeResult, data);
2863
+ decode(message, options = {}) {
2864
+ const decodeResult = this.defaultResult();
2865
+ decodeResult.decoder.name = this.name;
2866
+ decodeResult.message = message;
2867
+ decodeResult.formatted.description = "Latest New Format";
2868
+ let text = message.text;
2869
+ if (text.match(/^M\d{2}A\w{6}/)) {
2870
+ ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
2871
+ text = text.substring(10);
2872
+ }
2873
+ decodeResult.decoded = true;
2874
+ const fields = text.split(",");
2875
+ if (fields.length === 11) {
2876
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
2877
+ ResultFormatter.tail(decodeResult, fields[2].replace(".", ""));
2878
+ if (fields[3])
2879
+ ResultFormatter.callsign(decodeResult, fields[3]);
2880
+ ResultFormatter.departureAirport(decodeResult, fields[4]);
2881
+ ResultFormatter.arrivalAirport(decodeResult, fields[5]);
2882
+ const alt = text.substring(48, 51);
2883
+ if (alt !== "") {
2884
+ ResultFormatter.altitude(decodeResult, Number(alt) * 100);
2885
+ }
2886
+ ResultFormatter.unknownArr(decodeResult, fields.slice(8));
2887
+ } else if (fields.length === 6) {
2888
+ if (fields[0].match(/^[NS]/)) {
2889
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13)));
2890
+ let wp1 = {
2891
+ name: fields[0].substring(13).trim(),
2892
+ time: DateTimeUtils.convertHHMMSSToTod(fields[1].substring(0, 6)),
2893
+ timeFormat: "tod"
2894
+ };
2895
+ ResultFormatter.altitude(decodeResult, Number(fields[1].substring(6, 9)) * 100);
2896
+ let wp2 = {
2897
+ name: fields[1].substring(9).trim(),
2898
+ time: DateTimeUtils.convertHHMMSSToTod(fields[2]),
2899
+ timeFormat: "tod"
2900
+ };
2901
+ ResultFormatter.route(decodeResult, { waypoints: [wp1, wp2] });
2902
+ ResultFormatter.temperature(decodeResult, fields[3]);
2903
+ ResultFormatter.unknownArr(decodeResult, fields.slice(4));
2904
+ } else {
2905
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
2906
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1]));
2907
+ ResultFormatter.unknown(decodeResult, fields[2]);
2908
+ ResultFormatter.altitude(decodeResult, Number(fields[3]));
2909
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates((fields[4] + fields[5]).replace(/[ \.]/g, "")));
2910
+ }
2911
+ } else {
2912
+ decodeResult.decoded = false;
2913
+ ResultFormatter.unknown(decodeResult, text);
2914
+ }
2915
+ if (decodeResult.decoded) {
2916
+ if (!decodeResult.remaining.text)
2917
+ decodeResult.decoder.decodeLevel = "full";
2918
+ else
2919
+ decodeResult.decoder.decodeLevel = "partial";
2920
+ } else {
2921
+ decodeResult.decoder.decodeLevel = "none";
2922
+ }
2923
+ return decodeResult;
2614
2924
  }
2615
- }
2616
- function processLR(decodeResult, data) {
2617
- if (data.length === 19) {
2618
- ResultFormatter.unknown(decodeResult, data[1]);
2619
- ResultFormatter.flightNumber(decodeResult, data[2]);
2620
- ResultFormatter.departureAirport(decodeResult, data[3]);
2621
- ResultFormatter.arrivalAirport(decodeResult, data[4]);
2622
- ResultFormatter.arrivalRunway(decodeResult, data[5]);
2623
- ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
2624
- } else {
2625
- ResultFormatter.unknown(decodeResult, data.join(","));
2925
+ };
2926
+
2927
+ // lib/plugins/Label_4A_01.ts
2928
+ var Label_4A_01 = class extends DecoderPlugin {
2929
+ name = "label-4a-01";
2930
+ qualifiers() {
2931
+ return {
2932
+ labels: ["4A"],
2933
+ preambles: ["01"]
2934
+ };
2626
2935
  }
2627
- }
2628
- function parseMessageType(decodeResult, messageType) {
2629
- const parts = messageType.split("#");
2630
- if (parts.length == 1) {
2631
- const type = parts[0].substring(0, 3);
2632
- if (type === "POS" && parts[0].length !== 3) {
2633
- H1Helper.processPosition(decodeResult, parts[0].substring(3).split(","));
2936
+ decode(message, options = {}) {
2937
+ const decodeResult = this.defaultResult();
2938
+ decodeResult.decoder.name = this.name;
2939
+ decodeResult.message = message;
2940
+ decodeResult.formatted.description = "Latest New Format";
2941
+ decodeResult.decoded = true;
2942
+ let rgx = message.text.match(/^01([A-Z]{2})([A-Z]{2})\s*(\w+)\/(\d{6})([A-Z]{4})([A-Z]{4})\r\n([+-]\s*\d+)(\d{3}\.\d)([+-]\s*\d+\.\d)/);
2943
+ if (rgx) {
2944
+ ResultFormatter.state_change(decodeResult, rgx[1], rgx[2]);
2945
+ ResultFormatter.callsign(decodeResult, rgx[3]);
2946
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(rgx[4] + "00"));
2947
+ ResultFormatter.departureAirport(decodeResult, rgx[5]);
2948
+ ResultFormatter.arrivalAirport(decodeResult, rgx[6]);
2949
+ ResultFormatter.altitude(decodeResult, Number(rgx[7].replace(/ /g, "")));
2950
+ ResultFormatter.unknown(decodeResult, rgx[8]);
2951
+ ResultFormatter.temperature(decodeResult, rgx[9].replace(/ /g, ""));
2952
+ } else {
2953
+ decodeResult.decoded = false;
2954
+ ResultFormatter.unknown(decodeResult, message.text);
2634
2955
  }
2635
- return processMessageType(decodeResult, type);
2636
- } else if (parts.length == 2) {
2637
- if (parts[0].length > 0) {
2638
- ResultFormatter.unknown(decodeResult, parts[0].substring(0, 3));
2639
- decodeResult.raw.flight_number = parts[0].substring(3);
2640
- ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
2956
+ if (decodeResult.decoded) {
2957
+ if (!decodeResult.remaining.text)
2958
+ decodeResult.decoder.decodeLevel = "full";
2959
+ else
2960
+ decodeResult.decoder.decodeLevel = "partial";
2961
+ } else {
2962
+ decodeResult.decoder.decodeLevel = "none";
2641
2963
  }
2642
- const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
2643
- if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
2644
- H1Helper.processPosition(decodeResult, parts[1].substring(6).split(","));
2964
+ return decodeResult;
2965
+ }
2966
+ };
2967
+
2968
+ // lib/plugins/Label_4A_DIS.ts
2969
+ var Label_4A_DIS = class extends DecoderPlugin {
2970
+ name = "label-4a-dis";
2971
+ qualifiers() {
2972
+ return {
2973
+ labels: ["4A"],
2974
+ preambles: ["DIS"]
2975
+ };
2976
+ }
2977
+ decode(message, options = {}) {
2978
+ const decodeResult = this.defaultResult();
2979
+ decodeResult.decoder.name = this.name;
2980
+ decodeResult.message = message;
2981
+ decodeResult.formatted.description = "Latest New Format";
2982
+ decodeResult.decoded = true;
2983
+ const fields = message.text.split(",");
2984
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(2) + "00"));
2985
+ ResultFormatter.callsign(decodeResult, fields[2]);
2986
+ ResultFormatter.freetext(decodeResult, fields.slice(3).join(""));
2987
+ if (decodeResult.decoded) {
2988
+ if (!decodeResult.remaining.text)
2989
+ decodeResult.decoder.decodeLevel = "full";
2990
+ else
2991
+ decodeResult.decoder.decodeLevel = "partial";
2992
+ } else {
2993
+ decodeResult.decoder.decodeLevel = "none";
2645
2994
  }
2646
- return processMessageType(decodeResult, type);
2647
- } else {
2648
- ResultFormatter.unknown(decodeResult, messageType);
2649
- return false;
2995
+ return decodeResult;
2650
2996
  }
2651
- }
2652
- function processMessageType(decodeResult, type) {
2653
- if (type === "FPN") {
2654
- decodeResult.formatted.description = "Flight Plan";
2655
- } else if (type === "FTX") {
2656
- decodeResult.formatted.description = "Free Text";
2657
- } else if (type === "INI") {
2658
- decodeResult.formatted.description = "Flight Plan Initial Report";
2659
- } else if (type === "POS") {
2660
- decodeResult.formatted.description = "Position Report";
2661
- } else if (type === "PRG") {
2662
- decodeResult.formatted.description = "Progress Report";
2663
- } else if (type === "PWI") {
2664
- decodeResult.formatted.description = "Weather Report";
2665
- } else {
2666
- decodeResult.formatted.description = "Unknown H1 Message";
2667
- return false;
2997
+ };
2998
+
2999
+ // lib/plugins/Label_4A_DOOR.ts
3000
+ var Label_4A_DOOR = class extends DecoderPlugin {
3001
+ name = "label-4a-door";
3002
+ qualifiers() {
3003
+ return {
3004
+ labels: ["4A"],
3005
+ preambles: ["DOOR"]
3006
+ };
2668
3007
  }
2669
- return true;
2670
- }
2671
- function processDC(decodeResult, data) {
2672
- decodeResult.raw.message_date = data[0];
2673
- if (data.length === 1) {
2674
- } else if (data.length === 2) {
2675
- const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
2676
- const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
2677
- decodeResult.raw.message_timestamp = time;
3008
+ decode(message, options = {}) {
3009
+ const decodeResult = this.defaultResult();
3010
+ decodeResult.decoder.name = this.name;
3011
+ decodeResult.message = message;
3012
+ decodeResult.formatted.description = "Latest New Format";
3013
+ decodeResult.decoded = true;
3014
+ const fields = message.text.split(" ");
3015
+ if (fields.length === 3) {
3016
+ ResultFormatter.door_event(decodeResult, fields[0].split("/")[1], fields[1]);
3017
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2] + "00"));
3018
+ } else {
3019
+ decodeResult.decoded = false;
3020
+ ResultFormatter.unknown(decodeResult, message.text);
3021
+ }
3022
+ if (decodeResult.decoded) {
3023
+ if (!decodeResult.remaining.text)
3024
+ decodeResult.decoder.decodeLevel = "full";
3025
+ else
3026
+ decodeResult.decoder.decodeLevel = "partial";
3027
+ } else {
3028
+ decodeResult.decoder.decodeLevel = "none";
3029
+ }
3030
+ return decodeResult;
2678
3031
  }
2679
- }
2680
- function processRoute(decodeResult, last, time, next, eta, then, date) {
2681
- const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
2682
- const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
2683
- const timeFormat = date ? "epoch" : "tod";
2684
- const lastWaypoint = RouteUtils.getWaypoint(last);
2685
- lastWaypoint.time = lastTime;
2686
- lastWaypoint.timeFormat = timeFormat;
2687
- const nextWaypoint = RouteUtils.getWaypoint(next);
2688
- nextWaypoint.time = nextTime;
2689
- nextWaypoint.timeFormat = timeFormat;
2690
- const thenWaypoint = RouteUtils.getWaypoint(then || "?");
2691
- const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
2692
- decodeResult.raw.route = { waypoints };
2693
- decodeResult.formatted.items.push({
2694
- type: "aircraft_route",
2695
- code: "ROUTE",
2696
- label: "Aircraft Route",
2697
- value: RouteUtils.routeToString(decodeResult.raw.route)
2698
- });
2699
- }
2700
- function processWindData(decodeResult, message) {
2701
- if (decodeResult.raw.wind_data === void 0) {
2702
- decodeResult.raw.wind_data = [];
3032
+ };
3033
+
3034
+ // lib/plugins/Label_4A_Slash_01.ts
3035
+ var Label_4A_Slash_01 = class extends DecoderPlugin {
3036
+ name = "label-4a-slash-01";
3037
+ qualifiers() {
3038
+ return {
3039
+ labels: ["4A"],
3040
+ preambles: ["/01"]
3041
+ };
2703
3042
  }
2704
- const flightLevel = Number(message.slice(0, 3));
2705
- const fields = message.slice(4).split(".");
2706
- fields.forEach((field) => {
2707
- const data = field.split(",");
2708
- const waypoint = data[0];
2709
- const windData = data[1];
2710
- const windDirection = Number(windData.slice(0, 3));
2711
- const windSpeed = Number(windData.slice(3));
2712
- if (data.length === 3) {
2713
- const tempData = data[2];
2714
- const tempFlightLevel = Number(tempData.slice(0, 3));
2715
- const tempString = tempData.slice(3);
2716
- const tempDegrees = Number(tempString.substring(1)) * (tempString.charAt(0) === "M" ? -1 : 1);
2717
- decodeResult.raw.wind_data.push({
2718
- waypoint,
2719
- flightLevel,
2720
- windDirection,
2721
- windSpeed,
2722
- temperature: {
2723
- flightLevel: tempFlightLevel,
2724
- degreesC: tempDegrees
2725
- }
2726
- });
2727
- decodeResult.formatted.items.push({
2728
- type: "wind_data",
2729
- code: "WIND",
2730
- label: "Wind Data",
2731
- value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt, ${tempDegrees}\xB0C at FL${tempFlightLevel}`
2732
- });
3043
+ decode(message, options = {}) {
3044
+ const decodeResult = this.defaultResult();
3045
+ decodeResult.decoder.name = this.name;
3046
+ decodeResult.message = message;
3047
+ decodeResult.formatted.description = "Latest New Format";
3048
+ decodeResult.decoded = true;
3049
+ if (message.text.length === 5 && message.text.substring(0, 4) === "/01-") {
3050
+ ResultFormatter.unknown(decodeResult, message.text.substring(4));
2733
3051
  } else {
2734
- decodeResult.raw.wind_data.push({
2735
- waypoint,
2736
- flightLevel,
2737
- windDirection,
2738
- windSpeed
2739
- });
2740
- decodeResult.formatted.items.push({
2741
- type: "wind_data",
2742
- code: "WIND",
2743
- label: "Wind Data",
2744
- value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt`
2745
- });
3052
+ decodeResult.decoded = false;
3053
+ ResultFormatter.unknown(decodeResult, message.text);
2746
3054
  }
2747
- });
2748
- }
3055
+ if (decodeResult.decoded) {
3056
+ if (!decodeResult.remaining.text)
3057
+ decodeResult.decoder.decodeLevel = "full";
3058
+ else
3059
+ decodeResult.decoder.decodeLevel = "partial";
3060
+ } else {
3061
+ decodeResult.decoder.decodeLevel = "none";
3062
+ }
3063
+ return decodeResult;
3064
+ }
3065
+ };
2749
3066
 
2750
3067
  // lib/plugins/Label_4J_POS.ts
2751
3068
  var Label_4J_POS = class extends DecoderPlugin {
@@ -4640,6 +4957,9 @@ var MessageDecoder = class {
4640
4957
  this.registerPlugin(new Label_15(this));
4641
4958
  this.registerPlugin(new Label_15_FST(this));
4642
4959
  this.registerPlugin(new Label_16_N_Space(this));
4960
+ this.registerPlugin(new Label_16_POSA1(this));
4961
+ this.registerPlugin(new Label_16_TOD(this));
4962
+ this.registerPlugin(new Label_1J_2J_FTX(this));
4643
4963
  this.registerPlugin(new Label_1L_3Line(this));
4644
4964
  this.registerPlugin(new Label_1L_070(this));
4645
4965
  this.registerPlugin(new Label_1L_660(this));
@@ -4649,6 +4969,10 @@ var MessageDecoder = class {
4649
4969
  this.registerPlugin(new Label_22_OFF(this));
4650
4970
  this.registerPlugin(new Label_22_POS(this));
4651
4971
  this.registerPlugin(new Label_24_Slash(this));
4972
+ this.registerPlugin(new Label_2P_FM3(this));
4973
+ this.registerPlugin(new Label_2P_FM4(this));
4974
+ this.registerPlugin(new Label_2P_FM5(this));
4975
+ this.registerPlugin(new Label_2P_POS(this));
4652
4976
  this.registerPlugin(new Label_30_Slash_EA(this));
4653
4977
  this.registerPlugin(new Label_44_ETA(this));
4654
4978
  this.registerPlugin(new Label_44_IN(this));