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