@airframes/acars-decoder 1.6.12 → 1.6.13

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
@@ -129,7 +129,7 @@ var DecoderPlugin = class {
129
129
  };
130
130
 
131
131
  // lib/utils/coordinate_utils.ts
132
- var CoordinateUtils = class {
132
+ var CoordinateUtils = class _CoordinateUtils {
133
133
  /**
134
134
  * Decode a string of coordinates into an object with latitude and longitude in millidegrees
135
135
  * @param stringCoords - The string of coordinates to decode
@@ -146,8 +146,8 @@ var CoordinateUtils = class {
146
146
  longitudeChars = stringCoords.substring(8, 14);
147
147
  }
148
148
  if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
149
- results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * (firstChar === "S" ? -1 : 1);
150
- results.longitude = Number(longitudeChars) / 1e3 * (middleChar === "W" ? -1 : 1);
149
+ results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * _CoordinateUtils.getDirection(firstChar);
150
+ results.longitude = Number(longitudeChars) / 1e3 * _CoordinateUtils.getDirection(middleChar);
151
151
  } else {
152
152
  return;
153
153
  }
@@ -173,8 +173,8 @@ var CoordinateUtils = class {
173
173
  const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
174
174
  const lonMin = Number(longitudeChars) % 1e3 / 10;
175
175
  if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
176
- results.latitude = (latDeg + latMin / 60) * (firstChar === "S" ? -1 : 1);
177
- results.longitude = (lonDeg + lonMin / 60) * (middleChar === "W" ? -1 : 1);
176
+ results.latitude = (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar);
177
+ results.longitude = (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar);
178
178
  } else {
179
179
  return;
180
180
  }
@@ -281,6 +281,15 @@ var RouteUtils = class _RouteUtils {
281
281
 
282
282
  // lib/utils/result_formatter.ts
283
283
  var ResultFormatter = class {
284
+ static route(decodeResult, route) {
285
+ decodeResult.raw.route = route;
286
+ decodeResult.formatted.items.push({
287
+ type: "aircraft_route",
288
+ code: "ROUTE",
289
+ label: "Aircraft Route",
290
+ value: RouteUtils.routeToString(route)
291
+ });
292
+ }
284
293
  static state_change(decodeResult, from, to) {
285
294
  decodeResult.raw.state_change = {
286
295
  from,
@@ -317,6 +326,9 @@ var ResultFormatter = class {
317
326
  });
318
327
  }
319
328
  static position(decodeResult, value) {
329
+ if (!value || isNaN(value.latitude) || isNaN(value.longitude)) {
330
+ return;
331
+ }
320
332
  decodeResult.raw.position = value;
321
333
  decodeResult.formatted.items.push({
322
334
  type: "aircraft_position",
@@ -553,17 +565,50 @@ var ResultFormatter = class {
553
565
  value: DateTimeUtils.timestampToString(time, "tod")
554
566
  });
555
567
  }
556
- static text(decodeResult, text2) {
557
- decodeResult.raw.text = text2;
568
+ static day(decodeResult, day) {
569
+ decodeResult.raw.day_of_month = day;
570
+ decodeResult.formatted.items.push({
571
+ type: "day_of_month",
572
+ code: "MSG_DAY",
573
+ label: "Day of Month",
574
+ value: `${day}`
575
+ });
576
+ }
577
+ static departureDay(decodeResult, day) {
578
+ decodeResult.raw.departure_day_of_month = day;
579
+ decodeResult.formatted.items.push({
580
+ type: "day_of_month",
581
+ code: "DEP_DAY",
582
+ label: "Departure Day",
583
+ value: `${day}`
584
+ });
585
+ }
586
+ static arrivalDay(decodeResult, day) {
587
+ decodeResult.raw.arrival_day_of_month = day;
588
+ decodeResult.formatted.items.push({
589
+ type: "day_of_month",
590
+ code: "ARR_DAY",
591
+ label: "Arrival Day",
592
+ value: `${day}`
593
+ });
594
+ }
595
+ static text(decodeResult, text) {
596
+ decodeResult.raw.text = text;
558
597
  decodeResult.formatted.items.push({
559
598
  type: "text",
560
599
  code: "TEXT",
561
600
  label: "Text Message",
562
- value: text2
601
+ value: text
563
602
  });
564
603
  }
565
- static unknown(decodeResult, value) {
566
- decodeResult.remaining.text += "," + value;
604
+ static unknown(decodeResult, value, sep = ",") {
605
+ if (!decodeResult.remaining.text)
606
+ decodeResult.remaining.text = value;
607
+ else
608
+ decodeResult.remaining.text += sep + value;
609
+ }
610
+ static unknownArr(decodeResult, value, sep = ",") {
611
+ this.unknown(decodeResult, value.join(sep), sep);
567
612
  }
568
613
  };
569
614
 
@@ -639,14 +684,14 @@ var Label_5Z_Slash = class extends DecoderPlugin {
639
684
  decodeResult.raw.day_of_month = Number(info[3]);
640
685
  ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
641
686
  ResultFormatter.arrivalRunway(decodeResult, info[5].slice(1));
642
- decodeResult.remaining.text = data.slice(3).join("/");
687
+ ResultFormatter.unknownArr(decodeResult, data.slice(3), "/");
643
688
  } else if (type === "B3") {
644
689
  ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
645
690
  ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
646
691
  decodeResult.raw.day_of_month = Number(header[2]);
647
692
  ResultFormatter.arrivalRunway(decodeResult, header[3].slice(1));
648
693
  if (header.length > 4) {
649
- decodeResult.remaining.text = header.slice(4).join(" ");
694
+ ResultFormatter.unknownArr(decodeResult, header.slice(4), "/");
650
695
  }
651
696
  } else if (type === "C3" && data[1] === "C3 GATE REQ ") {
652
697
  const info = data[2].split(" ");
@@ -654,7 +699,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
654
699
  ResultFormatter.arrivalAirport(decodeResult, info[2]);
655
700
  decodeResult.raw.day_of_month = Number(info[3]);
656
701
  ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
657
- decodeResult.remaining.text = info.slice(5).join(" ");
702
+ ResultFormatter.unknownArr(decodeResult, info.slice(5), " ");
658
703
  } else if (type === "C3") {
659
704
  ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
660
705
  ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
@@ -666,7 +711,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
666
711
  ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(airports[4]));
667
712
  const estimates = data[3].split(" ");
668
713
  ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(estimates[1] + "00"));
669
- decodeResult.remaining.text = estimates[2];
714
+ ResultFormatter.unknown(decodeResult, estimates[2]);
670
715
  } else {
671
716
  if (options.debug) {
672
717
  console.log(`Decoder: Unkown 5Z RDC format: ${message.text}`);
@@ -678,7 +723,7 @@ var Label_5Z_Slash = class extends DecoderPlugin {
678
723
  if (options.debug) {
679
724
  console.log(`Decoder: Unknown 5Z message: ${message.text}`);
680
725
  }
681
- decodeResult.remaining.text = message.text;
726
+ ResultFormatter.unknown(decodeResult, message.text);
682
727
  decodeResult.decoded = false;
683
728
  decodeResult.decoder.decodeLevel = "none";
684
729
  }
@@ -706,7 +751,7 @@ var Label_10_LDR = class extends DecoderPlugin {
706
751
  if (options.debug) {
707
752
  console.log(`Decoder: Unknown 10 message: ${message.text}`);
708
753
  }
709
- decodeResult.remaining.text = message.text;
754
+ ResultFormatter.unknown(decodeResult, message.text);
710
755
  decodeResult.decoded = false;
711
756
  decodeResult.decoder.decodeLevel = "none";
712
757
  return decodeResult;
@@ -727,7 +772,7 @@ var Label_10_LDR = class extends DecoderPlugin {
727
772
  if (altRwy != "") {
728
773
  ResultFormatter.alternateRunway(decodeResult, altRwy);
729
774
  }
730
- decodeResult.remaining.text = [...parts.slice(0, 5), ...parts.slice(15)].join(",");
775
+ ResultFormatter.unknownArr(decodeResult, [...parts.slice(0, 5), ...parts.slice(15)]);
731
776
  decodeResult.decoded = true;
732
777
  decodeResult.decoder.decodeLevel = "partial";
733
778
  return decodeResult;
@@ -754,7 +799,7 @@ var Label_10_POS = class extends DecoderPlugin {
754
799
  if (options.debug) {
755
800
  console.log(`Decoder: Unknown 10 message: ${message.text}`);
756
801
  }
757
- decodeResult.remaining.text = message.text;
802
+ ResultFormatter.unknown(decodeResult, message.text);
758
803
  decodeResult.decoded = false;
759
804
  decodeResult.decoder.decodeLevel = "none";
760
805
  return decodeResult;
@@ -767,7 +812,7 @@ var Label_10_POS = class extends DecoderPlugin {
767
812
  };
768
813
  ResultFormatter.position(decodeResult, position);
769
814
  ResultFormatter.altitude(decodeResult, Number(parts[7]));
770
- decodeResult.remaining.text = [parts[0], ...parts.slice(3, 7), ...parts.slice(8)].join(",");
815
+ ResultFormatter.unknownArr(decodeResult, [parts[0], ...parts.slice(3, 7), ...parts.slice(8)]);
771
816
  decodeResult.decoded = true;
772
817
  decodeResult.decoder.decodeLevel = "partial";
773
818
  return decodeResult;
@@ -794,7 +839,7 @@ var Label_10_Slash = class extends DecoderPlugin {
794
839
  if (options.debug) {
795
840
  console.log(`Decoder: Unknown 10 message: ${message.text}`);
796
841
  }
797
- decodeResult.remaining.text = message.text;
842
+ ResultFormatter.unknown(decodeResult, message.text);
798
843
  decodeResult.decoded = false;
799
844
  decodeResult.decoder.decodeLevel = "none";
800
845
  return decodeResult;
@@ -821,17 +866,11 @@ var Label_10_Slash = class extends DecoderPlugin {
821
866
  time: DateTimeUtils.convertHHMMSSToTod(parts[15] + "00"),
822
867
  timeFormat: "tod"
823
868
  }];
824
- decodeResult.raw.route = { waypoints };
825
- decodeResult.formatted.items.push({
826
- type: "aircraft_route",
827
- code: "ROUTE",
828
- label: "Aircraft Route",
829
- value: RouteUtils.routeToString(decodeResult.raw.route)
830
- });
869
+ ResultFormatter.route(decodeResult, { waypoints });
831
870
  if (parts[16]) {
832
871
  ResultFormatter.departureAirport(decodeResult, parts[16]);
833
872
  }
834
- decodeResult.remaining.text = [parts[3], parts[4], ...parts.slice(9, 11), ...parts.slice(17)].join("/");
873
+ ResultFormatter.unknownArr(decodeResult, [parts[3], parts[4], ...parts.slice(9, 11), ...parts.slice(17)], "/");
835
874
  decodeResult.decoded = true;
836
875
  decodeResult.decoder.decodeLevel = "partial";
837
876
  return decodeResult;
@@ -853,35 +892,29 @@ var Label_12_N_Space = class extends DecoderPlugin {
853
892
  decodeResult.formatted.description = "Position Report";
854
893
  decodeResult.message = message;
855
894
  const variant1Regex = /^(?<lat>[NS])\s(?<lat_coord>.*),(?<long>[EW])\s*(?<long_coord>.*),(?<alt>.*),(?<unkwn1>.*),\s*(?<unkwn2>.*),.(?<airframe>.*),(?<unkwn3>.*)$/;
856
- let results;
857
- if (results = message.text.match(variant1Regex)) {
895
+ let results = message.text.match(variant1Regex);
896
+ if (results?.groups) {
858
897
  if (options.debug) {
859
898
  console.log(`Label 12 N : results`);
860
899
  console.log(results);
861
900
  }
862
- decodeResult.raw.position = {
901
+ ResultFormatter.position(decodeResult, {
863
902
  latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
864
903
  longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
865
- };
866
- const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
867
- decodeResult.formatted.items.push({
868
- type: "aircraft_position",
869
- code: "POS",
870
- label: "Aircraft Position",
871
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
872
904
  });
905
+ const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
873
906
  ResultFormatter.altitude(decodeResult, altitude);
874
- decodeResult.remaining.text = `,${results.groups.unkwn1} ,${results.groups.unkwn2}, ${results.groups.unkwn3}`;
907
+ ResultFormatter.unknownArr(decodeResult, [results.groups.unkwn1, results.groups.unkwn2, results.groups.unkwn3]);
875
908
  decodeResult.decoded = true;
876
909
  decodeResult.decoder.decodeLevel = "partial";
877
- } else {
878
- if (options.debug) {
879
- console.log(`Decoder: Unknown 12 message: ${message.text}`);
880
- }
881
- decodeResult.remaining.text = message.text;
882
- decodeResult.decoded = false;
883
- decodeResult.decoder.decodeLevel = "none";
910
+ return decodeResult;
884
911
  }
912
+ if (options.debug) {
913
+ console.log(`Decoder: Unknown 12 message: ${message.text}`);
914
+ }
915
+ ResultFormatter.unknown(decodeResult, message.text);
916
+ decodeResult.decoded = false;
917
+ decodeResult.decoder.decodeLevel = "none";
885
918
  return decodeResult;
886
919
  }
887
920
  };
@@ -908,12 +941,11 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
908
941
  if (options?.debug) {
909
942
  console.log(`Decoder: Unknown OOOI message: ${message.text}`);
910
943
  }
911
- decodeResult.remaining.text = message.text;
944
+ ResultFormatter.unknown(decodeResult, message.text);
912
945
  decodeResult.decoded = false;
913
946
  decodeResult.decoder.decodeLevel = "none";
914
947
  return decodeResult;
915
948
  }
916
- decodeResult.remaining.text = "";
917
949
  const data = parts[2].split(" ");
918
950
  ResultFormatter.departureAirport(decodeResult, data[1]);
919
951
  ResultFormatter.arrivalAirport(decodeResult, data[2]);
@@ -929,7 +961,7 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
929
961
  ResultFormatter.in(decodeResult, time);
930
962
  }
931
963
  if (parts.length === 7) {
932
- decodeResult.remaining.text += parts.slice(4).join("/");
964
+ ResultFormatter.unknownArr(decodeResult, parts.slice(4), "/");
933
965
  }
934
966
  for (let i = 1; i < lines.length; i++) {
935
967
  if (lines[i].startsWith("/LOC")) {
@@ -943,11 +975,9 @@ var Label_13Through18_Slash = class extends DecoderPlugin {
943
975
  longitude: CoordinateUtils.getDirection(location[1][0]) * CoordinateUtils.dmsToDecimalDegrees(Number(location[1].substring(1, 4)), Number(location[1].substring(4, 6)), Number(location[1].substring(6, 8)))
944
976
  };
945
977
  }
946
- if (!isNaN(position.latitude) && !isNaN(position.longitude)) {
947
- ResultFormatter.position(decodeResult, position);
948
- }
978
+ ResultFormatter.position(decodeResult, position);
949
979
  } else {
950
- decodeResult.remaining.text += "\r\n" + lines[i];
980
+ ResultFormatter.unknown(decodeResult, lines[i], "\r\n");
951
981
  }
952
982
  }
953
983
  decodeResult.decoded = true;
@@ -992,16 +1022,8 @@ var Label_15 = class extends DecoderPlugin {
992
1022
  decodeResult.formatted.description = "Position Report";
993
1023
  const twoZeeRegex = /^\(2(?<between>.+)\(Z$/;
994
1024
  const results = message.text.match(twoZeeRegex);
995
- if (results) {
996
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.between.substr(0, 13));
997
- if (decodeResult.raw.position) {
998
- decodeResult.formatted.items.push({
999
- type: "position",
1000
- code: "POS",
1001
- label: "Position",
1002
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1003
- });
1004
- }
1025
+ if (results?.groups) {
1026
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.between.substr(0, 13)));
1005
1027
  }
1006
1028
  decodeResult.decoded = true;
1007
1029
  decodeResult.decoder.decodeLevel = "partial";
@@ -1025,31 +1047,23 @@ var Label_15_FST = class extends DecoderPlugin {
1025
1047
  decodeResult.message = message;
1026
1048
  const parts = message.text.split(" ");
1027
1049
  const header = parts[0];
1028
- decodeResult.raw.departure_icao = header.substring(5, 9);
1029
- decodeResult.raw.arrival_icao = header.substring(9, 13);
1030
1050
  const stringCoords = header.substring(13);
1031
1051
  const firstChar = stringCoords.substring(0, 1);
1032
1052
  const middleChar = stringCoords.substring(7, 8);
1033
1053
  decodeResult.raw.position = {};
1034
1054
  if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
1035
- decodeResult.raw.position.latitude = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
1036
- decodeResult.raw.position.longitude = Number(stringCoords.substring(8, 15)) / 1e4 * (middleChar === "W" ? -1 : 1);
1037
- decodeResult.raw.altitude = Number(stringCoords.substring(15)) * 100;
1055
+ const lat = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
1056
+ const lon = Number(stringCoords.substring(8, 15)) / 1e4 * (middleChar === "W" ? -1 : 1);
1057
+ ResultFormatter.position(decodeResult, { latitude: lat, longitude: lon });
1058
+ ResultFormatter.altitude(decodeResult, Number(stringCoords.substring(15)) * 100);
1038
1059
  } else {
1039
1060
  decodeResult.decoded = false;
1040
1061
  decodeResult.decoder.decodeLevel = "none";
1041
1062
  return decodeResult;
1042
1063
  }
1043
- decodeResult.formatted.items.push({
1044
- type: "aircraft_position",
1045
- code: "POS",
1046
- label: "Aircraft Position",
1047
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1048
- });
1049
- ResultFormatter.altitude(decodeResult, decodeResult.raw.altitude);
1050
- ResultFormatter.departureAirport(decodeResult, decodeResult.raw.departure_icao);
1051
- ResultFormatter.arrivalAirport(decodeResult, decodeResult.raw.arrival_icao);
1052
- decodeResult.remaining.text = parts.slice(1).join(" ");
1064
+ ResultFormatter.departureAirport(decodeResult, header.substring(5, 9));
1065
+ ResultFormatter.arrivalAirport(decodeResult, header.substring(9, 13));
1066
+ ResultFormatter.unknownArr(decodeResult, parts.slice(1), " ");
1053
1067
  decodeResult.decoded = true;
1054
1068
  decodeResult.decoder.decodeLevel = "partial";
1055
1069
  return decodeResult;
@@ -1072,52 +1086,45 @@ var Label_16_N_Space = class extends DecoderPlugin {
1072
1086
  decodeResult.message = message;
1073
1087
  let variant1Regex = /^(?<lat>[NS])\s(?<lat_coord>.*),(?<long>[EW])\s*(?<long_coord>.*),(?<alt>.*),(?<unkwn1>.*),\s*(?<unkwn2>.*)$/;
1074
1088
  let variant2Regex = /^(?<lat>[NS])\s(?<lat_coord>.*)\/(?<long>[EW])\s*(?<long_coord>.*)$/;
1075
- let results;
1076
- if (results = message.text.match(variant1Regex)) {
1089
+ let results = message.text.match(variant1Regex);
1090
+ if (results?.groups) {
1077
1091
  if (options.debug) {
1078
1092
  console.log(`Label 16 N : results`);
1079
1093
  console.log(results);
1080
1094
  }
1081
- decodeResult.raw.position = {
1095
+ let pos = {
1082
1096
  latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
1083
1097
  longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
1084
1098
  };
1085
1099
  const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
1086
- decodeResult.formatted.items.push({
1087
- type: "aircraft_position",
1088
- code: "POS",
1089
- label: "Aircraft Position",
1090
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1091
- });
1100
+ ResultFormatter.position(decodeResult, pos);
1092
1101
  ResultFormatter.altitude(decodeResult, altitude);
1093
- decodeResult.remaining.text = `,${results.groups.unkwn1} ,${results.groups.unkwn2}`;
1102
+ ResultFormatter.unknownArr(decodeResult, [results.groups.unkwn1, results.groups.unkwn2]);
1094
1103
  decodeResult.decoded = true;
1095
1104
  decodeResult.decoder.decodeLevel = "partial";
1096
- } else if (results = message.text.match(variant2Regex)) {
1105
+ return decodeResult;
1106
+ }
1107
+ results = message.text.match(variant2Regex);
1108
+ if (results?.groups) {
1097
1109
  if (options.debug) {
1098
1110
  console.log(`Label 16 N : results`);
1099
1111
  console.log(results);
1100
1112
  }
1101
- decodeResult.raw.position = {
1113
+ let pos = {
1102
1114
  latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
1103
1115
  longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
1104
1116
  };
1105
- decodeResult.formatted.items.push({
1106
- type: "aircraft_position",
1107
- code: "POS",
1108
- label: "Aircraft Position",
1109
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1110
- });
1117
+ ResultFormatter.position(decodeResult, pos);
1111
1118
  decodeResult.decoded = true;
1112
1119
  decodeResult.decoder.decodeLevel = "full";
1113
- } else {
1114
- if (options.debug) {
1115
- console.log(`Decoder: Unknown 16 message: ${message.text}`);
1116
- }
1117
- decodeResult.remaining.text = message.text;
1118
- decodeResult.decoded = false;
1119
- decodeResult.decoder.decodeLevel = "none";
1120
+ return decodeResult;
1121
+ }
1122
+ if (options.debug) {
1123
+ console.log(`Decoder: Unknown 16 message: ${message.text}`);
1120
1124
  }
1125
+ ResultFormatter.unknown(decodeResult, message.text);
1126
+ decodeResult.decoded = false;
1127
+ decodeResult.decoder.decodeLevel = "none";
1121
1128
  return decodeResult;
1122
1129
  }
1123
1130
  };
@@ -1156,6 +1163,265 @@ var Label_1M_Slash = class extends DecoderPlugin {
1156
1163
  }
1157
1164
  };
1158
1165
 
1166
+ // lib/plugins/Label_1L_3-line.ts
1167
+ var Label_1L_3Line = class extends DecoderPlugin {
1168
+ // eslint-disable-line camelcase
1169
+ name = "label-1l-3-line";
1170
+ qualifiers() {
1171
+ return {
1172
+ labels: ["1L"]
1173
+ };
1174
+ }
1175
+ decode(message, options = {}) {
1176
+ const decodeResult = this.defaultResult();
1177
+ decodeResult.decoder.name = this.name;
1178
+ decodeResult.formatted.description = "Position Report";
1179
+ decodeResult.message = message;
1180
+ const lines = message.text.split("\r\n");
1181
+ if (lines.length !== 3) {
1182
+ if (options.debug) {
1183
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1184
+ }
1185
+ decodeResult.remaining.text = message.text;
1186
+ decodeResult.decoded = false;
1187
+ decodeResult.decoder.decodeLevel = "none";
1188
+ return decodeResult;
1189
+ }
1190
+ const parts = message.text.replaceAll("\r\n", "/").split("/");
1191
+ const data = /* @__PURE__ */ new Map();
1192
+ data.set("", parts[0]);
1193
+ for (let i = 1; i < parts.length; i++) {
1194
+ const part = parts[i].split(" ");
1195
+ data.set(part[0], part.slice(1).join(" "));
1196
+ }
1197
+ const dep = data.get("DEP");
1198
+ if (dep) {
1199
+ ResultFormatter.departureAirport(decodeResult, dep);
1200
+ data.delete("DEP");
1201
+ }
1202
+ const des = data.get("DES");
1203
+ if (des) {
1204
+ ResultFormatter.arrivalAirport(decodeResult, des);
1205
+ data.delete("DES");
1206
+ }
1207
+ const eta = data.get("ETA");
1208
+ if (eta) {
1209
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta + "00"));
1210
+ data.delete("ETA");
1211
+ }
1212
+ const alt = data.get("ALT");
1213
+ if (alt) {
1214
+ ResultFormatter.altitude(decodeResult, Number(alt));
1215
+ data.delete("ALT");
1216
+ }
1217
+ const fn = data.get("FN");
1218
+ if (fn) {
1219
+ ResultFormatter.flightNumber(decodeResult, fn);
1220
+ data.delete("FN");
1221
+ }
1222
+ const day = data.get("DAY");
1223
+ const utc = data.get("UTC");
1224
+ if (day && utc) {
1225
+ decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
1226
+ data.delete("DAY");
1227
+ data.delete("UTC");
1228
+ }
1229
+ const lat = data.get("LAT");
1230
+ const lon = data.get("LON");
1231
+ if (lat && lon) {
1232
+ ResultFormatter.position(decodeResult, {
1233
+ latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
1234
+ longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
1235
+ });
1236
+ data.delete("LAT");
1237
+ data.delete("LON");
1238
+ }
1239
+ let remaining = "";
1240
+ for (const [key, value] of data.entries()) {
1241
+ if (key === "") {
1242
+ remaining += value;
1243
+ } else {
1244
+ remaining += `/${key} ${value}`;
1245
+ }
1246
+ }
1247
+ decodeResult.remaining.text = remaining;
1248
+ decodeResult.decoded = true;
1249
+ decodeResult.decoder.decodeLevel = "partial";
1250
+ return decodeResult;
1251
+ }
1252
+ };
1253
+
1254
+ // lib/plugins/Label_1L_070.ts
1255
+ var Label_1L_070 = class extends DecoderPlugin {
1256
+ // eslint-disable-line camelcase
1257
+ name = "label-1l-070";
1258
+ qualifiers() {
1259
+ return {
1260
+ labels: ["1L"],
1261
+ preambles: ["000000070"]
1262
+ };
1263
+ }
1264
+ decode(message, options = {}) {
1265
+ const decodeResult = this.defaultResult();
1266
+ decodeResult.decoder.name = this.name;
1267
+ decodeResult.formatted.description = "Position Report";
1268
+ decodeResult.message = message;
1269
+ if (!message.text.startsWith("000000070")) {
1270
+ if (options.debug) {
1271
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1272
+ }
1273
+ decodeResult.remaining.text = message.text;
1274
+ decodeResult.decoded = false;
1275
+ decodeResult.decoder.decodeLevel = "none";
1276
+ return decodeResult;
1277
+ }
1278
+ const parts = message.text.substring(9).split(",");
1279
+ if (parts.length !== 7) {
1280
+ if (options.debug) {
1281
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1282
+ }
1283
+ decodeResult.remaining.text = message.text;
1284
+ decodeResult.decoded = false;
1285
+ decodeResult.decoder.decodeLevel = "none";
1286
+ return decodeResult;
1287
+ }
1288
+ ResultFormatter.departureAirport(decodeResult, parts[0]);
1289
+ ResultFormatter.arrivalAirport(decodeResult, parts[1]);
1290
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2] + "00"));
1291
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3] + "00"));
1292
+ ResultFormatter.position(decodeResult, {
1293
+ latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
1294
+ longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
1295
+ });
1296
+ decodeResult.remaining.text = parts[6];
1297
+ decodeResult.decoded = true;
1298
+ decodeResult.decoder.decodeLevel = "partial";
1299
+ return decodeResult;
1300
+ }
1301
+ };
1302
+
1303
+ // lib/plugins/Label_1L_660.ts
1304
+ var Label_1L_660 = class extends DecoderPlugin {
1305
+ // eslint-disable-line camelcase
1306
+ name = "label-1l-660";
1307
+ qualifiers() {
1308
+ return {
1309
+ labels: ["1L"],
1310
+ preambles: ["000000660"]
1311
+ };
1312
+ }
1313
+ decode(message, options = {}) {
1314
+ const decodeResult = this.defaultResult();
1315
+ decodeResult.decoder.name = this.name;
1316
+ decodeResult.formatted.description = "Position Report";
1317
+ decodeResult.message = message;
1318
+ if (!message.text.startsWith("000000660")) {
1319
+ if (options.debug) {
1320
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1321
+ }
1322
+ decodeResult.remaining.text = message.text;
1323
+ decodeResult.decoded = false;
1324
+ decodeResult.decoder.decodeLevel = "none";
1325
+ return decodeResult;
1326
+ }
1327
+ const parts = message.text.substring(9).split(",");
1328
+ if (parts.length !== 5) {
1329
+ if (options.debug) {
1330
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1331
+ }
1332
+ decodeResult.remaining.text = message.text;
1333
+ decodeResult.decoded = false;
1334
+ decodeResult.decoder.decodeLevel = "none";
1335
+ return decodeResult;
1336
+ }
1337
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(parts[0]);
1338
+ if (position) {
1339
+ ResultFormatter.position(decodeResult, position);
1340
+ }
1341
+ const hhmmss = parts[1].substring(0, 6);
1342
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmmss));
1343
+ const fl = parts[1].substring(6, 9);
1344
+ ResultFormatter.altitude(decodeResult, Number(fl) * 100);
1345
+ const next = parts[1].substring(9);
1346
+ ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
1347
+ decodeResult.remaining.text = parts.slice(2).join(",");
1348
+ decodeResult.decoded = true;
1349
+ decodeResult.decoder.decodeLevel = "partial";
1350
+ return decodeResult;
1351
+ }
1352
+ };
1353
+
1354
+ // lib/plugins/Label_1L_Slash.ts
1355
+ var Label_1L_Slash = class extends DecoderPlugin {
1356
+ // eslint-disable-line camelcase
1357
+ name = "label-1l-1-line";
1358
+ qualifiers() {
1359
+ return {
1360
+ labels: ["1L"],
1361
+ preambles: ["+", "-"]
1362
+ };
1363
+ }
1364
+ decode(message, options = {}) {
1365
+ const decodeResult = this.defaultResult();
1366
+ decodeResult.decoder.name = this.name;
1367
+ decodeResult.formatted.description = "Position Report";
1368
+ decodeResult.message = message;
1369
+ const parts = message.text.split("/");
1370
+ if (parts.length !== 7) {
1371
+ if (options.debug) {
1372
+ console.log(`Decoder: Unknown 1L message: ${message.text}`);
1373
+ }
1374
+ decodeResult.remaining.text = message.text;
1375
+ decodeResult.decoded = false;
1376
+ decodeResult.decoder.decodeLevel = "none";
1377
+ return decodeResult;
1378
+ }
1379
+ const data = /* @__PURE__ */ new Map();
1380
+ data.set("LAT", parts[0].replaceAll(" ", ""));
1381
+ data.set("LON", parts[1].replaceAll(" ", ""));
1382
+ for (let i = 2; i < parts.length; i++) {
1383
+ const part = parts[i].split(" ");
1384
+ data.set(part[0], part.slice(1).join(" "));
1385
+ }
1386
+ console.log(data);
1387
+ const position = {
1388
+ latitude: Number(data.get("LAT")),
1389
+ longitude: Number(data.get("LON"))
1390
+ };
1391
+ data.delete("LAT");
1392
+ data.delete("LON");
1393
+ ResultFormatter.position(decodeResult, position);
1394
+ const utc = data.get("UTC");
1395
+ if (utc) {
1396
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(utc));
1397
+ data.delete("UTC");
1398
+ }
1399
+ const alt = data.get("ALT");
1400
+ if (alt) {
1401
+ ResultFormatter.altitude(decodeResult, Number(alt));
1402
+ data.delete("ALT");
1403
+ }
1404
+ const fob = data.get("FOB");
1405
+ if (fob) {
1406
+ ResultFormatter.currentFuel(decodeResult, Number(fob));
1407
+ data.delete("FOB");
1408
+ }
1409
+ const eta = data.get("ETA");
1410
+ if (eta) {
1411
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta + "00"));
1412
+ data.delete("ETA");
1413
+ }
1414
+ let remaining = "";
1415
+ for (const [key, value] of data.entries()) {
1416
+ remaining += `/${key} ${value}`;
1417
+ }
1418
+ decodeResult.remaining.text = remaining;
1419
+ decodeResult.decoded = true;
1420
+ decodeResult.decoder.decodeLevel = "partial";
1421
+ return decodeResult;
1422
+ }
1423
+ };
1424
+
1159
1425
  // lib/plugins/Label_20_POS.ts
1160
1426
  var Label_20_POS = class extends DecoderPlugin {
1161
1427
  name = "label-20-pos";
@@ -1178,30 +1444,16 @@ var Label_20_POS = class extends DecoderPlugin {
1178
1444
  console.log(`DEBUG: ${this.name}: Variation 1 detected`);
1179
1445
  }
1180
1446
  const rawCoords = fields[0];
1181
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
1182
- if (decodeResult.raw.position) {
1183
- decodeResult.formatted.items.push({
1184
- type: "position",
1185
- code: "POS",
1186
- label: "Position",
1187
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1188
- });
1189
- }
1447
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(rawCoords));
1190
1448
  decodeResult.decoded = true;
1191
1449
  decodeResult.decoder.decodeLevel = "full";
1192
1450
  } else if (fields.length == 5) {
1193
1451
  if (options.debug) {
1194
1452
  console.log(`DEBUG: ${this.name}: Variation 2 detected`);
1195
1453
  }
1196
- const rawCoords = fields[0];
1197
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(rawCoords);
1198
- if (decodeResult.raw.position) {
1199
- decodeResult.formatted.items.push({
1200
- type: "position",
1201
- code: "POS",
1202
- label: "Position",
1203
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1204
- });
1454
+ const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
1455
+ if (position) {
1456
+ ResultFormatter.position(decodeResult, position);
1205
1457
  }
1206
1458
  decodeResult.decoded = true;
1207
1459
  decodeResult.decoder.decodeLevel = "full";
@@ -1240,11 +1492,7 @@ var Label_21_POS = class extends DecoderPlugin {
1240
1492
  ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
1241
1493
  ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[7]));
1242
1494
  ResultFormatter.arrivalAirport(decodeResult, fields[8]);
1243
- decodeResult.remaining.text = [
1244
- fields[1],
1245
- fields[4],
1246
- fields[5]
1247
- ].join(",");
1495
+ ResultFormatter.unknownArr(decodeResult, [fields[1], fields[4], fields[5]]);
1248
1496
  decodeResult.decoded = true;
1249
1497
  decodeResult.decoder.decodeLevel = "partial";
1250
1498
  } else {
@@ -1270,41 +1518,74 @@ function processPosition(decodeResult, value) {
1270
1518
  ResultFormatter.position(decodeResult, position);
1271
1519
  }
1272
1520
 
1273
- // lib/plugins/Label_24_Slash.ts
1274
- var Label_24_Slash = class extends DecoderPlugin {
1275
- name = "label-24-slash";
1521
+ // lib/plugins/Label_22_OFF.ts
1522
+ var Label_22_OFF = class extends DecoderPlugin {
1523
+ name = "label-22-off";
1276
1524
  qualifiers() {
1277
1525
  return {
1278
- labels: ["24"],
1279
- preambles: ["/"]
1526
+ labels: ["22"],
1527
+ preambles: ["OFF"]
1280
1528
  };
1281
1529
  }
1282
1530
  decode(message, options = {}) {
1283
1531
  const decodeResult = this.defaultResult();
1284
1532
  decodeResult.decoder.name = this.name;
1285
- decodeResult.formatted.description = "Position Report";
1533
+ decodeResult.formatted.description = "Takeoff Report";
1286
1534
  decodeResult.message = message;
1287
- const fields = message.text.split("/");
1288
- if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
1289
- const mmddyy = fields[1].substring(4, 6) + fields[1].substring(2, 4) + fields[1].substring(0, 2);
1290
- const hhmmss = fields[2] + "00";
1291
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(hhmmss, mmddyy);
1292
- ResultFormatter.flightNumber(decodeResult, fields[3]);
1293
- ResultFormatter.altitude(decodeResult, Number(fields[4]));
1294
- const lat = fields[5];
1295
- const lon = fields[6];
1296
- const position = {
1297
- latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
1298
- longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
1299
- };
1300
- ResultFormatter.position(decodeResult, position);
1301
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8] + "00"));
1302
- decodeResult.remaining.text = fields[7];
1535
+ if (message.text.startsWith("OFF01")) {
1536
+ const fields = message.text.substring(5).split("/");
1537
+ if (fields.length != 2) {
1538
+ decodeResult.decoded = false;
1539
+ decodeResult.decoder.decodeLevel = "none";
1540
+ return decodeResult;
1541
+ }
1542
+ ResultFormatter.flightNumber(decodeResult, fields[0]);
1543
+ ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
1544
+ ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
1545
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8) + "00"));
1546
+ ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
1547
+ ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
1548
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
1549
+ ResultFormatter.unknown(decodeResult, fields[1].substring(22));
1550
+ decodeResult.decoded = true;
1551
+ decodeResult.decoder.decodeLevel = "partial";
1552
+ } else if (message.text.startsWith("OFF02\r\n")) {
1553
+ const fields = message.text.substring(7).split(",");
1554
+ if (fields.length != 4) {
1555
+ decodeResult.decoded = false;
1556
+ decodeResult.decoder.decodeLevel = "none";
1557
+ return decodeResult;
1558
+ }
1559
+ ResultFormatter.departureAirport(decodeResult, fields[0]);
1560
+ ResultFormatter.arrivalAirport(decodeResult, fields[1]);
1561
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2] + "00"));
1562
+ ResultFormatter.unknown(decodeResult, fields[3]);
1563
+ decodeResult.decoded = true;
1564
+ decodeResult.decoder.decodeLevel = "partial";
1565
+ } else if (message.text.startsWith("OFF02")) {
1566
+ const fields = message.text.substring(5).split("/");
1567
+ if (fields.length != 2) {
1568
+ decodeResult.decoded = false;
1569
+ decodeResult.decoder.decodeLevel = "none";
1570
+ return decodeResult;
1571
+ }
1572
+ ResultFormatter.flightNumber(decodeResult, fields[0]);
1573
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(fields[1].substring(0, 14));
1574
+ if (position) {
1575
+ ResultFormatter.position(decodeResult, position);
1576
+ }
1577
+ ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
1578
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20) + "00"));
1579
+ ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
1580
+ ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
1581
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32) + "00"));
1582
+ ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
1583
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40) + "00"));
1303
1584
  decodeResult.decoded = true;
1304
1585
  decodeResult.decoder.decodeLevel = "partial";
1305
1586
  } else {
1306
1587
  if (options.debug) {
1307
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`);
1588
+ console.log(`DEBUG: ${this.name}: Unknown variation.`);
1308
1589
  }
1309
1590
  decodeResult.decoded = false;
1310
1591
  decodeResult.decoder.decodeLevel = "none";
@@ -1313,33 +1594,116 @@ var Label_24_Slash = class extends DecoderPlugin {
1313
1594
  }
1314
1595
  };
1315
1596
 
1316
- // lib/plugins/Label_30_Slash_EA.ts
1317
- var Label_30_Slash_EA = class extends DecoderPlugin {
1318
- name = "label-30-slash-ea";
1597
+ // lib/plugins/Label_22_POS.ts
1598
+ var Label_22_POS = class extends DecoderPlugin {
1599
+ name = "label-22-pos";
1319
1600
  qualifiers() {
1320
1601
  return {
1321
- labels: ["30"],
1322
- preambles: ["/EA"]
1602
+ labels: ["22"],
1603
+ preambles: ["N", "S"]
1323
1604
  };
1324
1605
  }
1325
1606
  decode(message, options = {}) {
1326
1607
  const decodeResult = this.defaultResult();
1327
1608
  decodeResult.decoder.name = this.name;
1328
- decodeResult.formatted.description = "ETA Report";
1609
+ decodeResult.formatted.description = "Position Report";
1329
1610
  decodeResult.message = message;
1330
- const results = message.text.split(/\n|\//).slice(1);
1331
- if (results) {
1611
+ const fields = message.text.split(",");
1612
+ if (fields.length !== 11) {
1332
1613
  if (options.debug) {
1333
- console.log(`Label 30 EA: results`);
1334
- console.log(results);
1614
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`);
1615
+ }
1616
+ decodeResult.decoded = false;
1617
+ decodeResult.decoder.decodeLevel = "none";
1618
+ return decodeResult;
1619
+ }
1620
+ const latStr = fields[0].substring(1, 8);
1621
+ const lonStr = fields[0].substring(9);
1622
+ const lat = Number(latStr) / 1e4;
1623
+ const lon = Number(lonStr) / 1e4;
1624
+ ResultFormatter.position(decodeResult, {
1625
+ latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
1626
+ longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
1627
+ });
1628
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1629
+ ResultFormatter.altitude(decodeResult, Number(fields[3]));
1630
+ ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
1631
+ decodeResult.decoded = true;
1632
+ decodeResult.decoder.decodeLevel = "partial";
1633
+ return decodeResult;
1634
+ }
1635
+ };
1636
+
1637
+ // lib/plugins/Label_24_Slash.ts
1638
+ var Label_24_Slash = class extends DecoderPlugin {
1639
+ name = "label-24-slash";
1640
+ qualifiers() {
1641
+ return {
1642
+ labels: ["24"],
1643
+ preambles: ["/"]
1644
+ };
1645
+ }
1646
+ decode(message, options = {}) {
1647
+ const decodeResult = this.defaultResult();
1648
+ decodeResult.decoder.name = this.name;
1649
+ decodeResult.formatted.description = "Position Report";
1650
+ decodeResult.message = message;
1651
+ const fields = message.text.split("/");
1652
+ if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
1653
+ const mmddyy = fields[1].substring(4, 6) + fields[1].substring(2, 4) + fields[1].substring(0, 2);
1654
+ const hhmmss = fields[2] + "00";
1655
+ decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(hhmmss, mmddyy);
1656
+ ResultFormatter.flightNumber(decodeResult, fields[3]);
1657
+ ResultFormatter.altitude(decodeResult, Number(fields[4]));
1658
+ const lat = fields[5];
1659
+ const lon = fields[6];
1660
+ const position = {
1661
+ latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
1662
+ longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
1663
+ };
1664
+ ResultFormatter.position(decodeResult, position);
1665
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8] + "00"));
1666
+ ResultFormatter.unknown(decodeResult, fields[7]);
1667
+ decodeResult.decoded = true;
1668
+ decodeResult.decoder.decodeLevel = "partial";
1669
+ } else {
1670
+ if (options.debug) {
1671
+ console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`);
1672
+ }
1673
+ decodeResult.decoded = false;
1674
+ decodeResult.decoder.decodeLevel = "none";
1675
+ }
1676
+ return decodeResult;
1677
+ }
1678
+ };
1679
+
1680
+ // lib/plugins/Label_30_Slash_EA.ts
1681
+ var Label_30_Slash_EA = class extends DecoderPlugin {
1682
+ name = "label-30-slash-ea";
1683
+ qualifiers() {
1684
+ return {
1685
+ labels: ["30"],
1686
+ preambles: ["/EA"]
1687
+ };
1688
+ }
1689
+ decode(message, options = {}) {
1690
+ const decodeResult = this.defaultResult();
1691
+ decodeResult.decoder.name = this.name;
1692
+ decodeResult.formatted.description = "ETA Report";
1693
+ decodeResult.message = message;
1694
+ const results = message.text.split(/\n|\//).slice(1);
1695
+ if (results) {
1696
+ if (options.debug) {
1697
+ console.log(`Label 30 EA: results`);
1698
+ console.log(results);
1335
1699
  }
1336
1700
  }
1337
1701
  ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4) + "00"));
1338
1702
  if (results[1].substring(0, 2) === "DS") {
1339
1703
  ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
1340
- decodeResult.remaining.text = "/".concat(results[2]);
1704
+ ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
1341
1705
  } else {
1342
- decodeResult.remaining.text = "/".concat(results[1], "/", results[2]);
1706
+ ResultFormatter.unknown(decodeResult, "/".concat(results[1], "/", results[2]));
1343
1707
  }
1344
1708
  decodeResult.decoded = true;
1345
1709
  decodeResult.decoder.decodeLevel = "partial";
@@ -1363,40 +1727,20 @@ var Label_44_ETA = class extends DecoderPlugin {
1363
1727
  decodeResult.message = message;
1364
1728
  const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
1365
1729
  const results = message.text.match(regex);
1366
- if (results) {
1730
+ if (results?.groups) {
1367
1731
  if (options.debug) {
1368
1732
  console.log(`Label 44 ETA Report: groups`);
1369
1733
  console.log(results.groups);
1370
1734
  }
1371
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords);
1372
- decodeResult.raw.departure_icao = results.groups.departure_icao;
1373
- decodeResult.raw.arrival_icao = results.groups.arrival_icao;
1735
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
1736
+ ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
1737
+ ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
1374
1738
  decodeResult.raw.current_time = Date.parse(
1375
1739
  (/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
1376
1740
  );
1377
1741
  if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
1378
- decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
1379
- }
1380
- if (decodeResult.raw.position) {
1381
- decodeResult.formatted.items.push({
1382
- type: "position",
1383
- code: "POS",
1384
- label: "Position",
1385
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1386
- });
1742
+ ResultFormatter.remainingFuel(decodeResult, Number(results.groups.fuel_in_tons));
1387
1743
  }
1388
- decodeResult.formatted.items.push({
1389
- type: "origin",
1390
- code: "ORG",
1391
- label: "Origin",
1392
- value: decodeResult.raw.departure_icao
1393
- });
1394
- decodeResult.formatted.items.push({
1395
- type: "destination",
1396
- code: "DST",
1397
- label: "Destination",
1398
- value: decodeResult.raw.arrival_icao
1399
- });
1400
1744
  }
1401
1745
  decodeResult.decoded = true;
1402
1746
  decodeResult.decoder.decodeLevel = "full";
@@ -1420,40 +1764,20 @@ var Label_44_IN = class extends DecoderPlugin {
1420
1764
  decodeResult.message = message;
1421
1765
  const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
1422
1766
  const results = message.text.match(regex);
1423
- if (results) {
1767
+ if (results?.groups) {
1424
1768
  if (options.debug) {
1425
1769
  console.log(`Label 44 In Air Report: groups`);
1426
1770
  console.log(results.groups);
1427
1771
  }
1428
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords);
1429
- decodeResult.raw.departure_icao = results.groups.departure_icao;
1430
- decodeResult.raw.arrival_icao = results.groups.arrival_icao;
1772
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
1773
+ ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
1774
+ ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
1431
1775
  decodeResult.raw.current_time = Date.parse(
1432
1776
  (/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
1433
1777
  );
1434
1778
  if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
1435
1779
  decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
1436
1780
  }
1437
- if (decodeResult.raw.position) {
1438
- decodeResult.formatted.items.push({
1439
- type: "position",
1440
- code: "POS",
1441
- label: "Position",
1442
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1443
- });
1444
- }
1445
- decodeResult.formatted.items.push({
1446
- type: "origin",
1447
- code: "ORG",
1448
- label: "Origin",
1449
- value: decodeResult.raw.departure_icao
1450
- });
1451
- decodeResult.formatted.items.push({
1452
- type: "destination",
1453
- code: "DST",
1454
- label: "Destination",
1455
- value: decodeResult.raw.arrival_icao
1456
- });
1457
1781
  }
1458
1782
  decodeResult.decoded = true;
1459
1783
  decodeResult.decoder.decodeLevel = "full";
@@ -1477,13 +1801,14 @@ var Label_44_OFF = class extends DecoderPlugin {
1477
1801
  decodeResult.message = message;
1478
1802
  const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
1479
1803
  const results = message.text.match(regex);
1480
- if (results) {
1804
+ if (results?.groups) {
1481
1805
  if (options.debug) {
1482
1806
  console.log(`Label 44 Off Runway Report: groups`);
1483
1807
  console.log(results.groups);
1484
1808
  }
1485
- decodeResult.raw.departure_icao = results.groups.departure_icao;
1486
- decodeResult.raw.arrival_icao = results.groups.arrival_icao;
1809
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
1810
+ ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
1811
+ ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
1487
1812
  decodeResult.raw.current_time = Date.parse(
1488
1813
  (/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
1489
1814
  );
@@ -1493,27 +1818,6 @@ var Label_44_OFF = class extends DecoderPlugin {
1493
1818
  if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
1494
1819
  decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
1495
1820
  }
1496
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords);
1497
- if (decodeResult.raw.position) {
1498
- decodeResult.formatted.items.push({
1499
- type: "position",
1500
- code: "POS",
1501
- label: "Position",
1502
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1503
- });
1504
- }
1505
- decodeResult.formatted.items.push({
1506
- type: "origin",
1507
- code: "ORG",
1508
- label: "Origin",
1509
- value: decodeResult.raw.departure_icao
1510
- });
1511
- decodeResult.formatted.items.push({
1512
- type: "destination",
1513
- code: "DST",
1514
- label: "Destination",
1515
- value: decodeResult.raw.arrival_icao
1516
- });
1517
1821
  }
1518
1822
  decodeResult.decoded = true;
1519
1823
  decodeResult.decoder.decodeLevel = "full";
@@ -1537,40 +1841,20 @@ var Label_44_ON = class extends DecoderPlugin {
1537
1841
  decodeResult.message = message;
1538
1842
  const regex = /^.*,(?<unsplit_coords>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<fuel_in_tons>.*)$/;
1539
1843
  const results = message.text.match(regex);
1540
- if (results) {
1844
+ if (results?.groups) {
1541
1845
  if (options.debug) {
1542
1846
  console.log(`Label 44 On Runway Report: groups`);
1543
1847
  console.log(results.groups);
1544
1848
  }
1545
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords);
1546
- decodeResult.raw.departure_icao = results.groups.departure_icao;
1547
- decodeResult.raw.arrival_icao = results.groups.arrival_icao;
1849
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(results.groups.unsplit_coords));
1850
+ ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
1851
+ ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
1548
1852
  decodeResult.raw.current_time = Date.parse(
1549
1853
  (/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
1550
1854
  );
1551
1855
  if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
1552
- decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
1856
+ ResultFormatter.remainingFuel(decodeResult, Number(results.groups.fuel_in_tons));
1553
1857
  }
1554
- if (decodeResult.raw.position) {
1555
- decodeResult.formatted.items.push({
1556
- type: "position",
1557
- code: "POS",
1558
- label: "Position",
1559
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1560
- });
1561
- }
1562
- decodeResult.formatted.items.push({
1563
- type: "origin",
1564
- code: "ORG",
1565
- label: "Origin",
1566
- value: decodeResult.raw.departure_icao
1567
- });
1568
- decodeResult.formatted.items.push({
1569
- type: "destination",
1570
- code: "DST",
1571
- label: "Destination",
1572
- value: decodeResult.raw.arrival_icao
1573
- });
1574
1858
  }
1575
1859
  decodeResult.decoded = true;
1576
1860
  decodeResult.decoder.decodeLevel = "full";
@@ -1594,12 +1878,12 @@ var Label_44_POS = class extends DecoderPlugin {
1594
1878
  decodeResult.message = message;
1595
1879
  const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
1596
1880
  const results = message.text.match(regex);
1597
- if (results) {
1881
+ if (results?.groups) {
1598
1882
  if (options.debug) {
1599
1883
  console.log(`Label 44 Position Report: groups`);
1600
1884
  console.log(results.groups);
1601
1885
  }
1602
- decodeResult.raw.position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords);
1886
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords));
1603
1887
  const flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? 0 : Number(results.groups.flight_level_or_ground);
1604
1888
  decodeResult.raw.current_time = Date.parse(
1605
1889
  (/* @__PURE__ */ new Date()).getFullYear() + "-" + results.groups.current_date.substr(0, 2) + "-" + results.groups.current_date.substr(2, 2) + "T" + results.groups.current_time.substr(0, 2) + ":" + results.groups.current_time.substr(2, 2) + ":00Z"
@@ -1610,14 +1894,6 @@ var Label_44_POS = class extends DecoderPlugin {
1610
1894
  if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
1611
1895
  decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
1612
1896
  }
1613
- if (decodeResult.raw.position) {
1614
- decodeResult.formatted.items.push({
1615
- type: "aircraft_position",
1616
- code: "POS",
1617
- label: "Aircraft Position",
1618
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
1619
- });
1620
- }
1621
1897
  ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
1622
1898
  ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
1623
1899
  ResultFormatter.altitude(decodeResult, flight_level * 100);
@@ -1641,13 +1917,13 @@ var Label_4A = class extends DecoderPlugin {
1641
1917
  decodeResult.decoder.name = this.name;
1642
1918
  decodeResult.message = message;
1643
1919
  decodeResult.formatted.description = "Latest New Format";
1644
- let text2 = message.text;
1645
- if (text2.match(/^M\d{2}A\w{6}/)) {
1920
+ let text = message.text;
1921
+ if (text.match(/^M\d{2}A\w{6}/)) {
1646
1922
  ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
1647
- text2 = text2.substring(10);
1923
+ text = text.substring(10);
1648
1924
  }
1649
1925
  decodeResult.decoded = true;
1650
- const fields = text2.split(",");
1926
+ const fields = text.split(",");
1651
1927
  if (fields.length === 11) {
1652
1928
  ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
1653
1929
  ResultFormatter.tail(decodeResult, fields[2].replace(".", ""));
@@ -1655,8 +1931,8 @@ var Label_4A = class extends DecoderPlugin {
1655
1931
  ResultFormatter.callsign(decodeResult, fields[3]);
1656
1932
  ResultFormatter.departureAirport(decodeResult, fields[4]);
1657
1933
  ResultFormatter.arrivalAirport(decodeResult, fields[5]);
1658
- ResultFormatter.altitude(decodeResult, text2.substring(48, 51) * 100);
1659
- decodeResult.remaining.text = fields.slice(8).join(",");
1934
+ ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
1935
+ ResultFormatter.unknownArr(decodeResult, fields.slice(8));
1660
1936
  } else if (fields.length === 6) {
1661
1937
  if (fields[0].match(/^[NS]/)) {
1662
1938
  ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13)));
@@ -1665,31 +1941,25 @@ var Label_4A = class extends DecoderPlugin {
1665
1941
  time: DateTimeUtils.convertHHMMSSToTod(fields[1].substring(0, 6)),
1666
1942
  timeFormat: "tod"
1667
1943
  };
1668
- ResultFormatter.altitude(decodeResult, fields[1].substring(6, 9) * 100);
1944
+ ResultFormatter.altitude(decodeResult, Number(fields[1].substring(6, 9)) * 100);
1669
1945
  let wp2 = {
1670
1946
  name: fields[1].substring(9).trim(),
1671
1947
  time: DateTimeUtils.convertHHMMSSToTod(fields[2]),
1672
1948
  timeFormat: "tod"
1673
1949
  };
1674
- decodeResult.raw.route = { waypoints: [wp1, wp2] };
1675
- decodeResult.formatted.items.push({
1676
- type: "aircraft_route",
1677
- code: "ROUTE",
1678
- label: "Aircraft Route",
1679
- value: RouteUtils.routeToString(decodeResult.raw.route)
1680
- });
1950
+ ResultFormatter.route(decodeResult, { waypoints: [wp1, wp2] });
1681
1951
  ResultFormatter.temperature(decodeResult, fields[3]);
1682
- decodeResult.remaining.text = fields.slice(4).join(",");
1952
+ ResultFormatter.unknownArr(decodeResult, fields.slice(4));
1683
1953
  } else {
1684
1954
  ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
1685
1955
  ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1]));
1686
- decodeResult.remaining.text = fields[2];
1687
- ResultFormatter.altitude(decodeResult, fields[3]);
1956
+ ResultFormatter.unknown(decodeResult, fields[2]);
1957
+ ResultFormatter.altitude(decodeResult, Number(fields[3]));
1688
1958
  ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates((fields[4] + fields[5]).replace(/[ \.]/g, "")));
1689
1959
  }
1690
1960
  } else {
1691
1961
  decodeResult.decoded = false;
1692
- decodeResult.remaining.text = text2;
1962
+ ResultFormatter.unknown(decodeResult, text);
1693
1963
  }
1694
1964
  if (decodeResult.decoded) {
1695
1965
  if (!decodeResult.remaining.text)
@@ -1726,11 +1996,11 @@ var Label_4A_01 = class extends DecoderPlugin {
1726
1996
  ResultFormatter.departureAirport(decodeResult, rgx[5]);
1727
1997
  ResultFormatter.arrivalAirport(decodeResult, rgx[6]);
1728
1998
  ResultFormatter.altitude(decodeResult, Number(rgx[7].replace(/ /g, "")));
1729
- decodeResult.remaining.text = rgx[8];
1999
+ ResultFormatter.unknown(decodeResult, rgx[8]);
1730
2000
  ResultFormatter.temperature(decodeResult, rgx[9].replace(/ /g, ""));
1731
2001
  } else {
1732
2002
  decodeResult.decoded = false;
1733
- decodeResult.remaining.text = message.text;
2003
+ ResultFormatter.unknown(decodeResult, message.text);
1734
2004
  }
1735
2005
  if (decodeResult.decoded) {
1736
2006
  if (!decodeResult.remaining.text)
@@ -1796,7 +2066,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
1796
2066
  ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2] + "00"));
1797
2067
  } else {
1798
2068
  decodeResult.decoded = false;
1799
- decodeResult.remaining.text = text;
2069
+ ResultFormatter.unknown(decodeResult, message.text);
1800
2070
  }
1801
2071
  if (decodeResult.decoded) {
1802
2072
  if (!decodeResult.remaining.text)
@@ -1826,10 +2096,10 @@ var Label_4A_Slash_01 = class extends DecoderPlugin {
1826
2096
  decodeResult.formatted.description = "Latest New Format";
1827
2097
  decodeResult.decoded = true;
1828
2098
  if (message.text.length === 5 && message.text.substring(0, 4) === "/01-") {
1829
- decodeResult.remaining.text = message.text.substring(4);
2099
+ ResultFormatter.unknown(decodeResult, message.text.substring(4));
1830
2100
  } else {
1831
2101
  decodeResult.decoded = false;
1832
- decodeResult.remaining.text = message.text;
2102
+ ResultFormatter.unknown(decodeResult, message.text);
1833
2103
  }
1834
2104
  if (decodeResult.decoded) {
1835
2105
  if (!decodeResult.remaining.text)
@@ -1856,25 +2126,25 @@ var Label_4N = class extends DecoderPlugin {
1856
2126
  decodeResult.decoder.name = this.name;
1857
2127
  decodeResult.message = message;
1858
2128
  decodeResult.formatted.description = "Airline Defined";
1859
- let text2 = message.text;
1860
- if (text2.match(/^M\d{2}A\w{6}/)) {
2129
+ let text = message.text;
2130
+ if (text.match(/^M\d{2}A\w{6}/)) {
1861
2131
  ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
1862
- text2 = text2.substring(10);
2132
+ text = text.substring(10);
1863
2133
  }
1864
2134
  decodeResult.decoded = true;
1865
- const fields = text2.split(",");
1866
- if (text2.length === 51) {
1867
- decodeResult.raw.day_of_month = text2.substring(0, 2);
1868
- ResultFormatter.departureAirport(decodeResult, text2.substring(8, 11));
1869
- ResultFormatter.arrivalAirport(decodeResult, text2.substring(13, 16));
1870
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text2.substring(30, 45).replace(/^(.)0/, "$1")));
1871
- ResultFormatter.altitude(decodeResult, text2.substring(48, 51) * 100);
1872
- decodeResult.remaining.text = [text2.substring(2, 4), text2.substring(19, 29)].join(" ");
2135
+ const fields = text.split(",");
2136
+ if (text.length === 51) {
2137
+ decodeResult.raw.day_of_month = text.substring(0, 2);
2138
+ ResultFormatter.departureAirport(decodeResult, text.substring(8, 11));
2139
+ ResultFormatter.arrivalAirport(decodeResult, text.substring(13, 16));
2140
+ ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(30, 45).replace(/^(.)0/, "$1")));
2141
+ ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
2142
+ ResultFormatter.unknownArr(decodeResult, [text.substring(2, 4), text.substring(19, 29)], " ");
1873
2143
  } else if (fields.length === 33) {
1874
2144
  decodeResult.raw.date = fields[3];
1875
2145
  if (fields[1] === "B") {
1876
2146
  ResultFormatter.position(decodeResult, { latitude: Number(fields[4]), longitude: Number(fields[5]) });
1877
- ResultFormatter.altitude(decodeResult, fields[6]);
2147
+ ResultFormatter.altitude(decodeResult, Number(fields[6]));
1878
2148
  }
1879
2149
  ResultFormatter.departureAirport(decodeResult, fields[8]);
1880
2150
  ResultFormatter.arrivalAirport(decodeResult, fields[9]);
@@ -1884,10 +2154,10 @@ var Label_4N = class extends DecoderPlugin {
1884
2154
  ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
1885
2155
  }
1886
2156
  ResultFormatter.checksum(decodeResult, fields[32]);
1887
- decodeResult.remaining.text = [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != "").join(",");
2157
+ ResultFormatter.unknownArr(decodeResult, [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != ""));
1888
2158
  } else {
1889
2159
  decodeResult.decoded = false;
1890
- decodeResult.remaining.text = text2;
2160
+ ResultFormatter.unknown(decodeResult, text);
1891
2161
  }
1892
2162
  if (decodeResult.decoded) {
1893
2163
  if (!decodeResult.remaining.text)
@@ -1983,23 +2253,14 @@ var Label_80 = class extends DecoderPlugin {
1983
2253
  break;
1984
2254
  }
1985
2255
  case "FOB": {
1986
- decodeResult.raw.fuel_on_board = match.groups.value;
1987
- decodeResult.formatted.items.push({
1988
- type: "fuel_on_board",
1989
- code: "FOB",
1990
- label: this.descriptions[match.groups.field],
1991
- value: decodeResult.raw.fuel_on_board
1992
- });
2256
+ const fob = Number(match.groups.value);
2257
+ if (!isNaN(fob)) {
2258
+ ResultFormatter.currentFuel(decodeResult, fob);
2259
+ }
1993
2260
  break;
1994
2261
  }
1995
2262
  case "HDG": {
1996
- decodeResult.raw.heading = Number(match.groups.value);
1997
- decodeResult.formatted.items.push({
1998
- type: "heading",
1999
- code: "HDG",
2000
- label: this.descriptions[match.groups.field],
2001
- value: decodeResult.raw.heading
2002
- });
2263
+ ResultFormatter.heading(decodeResult, Number(match.groups.value));
2003
2264
  break;
2004
2265
  }
2005
2266
  case "MCH": {
@@ -2078,33 +2339,33 @@ var Label_83 = class extends DecoderPlugin {
2078
2339
  decodeResult.decoder.name = this.name;
2079
2340
  decodeResult.message = message;
2080
2341
  decodeResult.formatted.description = "Airline Defined";
2081
- let text2 = message.text;
2082
- if (text2.match(/^M\d{2}A\w{6}/)) {
2342
+ let text = message.text;
2343
+ if (text.match(/^M\d{2}A\w{6}/)) {
2083
2344
  ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
2084
- text2 = text2.substring(10);
2345
+ text = text.substring(10);
2085
2346
  }
2086
2347
  decodeResult.decoded = true;
2087
- if (text2.substring(0, 10) === "4DH3 ETAT2") {
2088
- const fields = text2.split(/\s+/);
2348
+ if (text.substring(0, 10) === "4DH3 ETAT2") {
2349
+ const fields = text.split(/\s+/);
2089
2350
  if (fields[2].length > 5) {
2090
2351
  decodeResult.raw.day_of_month = fields[2].substring(5);
2091
2352
  }
2092
- decodeResult.remaining.text = fields[2].substring(0, 4);
2353
+ ResultFormatter.unknown(decodeResult, fields[2].substring(0, 4));
2093
2354
  const subfields = fields[3].split("/");
2094
2355
  ResultFormatter.departureAirport(decodeResult, subfields[0]);
2095
2356
  ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
2096
2357
  ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
2097
2358
  ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[6] + "00"));
2098
- } else if (text2.substring(0, 5) === "001PR") {
2099
- decodeResult.raw.day_of_month = text2.substring(5, 7);
2100
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text2.substring(13, 28).replace(/\./g, ""));
2359
+ } else if (text.substring(0, 5) === "001PR") {
2360
+ decodeResult.raw.day_of_month = text.substring(5, 7);
2361
+ const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, ""));
2101
2362
  if (position) {
2102
2363
  ResultFormatter.position(decodeResult, position);
2103
2364
  }
2104
- ResultFormatter.altitude(decodeResult, Number(text2.substring(28, 33)));
2105
- decodeResult.remaining.text = text2.substring(33);
2365
+ ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
2366
+ ResultFormatter.unknown(decodeResult, text.substring(33));
2106
2367
  } else {
2107
- const fields = text2.replace(/\s/g, "").split(",");
2368
+ const fields = text.replace(/\s/g, "").split(",");
2108
2369
  if (fields.length === 9) {
2109
2370
  ResultFormatter.departureAirport(decodeResult, fields[0]);
2110
2371
  ResultFormatter.arrivalAirport(decodeResult, fields[1]);
@@ -2118,12 +2379,12 @@ var Label_83 = class extends DecoderPlugin {
2118
2379
  }
2119
2380
  );
2120
2381
  ResultFormatter.altitude(decodeResult, Number(fields[5]));
2121
- ResultFormatter.groundspeed(decodeResult, fields[6]);
2122
- ResultFormatter.heading(decodeResult, fields[7]);
2123
- decodeResult.remaining.text = fields[8];
2382
+ ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
2383
+ ResultFormatter.heading(decodeResult, Number(fields[7]));
2384
+ ResultFormatter.unknown(decodeResult, fields[8]);
2124
2385
  } else {
2125
2386
  decodeResult.decoded = false;
2126
- decodeResult.remaining.text = message.text;
2387
+ ResultFormatter.unknown(decodeResult, message.text);
2127
2388
  }
2128
2389
  }
2129
2390
  if (decodeResult.decoded) {
@@ -2153,7 +2414,7 @@ var Label_8E = class extends DecoderPlugin {
2153
2414
  decodeResult.message = message;
2154
2415
  const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
2155
2416
  const results = message.text.match(regex);
2156
- if (results) {
2417
+ if (results?.groups) {
2157
2418
  if (options.debug) {
2158
2419
  console.log(`Label 8E ETA: groups`);
2159
2420
  console.log(results.groups);
@@ -2204,7 +2465,8 @@ var Label_ColonComma = class extends DecoderPlugin {
2204
2465
  decodeResult.formatted.items.push({
2205
2466
  type: "frequency",
2206
2467
  label: "Frequency",
2207
- value: `${decodeResult.raw.frequency} MHz`
2468
+ value: `${decodeResult.raw.frequency} MHz`,
2469
+ code: "FREQ"
2208
2470
  });
2209
2471
  decodeResult.decoded = true;
2210
2472
  decodeResult.decoder.decodeLevel = "full";
@@ -2212,240 +2474,72 @@ var Label_ColonComma = class extends DecoderPlugin {
2212
2474
  }
2213
2475
  };
2214
2476
 
2215
- // lib/plugins/Label_H1_FLR.ts
2216
- var Label_H1_FLR = class extends DecoderPlugin {
2217
- name = "label-h1-flr";
2218
- qualifiers() {
2219
- return {
2220
- labels: ["H1"],
2221
- preambles: ["FLR", "#CFBFLR"]
2222
- };
2223
- }
2224
- decode(message, options = {}) {
2225
- let decodeResult = this.defaultResult();
2226
- decodeResult.decoder.name = this.name;
2227
- decodeResult.formatted.description = "Fault Log Report";
2228
- decodeResult.message = message;
2229
- const parts = message.text.split("/FR");
2230
- if (parts.length > 1) {
2231
- decodeResult.remaining.text = "";
2232
- const fields = parts[0].split("/");
2233
- for (let i = 1; i < fields.length; i++) {
2234
- const field = fields[i];
2235
- if (field.startsWith("PN")) {
2236
- processUnknown(decodeResult, "/" + field);
2237
- } else {
2238
- processUnknown(decodeResult, "/" + field);
2239
- }
2477
+ // lib/utils/flight_plan_utils.ts
2478
+ var FlightPlanUtils = class _FlightPlanUtils {
2479
+ /**
2480
+ * Processes flight plan data
2481
+ *
2482
+ * Expected format is [header, key1, val1, ... keyN, valN]
2483
+ *
2484
+ * @param decodeResult - results
2485
+ * @param data - original message split by ':'
2486
+ * @returns whether all fields were processed or not
2487
+ */
2488
+ static processFlightPlan(decodeResult, data) {
2489
+ let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
2490
+ for (let i = 1; i < data.length; i += 2) {
2491
+ const key = data[i];
2492
+ const value = data[i + 1];
2493
+ switch (key) {
2494
+ case "A":
2495
+ addProcedure(decodeResult, value, "arrival");
2496
+ break;
2497
+ case "AA":
2498
+ addArrivalAirport(decodeResult, value);
2499
+ break;
2500
+ case "AP":
2501
+ addProcedure(decodeResult, value, "approach");
2502
+ break;
2503
+ case "CR":
2504
+ addCompanyRoute(decodeResult, value);
2505
+ break;
2506
+ case "D":
2507
+ addProcedure(decodeResult, value, "departure");
2508
+ break;
2509
+ case "DA":
2510
+ addDepartureAirport(decodeResult, value);
2511
+ break;
2512
+ case "F":
2513
+ addRoute(decodeResult, value);
2514
+ break;
2515
+ case "R":
2516
+ addRunway(decodeResult, value);
2517
+ break;
2518
+ // case 'WS': // something about routes, has altitude, so current parsing won't work
2519
+ // break;
2520
+ default:
2521
+ if (allKnownFields) {
2522
+ decodeResult.remaining.text = "";
2523
+ allKnownFields = false;
2524
+ }
2525
+ decodeResult.remaining.text += `:${key}:${value}`;
2526
+ decodeResult.decoder.decodeLevel = "partial";
2240
2527
  }
2241
- const data = parts[1].substring(0, 20);
2242
- const msg = parts[1].substring(20);
2243
- const datetime = data.substring(0, 12);
2244
- const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
2245
- processUnknown(decodeResult, data.substring(12));
2246
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
2247
- decodeResult.raw.fault_message = msg;
2528
+ }
2529
+ return allKnownFields;
2530
+ }
2531
+ static parseHeader(decodeResult, header) {
2532
+ let allKnownFields = true;
2533
+ if (header.startsWith("RF")) {
2248
2534
  decodeResult.formatted.items.push({
2249
- type: "fault",
2250
- code: "FR",
2251
- label: "Fault Report",
2252
- value: decodeResult.raw.fault_message
2535
+ type: "status",
2536
+ code: "ROUTE_STATUS",
2537
+ label: "Route Status",
2538
+ value: "Route Filed"
2253
2539
  });
2254
- decodeResult.decoded = true;
2255
- decodeResult.decoder.decodeLevel = "partial";
2256
- } else {
2257
- if (options.debug) {
2258
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
2259
- }
2260
- decodeResult.remaining.text = message.text;
2261
- decodeResult.decoded = false;
2262
- decodeResult.decoder.decodeLevel = "none";
2263
- }
2264
- return decodeResult;
2265
- }
2266
- };
2267
- function processUnknown(decodeResult, value) {
2268
- decodeResult.remaining.text += value;
2269
- }
2270
-
2271
- // lib/plugins/Label_H1_OHMA.ts
2272
- import * as zlib from "minizlib";
2273
- var Label_H1_OHMA = class extends DecoderPlugin {
2274
- name = "label-h1-ohma";
2275
- qualifiers() {
2276
- return {
2277
- labels: ["H1"],
2278
- preambles: ["OHMA", "/RTNBOCR.OHMA", "#T1B/RTNBOCR.OHMA"]
2279
- };
2280
- }
2281
- decode(message, options = {}) {
2282
- let decodeResult = this.defaultResult();
2283
- decodeResult.decoder.name = this.name;
2284
- decodeResult.formatted.description = "OHMA Message";
2285
- decodeResult.message = message;
2286
- decodeResult.remaining.text = "";
2287
- const data = message.text.split("OHMA")[1];
2288
- try {
2289
- const compressedBuffer = Buffer.from(data, "base64");
2290
- const decompress = new zlib.Inflate({ windowBits: 15 });
2291
- decompress.write(compressedBuffer);
2292
- decompress.flush(zlib.constants.Z_SYNC_FLUSH);
2293
- const result = decompress.read();
2294
- const jsonText = result.toString();
2295
- let formattedMsg;
2296
- let jsonMessage;
2297
- try {
2298
- jsonMessage = JSON.parse(jsonText).message;
2299
- } catch {
2300
- jsonMessage = jsonText;
2301
- }
2302
- try {
2303
- const ohmaMsg = JSON.parse(jsonMessage);
2304
- formattedMsg = JSON.stringify(ohmaMsg, null, 2);
2305
- } catch {
2306
- formattedMsg = jsonMessage;
2307
- }
2308
- decodeResult.decoded = true;
2309
- decodeResult.decoder.decodeLevel = "full";
2310
- decodeResult.raw.ohma = jsonText;
2311
- decodeResult.formatted.items.push({
2312
- type: "ohma",
2313
- code: "OHMA",
2314
- label: "OHMA Downlink",
2315
- value: formattedMsg
2316
- });
2317
- } catch (e) {
2318
- if (options.debug) {
2319
- console.log(`Decoder: Unknown H1 OHMA message: ${message.text}`, e);
2320
- }
2321
- decodeResult.remaining.text += message.text;
2322
- decodeResult.decoded = false;
2323
- decodeResult.decoder.decodeLevel = "none";
2324
- }
2325
- return decodeResult;
2326
- }
2327
- };
2328
-
2329
- // lib/plugins/Label_H1_WRN.ts
2330
- var Label_H1_WRN = class extends DecoderPlugin {
2331
- name = "label-h1-wrn";
2332
- qualifiers() {
2333
- return {
2334
- labels: ["H1"],
2335
- preambles: ["WRN", "#CFBWRN"]
2336
- };
2337
- }
2338
- decode(message, options = {}) {
2339
- let decodeResult = this.defaultResult();
2340
- decodeResult.decoder.name = this.name;
2341
- decodeResult.formatted.description = "Warning Message";
2342
- decodeResult.message = message;
2343
- const parts = message.text.split("/WN");
2344
- if (parts.length > 1) {
2345
- decodeResult.remaining.text = "";
2346
- const fields = parts[0].split("/");
2347
- for (let i = 1; i < fields.length; i++) {
2348
- const field = fields[i];
2349
- if (field.startsWith("PN")) {
2350
- processUnknown2(decodeResult, "/" + field);
2351
- } else {
2352
- processUnknown2(decodeResult, "/" + field);
2353
- }
2354
- }
2355
- const data = parts[1].substring(0, 20);
2356
- const msg = parts[1].substring(20);
2357
- const datetime = data.substring(0, 12);
2358
- const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
2359
- processUnknown2(decodeResult, data.substring(12));
2360
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
2361
- decodeResult.raw.warning_message = msg;
2362
- decodeResult.formatted.items.push({
2363
- type: "warning",
2364
- code: "WRN",
2365
- label: "Warning Message",
2366
- value: decodeResult.raw.warning_message
2367
- });
2368
- decodeResult.decoded = true;
2369
- decodeResult.decoder.decodeLevel = "partial";
2370
- } else {
2371
- if (options.debug) {
2372
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
2373
- }
2374
- decodeResult.remaining.text = message.text;
2375
- decodeResult.decoded = false;
2376
- decodeResult.decoder.decodeLevel = "none";
2377
- }
2378
- return decodeResult;
2379
- }
2380
- };
2381
- function processUnknown2(decodeResult, value) {
2382
- decodeResult.remaining.text += value;
2383
- }
2384
-
2385
- // lib/utils/flight_plan_utils.ts
2386
- var FlightPlanUtils = class _FlightPlanUtils {
2387
- /**
2388
- * Processes flight plan data
2389
- *
2390
- * Expected format is [header, key1, val1, ... keyN, valN]
2391
- *
2392
- * @param decodeResult - results
2393
- * @param data - original message split by ':'
2394
- * @returns whether all fields were processed or not
2395
- */
2396
- static processFlightPlan(decodeResult, data) {
2397
- let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
2398
- for (let i = 1; i < data.length; i += 2) {
2399
- const key = data[i];
2400
- const value = data[i + 1];
2401
- switch (key) {
2402
- case "A":
2403
- addProcedure(decodeResult, value, "arrival");
2404
- break;
2405
- case "AA":
2406
- addArrivalAirport(decodeResult, value);
2407
- break;
2408
- case "AP":
2409
- addProcedure(decodeResult, value, "approach");
2410
- break;
2411
- case "CR":
2412
- addCompanyRoute(decodeResult, value);
2413
- break;
2414
- case "D":
2415
- addProcedure(decodeResult, value, "departure");
2416
- break;
2417
- case "DA":
2418
- addDepartureAirport(decodeResult, value);
2419
- break;
2420
- case "F":
2421
- addRoute(decodeResult, value);
2422
- break;
2423
- case "R":
2424
- addRunway(decodeResult, value);
2425
- break;
2426
- default:
2427
- if (allKnownFields) {
2428
- decodeResult.remaining.text = "";
2429
- allKnownFields = false;
2430
- }
2431
- decodeResult.remaining.text += `:${key}:${value}`;
2432
- decodeResult.decoder.decodeLevel = "partial";
2433
- }
2434
- }
2435
- return allKnownFields;
2436
- }
2437
- static parseHeader(decodeResult, header) {
2438
- let allKnownFields = true;
2439
- if (header.startsWith("RF")) {
2440
- decodeResult.formatted.items.push({
2441
- type: "status",
2442
- code: "ROUTE_STATUS",
2443
- label: "Route Status",
2444
- value: "Route Filed"
2445
- });
2446
- decodeResult.raw.route_status = "RF";
2447
- if (header.length > 2) {
2448
- addRoute(decodeResult, header.substring(2));
2540
+ decodeResult.raw.route_status = "RF";
2541
+ if (header.length > 2) {
2542
+ addRoute(decodeResult, header.substring(2));
2449
2543
  }
2450
2544
  } else if (header.startsWith("RP")) {
2451
2545
  decodeResult.raw.route_status = "RP";
@@ -2485,13 +2579,7 @@ function addRunway(decodeResult, value) {
2485
2579
  }
2486
2580
  function addRoute(decodeResult, value) {
2487
2581
  const route = value.split(".");
2488
- decodeResult.raw.route = { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) };
2489
- decodeResult.formatted.items.push({
2490
- type: "aircraft_route",
2491
- code: "ROUTE",
2492
- label: "Aircraft Route",
2493
- value: RouteUtils.routeToString(decodeResult.raw.route)
2494
- });
2582
+ ResultFormatter.route(decodeResult, { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) });
2495
2583
  }
2496
2584
  function addProcedure(decodeResult, value, type) {
2497
2585
  if (decodeResult.raw.procedures === void 0) {
@@ -2577,21 +2665,23 @@ var H1Helper = class {
2577
2665
  } else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
2578
2666
  FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
2579
2667
  } else if (fields[i].startsWith("PR")) {
2580
- decodeResult.remaining.text += "/" + fields[i];
2668
+ ResultFormatter.unknown(decodeResult, fields[i], "/");
2581
2669
  } else if (fields[i].startsWith("AF")) {
2582
2670
  processAirField(decodeResult, fields[i].substring(2).split(","));
2583
2671
  } else if (fields[i].startsWith("TD")) {
2584
2672
  processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
2585
2673
  } else if (fields[i].startsWith("FX")) {
2586
- decodeResult.raw.free_text = fields[i].substring(2);
2587
- decodeResult.formatted.items.push({
2588
- type: "text",
2589
- code: "TEXT",
2590
- label: "Free Text",
2591
- value: decodeResult.raw.free_text
2592
- });
2674
+ ResultFormatter.freetext(decodeResult, fields[i].substring(2));
2675
+ } else if (fields[i].startsWith("ET")) {
2676
+ if (fields[i].length === 7) {
2677
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3) + "00"));
2678
+ } else if (fields[i].length === 8) {
2679
+ ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4) + "00"));
2680
+ } else {
2681
+ ResultFormatter.unknown(decodeResult, fields[i], "/");
2682
+ }
2593
2683
  } else {
2594
- decodeResult.remaining.text += "/" + fields[i];
2684
+ ResultFormatter.unknown(decodeResult, fields[i], "/");
2595
2685
  }
2596
2686
  }
2597
2687
  if (decodeResult.formatted.items.length > 0) {
@@ -2605,7 +2695,7 @@ function processAirField(decodeResult, data) {
2605
2695
  ResultFormatter.departureAirport(decodeResult, data[0]);
2606
2696
  ResultFormatter.arrivalAirport(decodeResult, data[1]);
2607
2697
  } else {
2608
- decodeResult.remaining.text += "AF/" + data.join(",");
2698
+ ResultFormatter.unknown(decodeResult, data.join(","), "AF/");
2609
2699
  }
2610
2700
  }
2611
2701
  function processTimeOfDeparture(decodeResult, data) {
@@ -2625,7 +2715,7 @@ function processTimeOfDeparture(decodeResult, data) {
2625
2715
  value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
2626
2716
  });
2627
2717
  } else {
2628
- decodeResult.remaining.text += "/TD" + data.join(",");
2718
+ ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
2629
2719
  }
2630
2720
  }
2631
2721
  function processIdentification(decodeResult, data) {
@@ -2641,7 +2731,7 @@ function processDT(decodeResult, data) {
2641
2731
  if (!decodeResult.raw.arrival_icao) {
2642
2732
  ResultFormatter.arrivalAirport(decodeResult, data[0]);
2643
2733
  } else if (decodeResult.raw.arrival_icao != data[0]) {
2644
- decodeResult.remaining.text += "/" + data;
2734
+ ResultFormatter.unknownArr(decodeResult, data);
2645
2735
  }
2646
2736
  if (data.length > 1) {
2647
2737
  ResultFormatter.arrivalRunway(decodeResult, data[1]);
@@ -2656,7 +2746,7 @@ function processDT(decodeResult, data) {
2656
2746
  ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
2657
2747
  }
2658
2748
  if (data.length > 5) {
2659
- decodeResult.remaining.text += "," + data.slice(5).join(",");
2749
+ ResultFormatter.unknownArr(decodeResult, data);
2660
2750
  }
2661
2751
  }
2662
2752
  function processLR(decodeResult, data) {
@@ -2681,9 +2771,9 @@ function parseMessageType(decodeResult, messageType) {
2681
2771
  return processMessageType(decodeResult, type);
2682
2772
  } else if (parts.length == 2) {
2683
2773
  if (parts[0].length > 0) {
2684
- decodeResult.remaining.text += parts[0].substring(0, 3);
2774
+ ResultFormatter.unknown(decodeResult, parts[0].substring(0, 3));
2685
2775
  decodeResult.raw.flight_number = parts[0].substring(3);
2686
- decodeResult.remaining.text += "#" + (parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3));
2776
+ ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
2687
2777
  }
2688
2778
  const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
2689
2779
  if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
@@ -2691,7 +2781,7 @@ function parseMessageType(decodeResult, messageType) {
2691
2781
  }
2692
2782
  processMessageType(decodeResult, type);
2693
2783
  } else {
2694
- decodeResult.remaining.text += messageType;
2784
+ ResultFormatter.unknown(decodeResult, messageType);
2695
2785
  }
2696
2786
  }
2697
2787
  function processMessageType(decodeResult, type) {
@@ -2805,16 +2895,205 @@ var Label_H1 = class extends DecoderPlugin {
2805
2895
  let decodeResult = this.defaultResult();
2806
2896
  decodeResult.decoder.name = this.name;
2807
2897
  decodeResult.message = message;
2808
- decodeResult.remaining.text = "";
2809
2898
  const msg = message.text.replace(/\n|\r/g, "");
2810
2899
  const decoded = H1Helper.decodeH1Message(decodeResult, msg);
2811
2900
  decodeResult.decoded = decoded;
2812
- decodeResult.decoder.decodeLevel = decodeResult.remaining.text.length === 0 ? "full" : "partial";
2901
+ decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
2813
2902
  if (decodeResult.formatted.items.length === 0) {
2814
2903
  if (options.debug) {
2815
2904
  console.log(`Decoder: Unknown H1 message: ${message.text}`);
2816
2905
  }
2817
- decodeResult.remaining.text = message.text;
2906
+ ResultFormatter.unknown(decodeResult, message.text);
2907
+ decodeResult.decoded = false;
2908
+ decodeResult.decoder.decodeLevel = "none";
2909
+ }
2910
+ return decodeResult;
2911
+ }
2912
+ };
2913
+
2914
+ // lib/plugins/Label_H1_FLR.ts
2915
+ var Label_H1_FLR = class extends DecoderPlugin {
2916
+ name = "label-h1-flr";
2917
+ qualifiers() {
2918
+ return {
2919
+ labels: ["H1"],
2920
+ preambles: ["FLR", "#CFBFLR"]
2921
+ };
2922
+ }
2923
+ decode(message, options = {}) {
2924
+ let decodeResult = this.defaultResult();
2925
+ decodeResult.decoder.name = this.name;
2926
+ decodeResult.formatted.description = "Fault Log Report";
2927
+ decodeResult.message = message;
2928
+ const parts = message.text.split("/FR");
2929
+ if (parts.length > 1) {
2930
+ const fields = parts[0].split("/");
2931
+ for (let i = 1; i < fields.length; i++) {
2932
+ const field = fields[i];
2933
+ ResultFormatter.unknown(decodeResult, field, "/");
2934
+ }
2935
+ const data = parts[1].substring(0, 20);
2936
+ const msg = parts[1].substring(20);
2937
+ const datetime = data.substring(0, 12);
2938
+ const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
2939
+ ResultFormatter.unknown(decodeResult, data.substring(12), "/");
2940
+ decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
2941
+ decodeResult.raw.fault_message = msg;
2942
+ decodeResult.formatted.items.push({
2943
+ type: "fault",
2944
+ code: "FR",
2945
+ label: "Fault Report",
2946
+ value: decodeResult.raw.fault_message
2947
+ });
2948
+ decodeResult.decoded = true;
2949
+ decodeResult.decoder.decodeLevel = "partial";
2950
+ } else {
2951
+ if (options.debug) {
2952
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
2953
+ }
2954
+ ResultFormatter.unknown(decodeResult, message.text);
2955
+ decodeResult.decoded = false;
2956
+ decodeResult.decoder.decodeLevel = "none";
2957
+ }
2958
+ return decodeResult;
2959
+ }
2960
+ };
2961
+
2962
+ // lib/plugins/Label_H1_OHMA.ts
2963
+ import * as zlib from "minizlib";
2964
+ var Label_H1_OHMA = class extends DecoderPlugin {
2965
+ name = "label-h1-ohma";
2966
+ qualifiers() {
2967
+ return {
2968
+ labels: ["H1"],
2969
+ preambles: ["OHMA", "/RTNBOCR.OHMA", "#T1B/RTNBOCR.OHMA"]
2970
+ };
2971
+ }
2972
+ decode(message, options = {}) {
2973
+ let decodeResult = this.defaultResult();
2974
+ decodeResult.decoder.name = this.name;
2975
+ decodeResult.formatted.description = "OHMA Message";
2976
+ decodeResult.message = message;
2977
+ const data = message.text.split("OHMA")[1];
2978
+ try {
2979
+ const compressedBuffer = Buffer.from(data, "base64");
2980
+ const decompress = new zlib.Inflate({ windowBits: 15 });
2981
+ decompress.write(compressedBuffer);
2982
+ decompress.flush(zlib.constants.Z_SYNC_FLUSH);
2983
+ const result = decompress.read();
2984
+ const jsonText = result.toString();
2985
+ let formattedMsg;
2986
+ let jsonMessage;
2987
+ try {
2988
+ jsonMessage = JSON.parse(jsonText).message;
2989
+ } catch {
2990
+ jsonMessage = jsonText;
2991
+ }
2992
+ try {
2993
+ const ohmaMsg = JSON.parse(jsonMessage);
2994
+ formattedMsg = JSON.stringify(ohmaMsg, null, 2);
2995
+ } catch {
2996
+ formattedMsg = jsonMessage;
2997
+ }
2998
+ decodeResult.decoded = true;
2999
+ decodeResult.decoder.decodeLevel = "full";
3000
+ decodeResult.raw.ohma = jsonText;
3001
+ decodeResult.formatted.items.push({
3002
+ type: "ohma",
3003
+ code: "OHMA",
3004
+ label: "OHMA Downlink",
3005
+ value: formattedMsg
3006
+ });
3007
+ } catch (e) {
3008
+ if (options.debug) {
3009
+ console.log(`Decoder: Unknown H1 OHMA message: ${message.text}`, e);
3010
+ }
3011
+ ResultFormatter.unknown(decodeResult, message.text);
3012
+ decodeResult.decoded = false;
3013
+ decodeResult.decoder.decodeLevel = "none";
3014
+ }
3015
+ return decodeResult;
3016
+ }
3017
+ };
3018
+
3019
+ // lib/plugins/Label_H1_StarPOS.ts
3020
+ var Label_H1_StarPOS = class extends DecoderPlugin {
3021
+ name = "label-h1-star-pos";
3022
+ qualifiers() {
3023
+ return {
3024
+ labels: ["H1"],
3025
+ preambles: ["*POS"]
3026
+ };
3027
+ }
3028
+ decode(message, options = {}) {
3029
+ let decodeResult = this.defaultResult();
3030
+ decodeResult.decoder.name = this.name;
3031
+ decodeResult.formatted.description = "Position Report";
3032
+ decodeResult.message = message;
3033
+ const msg = message.text;
3034
+ if (msg.length !== 43 || !msg.startsWith("*POS")) {
3035
+ if (options.debug) {
3036
+ console.log(`Decoder: Unknown H1 message: ${msg}`);
3037
+ }
3038
+ ResultFormatter.unknown(decodeResult, msg);
3039
+ decodeResult.decoded = false;
3040
+ decodeResult.decoder.decodeLevel = "none";
3041
+ return decodeResult;
3042
+ }
3043
+ decodeResult.raw.month = Number(msg.substring(4, 6));
3044
+ decodeResult.raw.day_of_month = Number(msg.substring(6, 8));
3045
+ ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12) + "00"));
3046
+ ResultFormatter.position(decodeResult, {
3047
+ // Deg Min, no sec
3048
+ latitude: CoordinateUtils.getDirection(msg.substring(12, 13)) * (Number(msg.substring(13, 15)) + Number(msg.substring(15, 17)) / 60),
3049
+ longitude: CoordinateUtils.getDirection(msg.substring(17, 18)) * (Number(msg.substring(18, 21)) + Number(msg.substring(21, 23)) / 60)
3050
+ });
3051
+ ResultFormatter.altitude(decodeResult, Number(msg.substring(23, 28)));
3052
+ ResultFormatter.unknown(decodeResult, msg.substring(28));
3053
+ decodeResult.decoded = true;
3054
+ decodeResult.decoder.decodeLevel = "partial";
3055
+ return decodeResult;
3056
+ }
3057
+ };
3058
+
3059
+ // lib/plugins/Label_H1_WRN.ts
3060
+ var Label_H1_WRN = class extends DecoderPlugin {
3061
+ name = "label-h1-wrn";
3062
+ qualifiers() {
3063
+ return {
3064
+ labels: ["H1"],
3065
+ preambles: ["WRN", "#CFBWRN"]
3066
+ };
3067
+ }
3068
+ decode(message, options = {}) {
3069
+ let decodeResult = this.defaultResult();
3070
+ decodeResult.decoder.name = this.name;
3071
+ decodeResult.formatted.description = "Warning Message";
3072
+ decodeResult.message = message;
3073
+ const parts = message.text.split("/WN");
3074
+ if (parts.length > 1) {
3075
+ const fields = parts[0].split("/");
3076
+ ResultFormatter.unknownArr(decodeResult, fields.slice(1), "/");
3077
+ const data = parts[1].substring(0, 20);
3078
+ const msg = parts[1].substring(20);
3079
+ const datetime = data.substring(0, 12);
3080
+ const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
3081
+ ResultFormatter.unknown(decodeResult, data.substring(12), "/");
3082
+ decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
3083
+ decodeResult.raw.warning_message = msg;
3084
+ decodeResult.formatted.items.push({
3085
+ type: "warning",
3086
+ code: "WRN",
3087
+ label: "Warning Message",
3088
+ value: decodeResult.raw.warning_message
3089
+ });
3090
+ decodeResult.decoded = true;
3091
+ decodeResult.decoder.decodeLevel = "partial";
3092
+ } else {
3093
+ if (options.debug) {
3094
+ console.log(`Decoder: Unknown H1 message: ${message.text}`);
3095
+ }
3096
+ ResultFormatter.unknown(decodeResult, message.text);
2818
3097
  decodeResult.decoded = false;
2819
3098
  decodeResult.decoder.decodeLevel = "none";
2820
3099
  }
@@ -2845,25 +3124,18 @@ var Label_HX = class extends DecoderPlugin {
2845
3124
  let londir = parts[4].substring(0, 1);
2846
3125
  let londeg = Number(parts[4].substring(1, 4));
2847
3126
  let lonmin = Number(parts[4].substring(4, 8));
2848
- decodeResult.raw.position = {
3127
+ let pos = {
2849
3128
  latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
2850
3129
  longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
2851
3130
  };
2852
- decodeResult.remaining.text = parts.slice(5).join(" ");
3131
+ ResultFormatter.unknownArr(decodeResult, parts.slice(5), " ");
3132
+ ResultFormatter.position(decodeResult, pos);
2853
3133
  } else if (parts[2] === "43") {
2854
3134
  ResultFormatter.departureAirport(decodeResult, parts[3]);
2855
- decodeResult.remaining.text = parts.slice(4).join(" ");
3135
+ ResultFormatter.unknownArr(decodeResult, parts.slice(4), " ");
2856
3136
  } else {
2857
3137
  decodeResult.decoded = false;
2858
3138
  }
2859
- if (decodeResult.raw.position) {
2860
- decodeResult.formatted.items.push({
2861
- type: "aircraft_position",
2862
- code: "POS",
2863
- label: "Aircraft Position",
2864
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
2865
- });
2866
- }
2867
3139
  if (decodeResult.decoded) {
2868
3140
  if (!decodeResult.remaining.text)
2869
3141
  decodeResult.decoder.decodeLevel = "full";
@@ -2893,7 +3165,7 @@ var Label_SQ = class extends DecoderPlugin {
2893
3165
  if (decodeResult.raw.version === "2") {
2894
3166
  const regex = /0(\d)X(?<org>\w)(?<iata>\w\w\w)(?<icao>\w\w\w\w)(?<station>\d)(?<lat>\d+)(?<latd>[NS])(?<lng>\d+)(?<lngd>[EW])V(?<vfreq>\d+)\/.*/;
2895
3167
  const result = message.text.match(regex);
2896
- if (result && result.length >= 8) {
3168
+ if (result?.groups && result.length >= 8) {
2897
3169
  decodeResult.raw.groundStation = {
2898
3170
  number: result.groups.station,
2899
3171
  iataCode: result.groups.iata,
@@ -2903,7 +3175,7 @@ var Label_SQ = class extends DecoderPlugin {
2903
3175
  longitude: Number(result.groups.lng) / 100 * (result.groups.lngd === "W" ? -1 : 1)
2904
3176
  }
2905
3177
  };
2906
- decodeResult.raw.vdlFrequency = result.groups.vfreq / 1e3;
3178
+ decodeResult.raw.vdlFrequency = Number(result.groups.vfreq) / 1e3;
2907
3179
  }
2908
3180
  }
2909
3181
  decodeResult.formatted.description = "Ground Station Squitter";
@@ -2994,31 +3266,11 @@ var Label_QR = class extends DecoderPlugin {
2994
3266
  decode(message, options = {}) {
2995
3267
  const decodeResult = this.defaultResult();
2996
3268
  decodeResult.decoder.name = this.name;
2997
- decodeResult.raw.origin = message.text.substring(0, 4);
2998
- decodeResult.raw.destination = message.text.substring(4, 8);
2999
- decodeResult.raw.wheels_on = message.text.substring(8, 12);
3000
- decodeResult.remaining.text = message.text.substring(12);
3001
3269
  decodeResult.formatted.description = "ON Report";
3002
- decodeResult.formatted.items = [
3003
- {
3004
- type: "origin",
3005
- code: "ORG",
3006
- label: "Origin",
3007
- value: decodeResult.raw.origin
3008
- },
3009
- {
3010
- type: "destination",
3011
- code: "DST",
3012
- label: "Destination",
3013
- value: decodeResult.raw.destination
3014
- },
3015
- {
3016
- type: "wheels_on",
3017
- code: "WON",
3018
- label: "Wheels ON",
3019
- value: decodeResult.raw.wheels_on
3020
- }
3021
- ];
3270
+ ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3271
+ ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3272
+ ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
3273
+ ResultFormatter.unknown(decodeResult, message.text.substring(12));
3022
3274
  decodeResult.decoded = true;
3023
3275
  if (!decodeResult.remaining.text)
3024
3276
  decodeResult.decoder.decodeLevel = "full";
@@ -3039,31 +3291,11 @@ var Label_QP = class extends DecoderPlugin {
3039
3291
  decode(message, options = {}) {
3040
3292
  const decodeResult = this.defaultResult();
3041
3293
  decodeResult.decoder.name = this.name;
3042
- decodeResult.raw.origin = message.text.substring(0, 4);
3043
- decodeResult.raw.destination = message.text.substring(4, 8);
3044
- decodeResult.raw.gate_out = message.text.substring(8, 12);
3045
- decodeResult.remaining.text = message.text.substring(12);
3046
3294
  decodeResult.formatted.description = "OUT Report";
3047
- decodeResult.formatted.items = [
3048
- {
3049
- type: "origin",
3050
- code: "ORG",
3051
- label: "Origin",
3052
- value: decodeResult.raw.origin
3053
- },
3054
- {
3055
- type: "destination",
3056
- code: "DST",
3057
- label: "Destination",
3058
- value: decodeResult.raw.destination
3059
- },
3060
- {
3061
- type: "gate_out",
3062
- code: "GOUT",
3063
- label: "Gate OUT",
3064
- value: decodeResult.raw.gate_out
3065
- }
3066
- ];
3295
+ ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3296
+ ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3297
+ ResultFormatter.out(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
3298
+ ResultFormatter.unknown(decodeResult, message.text.substring(12));
3067
3299
  decodeResult.decoded = true;
3068
3300
  if (!decodeResult.remaining.text)
3069
3301
  decodeResult.decoder.decodeLevel = "full";
@@ -3084,31 +3316,11 @@ var Label_QS = class extends DecoderPlugin {
3084
3316
  decode(message, options = {}) {
3085
3317
  const decodeResult = this.defaultResult();
3086
3318
  decodeResult.decoder.name = this.name;
3087
- decodeResult.raw.origin = message.text.substring(0, 4);
3088
- decodeResult.raw.destination = message.text.substring(4, 8);
3089
- decodeResult.raw.gate_in = message.text.substring(8, 12);
3090
- decodeResult.remaining.text = message.text.substring(12);
3091
3319
  decodeResult.formatted.description = "IN Report";
3092
- decodeResult.formatted.items = [
3093
- {
3094
- type: "origin",
3095
- code: "ORG",
3096
- label: "Origin",
3097
- value: decodeResult.raw.origin
3098
- },
3099
- {
3100
- type: "destination",
3101
- code: "DST",
3102
- label: "Destination",
3103
- value: decodeResult.raw.destination
3104
- },
3105
- {
3106
- type: "gate_in",
3107
- code: "GIN",
3108
- label: "Gate IN",
3109
- value: decodeResult.raw.gate_in
3110
- }
3111
- ];
3320
+ ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3321
+ ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3322
+ ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
3323
+ ResultFormatter.unknown(decodeResult, message.text.substring(12));
3112
3324
  decodeResult.decoded = true;
3113
3325
  if (!decodeResult.remaining.text)
3114
3326
  decodeResult.decoder.decodeLevel = "full";
@@ -3133,43 +3345,30 @@ var Label_QQ = class extends DecoderPlugin {
3133
3345
  decodeResult.formatted.description = "OFF Report";
3134
3346
  ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3135
3347
  ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3136
- decodeResult.raw.wheels_off = message.text.substring(8, 12);
3137
3348
  if (message.text.substring(12, 19) === "\r\n001FE") {
3138
3349
  decodeResult.raw.day_of_month = message.text.substring(19, 21);
3139
- decodeResult.raw.wheels_off = message.text.substring(21, 27);
3350
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(21, 27)));
3140
3351
  let latdir = message.text.substring(27, 28);
3141
3352
  let latdeg = Number(message.text.substring(28, 30));
3142
3353
  let latmin = Number(message.text.substring(30, 34));
3143
3354
  let londir = message.text.substring(34, 35);
3144
3355
  let londeg = Number(message.text.substring(35, 38));
3145
3356
  let lonmin = Number(message.text.substring(38, 42));
3146
- decodeResult.raw.position = {
3357
+ let pos = {
3147
3358
  latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
3148
3359
  longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
3149
3360
  };
3150
- decodeResult.remaining.text = message.text.substring(42, 45);
3361
+ ResultFormatter.unknown(decodeResult, message.text.substring(42, 45));
3362
+ ResultFormatter.position(decodeResult, pos);
3151
3363
  if (decodeResult.remaining.text !== "---") {
3152
- ResultFormatter.groundspeed(decodeResult, message.text.substring(45, 48));
3364
+ ResultFormatter.groundspeed(decodeResult, Number(message.text.substring(45, 48)));
3153
3365
  } else {
3154
3366
  ResultFormatter.unknown(decodeResult, message.text.substring(45, 48));
3155
3367
  }
3156
3368
  ResultFormatter.unknown(decodeResult, message.text.substring(48));
3157
3369
  } else {
3158
- decodeResult.remaining.text = message.text.substring(12);
3159
- }
3160
- decodeResult.formatted.items.push({
3161
- type: "wheels_off",
3162
- code: "WOFF",
3163
- label: "Wheels OFF",
3164
- value: decodeResult.raw.wheels_off
3165
- });
3166
- if (decodeResult.raw.position) {
3167
- decodeResult.formatted.items.push({
3168
- type: "aircraft_position",
3169
- code: "POS",
3170
- label: "Aircraft Position",
3171
- value: CoordinateUtils.coordinateString(decodeResult.raw.position)
3172
- });
3370
+ ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
3371
+ ResultFormatter.unknown(decodeResult, message.text.substring(12));
3173
3372
  }
3174
3373
  decodeResult.decoded = true;
3175
3374
  if (!decodeResult.remaining.text)
@@ -4001,8 +4200,14 @@ var MessageDecoder = class {
4001
4200
  this.registerPlugin(new Label_15(this));
4002
4201
  this.registerPlugin(new Label_15_FST(this));
4003
4202
  this.registerPlugin(new Label_16_N_Space(this));
4203
+ this.registerPlugin(new Label_1L_3Line(this));
4204
+ this.registerPlugin(new Label_1L_070(this));
4205
+ this.registerPlugin(new Label_1L_660(this));
4206
+ this.registerPlugin(new Label_1L_Slash(this));
4004
4207
  this.registerPlugin(new Label_20_POS(this));
4005
4208
  this.registerPlugin(new Label_21_POS(this));
4209
+ this.registerPlugin(new Label_22_OFF(this));
4210
+ this.registerPlugin(new Label_22_POS(this));
4006
4211
  this.registerPlugin(new Label_24_Slash(this));
4007
4212
  this.registerPlugin(new Label_30_Slash_EA(this));
4008
4213
  this.registerPlugin(new Label_44_ETA(this));
@@ -4021,6 +4226,7 @@ var MessageDecoder = class {
4021
4226
  this.registerPlugin(new Label_H1_OHMA(this));
4022
4227
  this.registerPlugin(new Label_H1_WRN(this));
4023
4228
  this.registerPlugin(new Label_H1(this));
4229
+ this.registerPlugin(new Label_H1_StarPOS(this));
4024
4230
  this.registerPlugin(new Label_HX(this));
4025
4231
  this.registerPlugin(new Label_80(this));
4026
4232
  this.registerPlugin(new Label_83(this));