@airframes/acars-decoder 1.8.13 → 1.8.14

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
@@ -85,56 +85,6 @@ var IcaoDecoder = class _IcaoDecoder {
85
85
  }
86
86
  };
87
87
 
88
- // lib/DecoderPlugin.ts
89
- var DecoderPlugin = class {
90
- decoder;
91
- name = "unknown";
92
- defaultResult() {
93
- return {
94
- decoded: false,
95
- decoder: {
96
- name: "unknown",
97
- type: "pattern-match",
98
- decodeLevel: "none"
99
- },
100
- formatted: {
101
- description: "Unknown",
102
- items: []
103
- },
104
- raw: {},
105
- remaining: {}
106
- };
107
- }
108
- options;
109
- constructor(decoder, options = {}) {
110
- this.decoder = decoder;
111
- this.options = options;
112
- }
113
- id() {
114
- console.log(
115
- "DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
116
- );
117
- return "abstract_decoder_plugin";
118
- }
119
- meetsStateRequirements() {
120
- return true;
121
- }
122
- // onRegister(store: Store<any>) {
123
- // this.store = store;
124
- // }
125
- qualifiers() {
126
- const labels = [];
127
- return {
128
- labels
129
- };
130
- }
131
- decode(message) {
132
- const decodeResult = this.defaultResult();
133
- decodeResult.remaining.text = message.text;
134
- return decodeResult;
135
- }
136
- };
137
-
138
88
  // lib/utils/coordinate_utils.ts
139
89
  var CoordinateUtils = class _CoordinateUtils {
140
90
  /**
@@ -992,6 +942,99 @@ var ResultFormatter = class {
992
942
  }
993
943
  };
994
944
 
945
+ // lib/DecoderPlugin.ts
946
+ var DecoderPlugin = class {
947
+ decoder;
948
+ name = "unknown";
949
+ defaultResult() {
950
+ return {
951
+ decoded: false,
952
+ decoder: {
953
+ name: "unknown",
954
+ type: "pattern-match",
955
+ decodeLevel: "none"
956
+ },
957
+ formatted: {
958
+ description: "Unknown",
959
+ items: []
960
+ },
961
+ raw: {},
962
+ remaining: {}
963
+ };
964
+ }
965
+ /**
966
+ * Creates a DecodeResult pre-populated with the plugin name, description, and message.
967
+ * Replaces the common boilerplate at the start of every decode() method.
968
+ */
969
+ initResult(message, description) {
970
+ const result = this.defaultResult();
971
+ result.decoder.name = this.name;
972
+ result.formatted.description = description;
973
+ result.message = message;
974
+ return result;
975
+ }
976
+ /**
977
+ * Sets the decoded flag and decodeLevel on a result.
978
+ * If decoded is true and no explicit level is given, infers 'full' or 'partial'
979
+ * based on whether remaining.text is set.
980
+ */
981
+ setDecodeLevel(result, decoded, level) {
982
+ result.decoded = decoded;
983
+ if (decoded) {
984
+ result.decoder.decodeLevel = level ?? (result.remaining.text ? "partial" : "full");
985
+ } else {
986
+ result.decoder.decodeLevel = "none";
987
+ }
988
+ }
989
+ /**
990
+ * Logs a debug message prefixed with the plugin name, only if options.debug is true.
991
+ */
992
+ debug(options, ...args) {
993
+ if (options.debug) {
994
+ console.log(`[${this.name}]`, ...args);
995
+ }
996
+ }
997
+ /**
998
+ * Marks a result as a failed decode with 'none' level, sets the remaining text
999
+ * as unknown, and logs a debug message. Returns the result for convenient early return.
1000
+ */
1001
+ failUnknown(result, text, options = {}) {
1002
+ this.debug(options, `Unknown message: ${text}`);
1003
+ ResultFormatter.unknown(result, text);
1004
+ result.decoded = false;
1005
+ result.decoder.decodeLevel = "none";
1006
+ return result;
1007
+ }
1008
+ options;
1009
+ constructor(decoder, options = {}) {
1010
+ this.decoder = decoder;
1011
+ this.options = options;
1012
+ }
1013
+ id() {
1014
+ console.log(
1015
+ "DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
1016
+ );
1017
+ return "abstract_decoder_plugin";
1018
+ }
1019
+ meetsStateRequirements() {
1020
+ return true;
1021
+ }
1022
+ // onRegister(store: Store<any>) {
1023
+ // this.store = store;
1024
+ // }
1025
+ qualifiers() {
1026
+ const labels = [];
1027
+ return {
1028
+ labels
1029
+ };
1030
+ }
1031
+ decode(message, options = {}) {
1032
+ const decodeResult = this.defaultResult();
1033
+ decodeResult.remaining.text = message.text;
1034
+ return decodeResult;
1035
+ }
1036
+ };
1037
+
995
1038
  // lib/plugins/CBand.ts
996
1039
  var CBand = class extends DecoderPlugin {
997
1040
  name = "c-band";
@@ -2061,19 +2104,10 @@ var Label_10_POS = class extends DecoderPlugin {
2061
2104
  };
2062
2105
  }
2063
2106
  decode(message, options = {}) {
2064
- const decodeResult = this.defaultResult();
2065
- decodeResult.decoder.name = this.name;
2066
- decodeResult.formatted.description = "Position Report";
2067
- decodeResult.message = message;
2107
+ const decodeResult = this.initResult(message, "Position Report");
2068
2108
  const parts = message.text.split(",");
2069
2109
  if (parts.length !== 12) {
2070
- if (options.debug) {
2071
- console.log(`Decoder: Unknown 10 message: ${message.text}`);
2072
- }
2073
- ResultFormatter.unknown(decodeResult, message.text);
2074
- decodeResult.decoded = false;
2075
- decodeResult.decoder.decodeLevel = "none";
2076
- return decodeResult;
2110
+ return this.failUnknown(decodeResult, message.text, options);
2077
2111
  }
2078
2112
  const lat = parts[1].trim();
2079
2113
  const lon = parts[2].trim();
@@ -2088,8 +2122,7 @@ var Label_10_POS = class extends DecoderPlugin {
2088
2122
  ...parts.slice(3, 7),
2089
2123
  ...parts.slice(8)
2090
2124
  ]);
2091
- decodeResult.decoded = true;
2092
- decodeResult.decoder.decodeLevel = "partial";
2125
+ this.setDecodeLevel(decodeResult, true, "partial");
2093
2126
  return decodeResult;
2094
2127
  }
2095
2128
  };
@@ -2216,19 +2249,10 @@ var Label_12_POS = class extends DecoderPlugin {
2216
2249
  };
2217
2250
  }
2218
2251
  decode(message, options = {}) {
2219
- const decodeResult = this.defaultResult();
2220
- decodeResult.decoder.name = this.name;
2221
- decodeResult.formatted.description = "Position Report";
2222
- decodeResult.message = message;
2252
+ const decodeResult = this.initResult(message, "Position Report");
2223
2253
  const data = message.text.substring(3).split(",");
2224
2254
  if (!message.text.startsWith("POS") || data.length !== 12) {
2225
- if (options.debug) {
2226
- console.log(`Decoder: Unknown 12 message: ${message.text}`);
2227
- }
2228
- ResultFormatter.unknown(decodeResult, message.text);
2229
- decodeResult.decoded = false;
2230
- decodeResult.decoder.decodeLevel = "none";
2231
- return decodeResult;
2255
+ return this.failUnknown(decodeResult, message.text, options);
2232
2256
  }
2233
2257
  const lat = data[0].substring(0, 8);
2234
2258
  const lon = data[0].substring(8);
@@ -2262,8 +2286,7 @@ var Label_12_POS = class extends DecoderPlugin {
2262
2286
  ResultFormatter.departureAirport(decodeResult, data[9]);
2263
2287
  ResultFormatter.arrivalAirport(decodeResult, data[10]);
2264
2288
  ResultFormatter.unknown(decodeResult, data[11]);
2265
- decodeResult.decoded = true;
2266
- decodeResult.decoder.decodeLevel = "partial";
2289
+ this.setDecodeLevel(decodeResult, true, "partial");
2267
2290
  return decodeResult;
2268
2291
  }
2269
2292
  };
@@ -2376,10 +2399,7 @@ var Label_15 = class extends DecoderPlugin {
2376
2399
  };
2377
2400
  }
2378
2401
  decode(message, options = {}) {
2379
- const decodeResult = this.defaultResult();
2380
- decodeResult.decoder.name = this.name;
2381
- decodeResult.formatted.description = "Position Report";
2382
- decodeResult.message = message;
2402
+ const decodeResult = this.initResult(message, "Position Report");
2383
2403
  if (message.text.startsWith("(2") && message.text.endsWith("(Z")) {
2384
2404
  const between = message.text.substring(2, message.text.length - 2);
2385
2405
  ResultFormatter.position(
@@ -2417,16 +2437,9 @@ var Label_15 = class extends DecoderPlugin {
2417
2437
  ResultFormatter.unknown(decodeResult, between.substring(26));
2418
2438
  }
2419
2439
  } else {
2420
- if (options.debug) {
2421
- console.log(`Decoder: Unknown 15 message: ${message.text}`);
2422
- }
2423
- ResultFormatter.unknown(decodeResult, message.text);
2424
- decodeResult.decoded = false;
2425
- decodeResult.decoder.decodeLevel = "none";
2426
- return decodeResult;
2440
+ return this.failUnknown(decodeResult, message.text, options);
2427
2441
  }
2428
- decodeResult.decoded = true;
2429
- decodeResult.decoder.decodeLevel = "partial";
2442
+ this.setDecodeLevel(decodeResult, true, "partial");
2430
2443
  return decodeResult;
2431
2444
  }
2432
2445
  };
@@ -2441,10 +2454,7 @@ var Label_15_FST = class extends DecoderPlugin {
2441
2454
  };
2442
2455
  }
2443
2456
  decode(message, options = {}) {
2444
- const decodeResult = this.defaultResult();
2445
- decodeResult.decoder.name = this.name;
2446
- decodeResult.formatted.description = "Position Report";
2447
- decodeResult.message = message;
2457
+ const decodeResult = this.initResult(message, "Position Report");
2448
2458
  const parts = message.text.split(" ");
2449
2459
  const header = parts[0];
2450
2460
  const stringCoords = header.substring(13);
@@ -2460,15 +2470,12 @@ var Label_15_FST = class extends DecoderPlugin {
2460
2470
  Number(stringCoords.substring(15)) * 100
2461
2471
  );
2462
2472
  } else {
2463
- decodeResult.decoded = false;
2464
- decodeResult.decoder.decodeLevel = "none";
2465
- return decodeResult;
2473
+ return this.failUnknown(decodeResult, message.text, options);
2466
2474
  }
2467
2475
  ResultFormatter.departureAirport(decodeResult, header.substring(5, 9));
2468
2476
  ResultFormatter.arrivalAirport(decodeResult, header.substring(9, 13));
2469
2477
  ResultFormatter.unknownArr(decodeResult, parts.slice(1), " ");
2470
- decodeResult.decoded = true;
2471
- decodeResult.decoder.decodeLevel = "partial";
2478
+ this.setDecodeLevel(decodeResult, true, "partial");
2472
2479
  return decodeResult;
2473
2480
  }
2474
2481
  };
@@ -2607,19 +2614,10 @@ var Label_16_POSA1 = class extends DecoderPlugin {
2607
2614
  };
2608
2615
  }
2609
2616
  decode(message, options = {}) {
2610
- const decodeResult = this.defaultResult();
2611
- decodeResult.decoder.name = this.name;
2612
- decodeResult.formatted.description = "Position Report";
2613
- decodeResult.message = message;
2617
+ const decodeResult = this.initResult(message, "Position Report");
2614
2618
  const fields = message.text.split(",");
2615
2619
  if (fields.length !== 11 || !fields[0].startsWith("POSA1")) {
2616
- if (options.debug) {
2617
- console.log(`Decoder: Unknown 16 message: ${message.text}`);
2618
- }
2619
- decodeResult.remaining.text = message.text;
2620
- decodeResult.decoded = false;
2621
- decodeResult.decoder.decodeLevel = "none";
2622
- return decodeResult;
2620
+ return this.failUnknown(decodeResult, message.text, options);
2623
2621
  }
2624
2622
  ResultFormatter.position(
2625
2623
  decodeResult,
@@ -2637,8 +2635,7 @@ var Label_16_POSA1 = class extends DecoderPlugin {
2637
2635
  { name: nextWaypoint, time: nextTime }
2638
2636
  ]
2639
2637
  });
2640
- decodeResult.decoded = true;
2641
- decodeResult.decoder.decodeLevel = "partial";
2638
+ this.setDecodeLevel(decodeResult, true, "partial");
2642
2639
  return decodeResult;
2643
2640
  }
2644
2641
  };
@@ -3020,42 +3017,31 @@ var Label_20_POS = class extends DecoderPlugin {
3020
3017
  };
3021
3018
  }
3022
3019
  decode(message, options = {}) {
3023
- const decodeResult = this.defaultResult();
3024
- decodeResult.decoder.name = this.name;
3025
- decodeResult.formatted.description = "Position Report";
3026
- decodeResult.message = message;
3020
+ const decodeResult = this.initResult(message, "Position Report");
3027
3021
  decodeResult.raw.preamble = message.text.substring(0, 3);
3028
3022
  const content = message.text.substring(3);
3029
3023
  const fields = content.split(",");
3030
3024
  if (fields.length == 11) {
3031
- if (options.debug) {
3032
- console.log(`DEBUG: ${this.name}: Variation 1 detected`);
3033
- }
3025
+ this.debug(options, "Variation 1 detected");
3034
3026
  const rawCoords = fields[0];
3035
3027
  ResultFormatter.position(
3036
3028
  decodeResult,
3037
3029
  CoordinateUtils.decodeStringCoordinates(rawCoords)
3038
3030
  );
3039
- decodeResult.decoded = true;
3040
- decodeResult.decoder.decodeLevel = "full";
3031
+ this.setDecodeLevel(decodeResult, true, "full");
3041
3032
  } else if (fields.length == 5) {
3042
- if (options.debug) {
3043
- console.log(`DEBUG: ${this.name}: Variation 2 detected`);
3044
- }
3033
+ this.debug(options, "Variation 2 detected");
3045
3034
  const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
3046
3035
  if (position) {
3047
3036
  ResultFormatter.position(decodeResult, position);
3048
3037
  }
3049
- decodeResult.decoded = true;
3050
- decodeResult.decoder.decodeLevel = "full";
3038
+ this.setDecodeLevel(decodeResult, true, "full");
3051
3039
  } else {
3052
- if (options.debug) {
3053
- console.log(
3054
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
3055
- );
3056
- }
3057
- decodeResult.decoded = false;
3058
- decodeResult.decoder.decodeLevel = "none";
3040
+ this.debug(
3041
+ options,
3042
+ `Unknown variation. Field count: ${fields.length}, content: ${content}`
3043
+ );
3044
+ this.setDecodeLevel(decodeResult, false);
3059
3045
  }
3060
3046
  return decodeResult;
3061
3047
  }
@@ -3071,10 +3057,7 @@ var Label_21_POS = class extends DecoderPlugin {
3071
3057
  };
3072
3058
  }
3073
3059
  decode(message, options = {}) {
3074
- const decodeResult = this.defaultResult();
3075
- decodeResult.decoder.name = this.name;
3076
- decodeResult.formatted.description = "Position Report";
3077
- decodeResult.message = message;
3060
+ const decodeResult = this.initResult(message, "Position Report");
3078
3061
  decodeResult.raw.preamble = message.text.substring(0, 3);
3079
3062
  const content = message.text.substring(3);
3080
3063
  const fields = content.split(",");
@@ -3096,16 +3079,13 @@ var Label_21_POS = class extends DecoderPlugin {
3096
3079
  fields[4],
3097
3080
  fields[5]
3098
3081
  ]);
3099
- decodeResult.decoded = true;
3100
- decodeResult.decoder.decodeLevel = "partial";
3082
+ this.setDecodeLevel(decodeResult, true, "partial");
3101
3083
  } else {
3102
- if (options.debug) {
3103
- console.log(
3104
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`
3105
- );
3106
- }
3107
- decodeResult.decoded = false;
3108
- decodeResult.decoder.decodeLevel = "none";
3084
+ this.debug(
3085
+ options,
3086
+ `Unknown variation. Field count: ${fields.length}, content: ${content}`
3087
+ );
3088
+ this.setDecodeLevel(decodeResult, false);
3109
3089
  }
3110
3090
  return decodeResult;
3111
3091
  }
@@ -3133,15 +3113,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3133
3113
  };
3134
3114
  }
3135
3115
  decode(message, options = {}) {
3136
- const decodeResult = this.defaultResult();
3137
- decodeResult.decoder.name = this.name;
3138
- decodeResult.formatted.description = "Takeoff Report";
3139
- decodeResult.message = message;
3116
+ const decodeResult = this.initResult(message, "Takeoff Report");
3140
3117
  if (message.text.startsWith("OFF01")) {
3141
3118
  const fields = message.text.substring(5).split("/");
3142
3119
  if (fields.length != 2) {
3143
- decodeResult.decoded = false;
3144
- decodeResult.decoder.decodeLevel = "none";
3120
+ this.setDecodeLevel(decodeResult, false);
3145
3121
  return decodeResult;
3146
3122
  }
3147
3123
  ResultFormatter.flightNumber(decodeResult, fields[0]);
@@ -3167,13 +3143,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3167
3143
  DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22))
3168
3144
  );
3169
3145
  ResultFormatter.unknown(decodeResult, fields[1].substring(22));
3170
- decodeResult.decoded = true;
3171
- decodeResult.decoder.decodeLevel = "partial";
3146
+ this.setDecodeLevel(decodeResult, true, "partial");
3172
3147
  } else if (message.text.startsWith("OFF02\r\n")) {
3173
3148
  const fields = message.text.substring(7).split(",");
3174
3149
  if (fields.length != 4) {
3175
- decodeResult.decoded = false;
3176
- decodeResult.decoder.decodeLevel = "none";
3150
+ this.setDecodeLevel(decodeResult, false);
3177
3151
  return decodeResult;
3178
3152
  }
3179
3153
  ResultFormatter.departureAirport(decodeResult, fields[0]);
@@ -3183,13 +3157,11 @@ var Label_22_OFF = class extends DecoderPlugin {
3183
3157
  DateTimeUtils.convertHHMMSSToTod(fields[2])
3184
3158
  );
3185
3159
  ResultFormatter.unknown(decodeResult, fields[3]);
3186
- decodeResult.decoded = true;
3187
- decodeResult.decoder.decodeLevel = "partial";
3160
+ this.setDecodeLevel(decodeResult, true, "partial");
3188
3161
  } else if (message.text.startsWith("OFF02")) {
3189
3162
  const fields = message.text.substring(5).split("/");
3190
3163
  if (fields.length != 2) {
3191
- decodeResult.decoded = false;
3192
- decodeResult.decoder.decodeLevel = "none";
3164
+ this.setDecodeLevel(decodeResult, false);
3193
3165
  return decodeResult;
3194
3166
  }
3195
3167
  ResultFormatter.flightNumber(decodeResult, fields[0]);
@@ -3218,14 +3190,10 @@ var Label_22_OFF = class extends DecoderPlugin {
3218
3190
  decodeResult,
3219
3191
  DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40))
3220
3192
  );
3221
- decodeResult.decoded = true;
3222
- decodeResult.decoder.decodeLevel = "partial";
3193
+ this.setDecodeLevel(decodeResult, true, "partial");
3223
3194
  } else {
3224
- if (options.debug) {
3225
- console.log(`DEBUG: ${this.name}: Unknown variation.`);
3226
- }
3227
- decodeResult.decoded = false;
3228
- decodeResult.decoder.decodeLevel = "none";
3195
+ this.debug(options, "Unknown variation.");
3196
+ this.setDecodeLevel(decodeResult, false);
3229
3197
  }
3230
3198
  return decodeResult;
3231
3199
  }
@@ -3241,19 +3209,14 @@ var Label_22_POS = class extends DecoderPlugin {
3241
3209
  };
3242
3210
  }
3243
3211
  decode(message, options = {}) {
3244
- const decodeResult = this.defaultResult();
3245
- decodeResult.decoder.name = this.name;
3246
- decodeResult.formatted.description = "Position Report";
3247
- decodeResult.message = message;
3212
+ const decodeResult = this.initResult(message, "Position Report");
3248
3213
  const fields = message.text.split(",");
3249
3214
  if (fields.length !== 11) {
3250
- if (options.debug) {
3251
- console.log(
3252
- `DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
3253
- );
3254
- }
3255
- decodeResult.decoded = false;
3256
- decodeResult.decoder.decodeLevel = "none";
3215
+ this.debug(
3216
+ options,
3217
+ `Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
3218
+ );
3219
+ this.setDecodeLevel(decodeResult, false);
3257
3220
  return decodeResult;
3258
3221
  }
3259
3222
  const latStr = fields[0].substring(1, 8);
@@ -3270,8 +3233,7 @@ var Label_22_POS = class extends DecoderPlugin {
3270
3233
  );
3271
3234
  ResultFormatter.altitude(decodeResult, Number(fields[3]));
3272
3235
  ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
3273
- decodeResult.decoded = true;
3274
- decodeResult.decoder.decodeLevel = "partial";
3236
+ this.setDecodeLevel(decodeResult, true, "partial");
3275
3237
  return decodeResult;
3276
3238
  }
3277
3239
  };
@@ -3563,218 +3525,143 @@ var Label_44_ETA = class extends DecoderPlugin {
3563
3525
  };
3564
3526
  }
3565
3527
  decode(message, options = {}) {
3566
- const decodeResult = this.defaultResult();
3567
- decodeResult.decoder.name = this.name;
3568
- decodeResult.formatted.description = "ETA Report";
3569
- decodeResult.message = message;
3528
+ const result = this.initResult(message, "ETA Report");
3570
3529
  const data = message.text.split(",");
3571
- if (data.length >= 9) {
3572
- if (options.debug) {
3573
- console.log("Label 44 ETA Report: groups");
3574
- console.log(data);
3575
- }
3576
- ResultFormatter.position(
3577
- decodeResult,
3578
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3579
- );
3580
- ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
3581
- ResultFormatter.departureAirport(decodeResult, data[3]);
3582
- ResultFormatter.arrivalAirport(decodeResult, data[4]);
3583
- ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
3584
- ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
3585
- ResultFormatter.timestamp(
3586
- decodeResult,
3587
- DateTimeUtils.convertHHMMSSToTod(data[6])
3588
- );
3589
- ResultFormatter.eta(
3590
- decodeResult,
3591
- DateTimeUtils.convertHHMMSSToTod(data[7])
3592
- );
3593
- const fuel = Number(data[8]);
3594
- if (!isNaN(fuel)) {
3595
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3596
- }
3597
- if (data.length > 9) {
3598
- ResultFormatter.unknownArr(decodeResult, data.slice(9));
3599
- }
3600
- } else {
3601
- if (options.debug) {
3602
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3603
- }
3604
- ResultFormatter.unknown(decodeResult, message.text);
3605
- decodeResult.decoded = false;
3606
- decodeResult.decoder.decodeLevel = "none";
3607
- return decodeResult;
3530
+ if (data.length < 9) {
3531
+ return this.failUnknown(result, message.text, options);
3532
+ }
3533
+ this.debug(options, "ETA Report: fields", data);
3534
+ ResultFormatter.position(
3535
+ result,
3536
+ CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3537
+ );
3538
+ ResultFormatter.altitude(result, 100 * Number(data[2]));
3539
+ ResultFormatter.departureAirport(result, data[3]);
3540
+ ResultFormatter.arrivalAirport(result, data[4]);
3541
+ ResultFormatter.month(result, Number(data[5].substring(0, 2)));
3542
+ ResultFormatter.day(result, Number(data[5].substring(2, 4)));
3543
+ ResultFormatter.timestamp(
3544
+ result,
3545
+ DateTimeUtils.convertHHMMSSToTod(data[6])
3546
+ );
3547
+ ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[7]));
3548
+ const fuel = Number(data[8]);
3549
+ if (!isNaN(fuel)) {
3550
+ ResultFormatter.remainingFuel(result, fuel);
3551
+ }
3552
+ if (data.length > 9) {
3553
+ ResultFormatter.unknownArr(result, data.slice(9));
3554
+ }
3555
+ this.setDecodeLevel(result, true, "full");
3556
+ return result;
3557
+ }
3558
+ };
3559
+
3560
+ // lib/plugins/Label_44_Base.ts
3561
+ var Label_44_Base = class extends DecoderPlugin {
3562
+ decode(message, options = {}) {
3563
+ const result = this.initResult(message, this.description);
3564
+ const data = message.text.split(",");
3565
+ if (data.length < this.minFields) {
3566
+ return this.failUnknown(result, message.text, options);
3567
+ }
3568
+ this.debug(options, `${this.description}: fields`, data);
3569
+ ResultFormatter.position(
3570
+ result,
3571
+ CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3572
+ );
3573
+ ResultFormatter.departureAirport(result, data[2]);
3574
+ ResultFormatter.arrivalAirport(result, data[3]);
3575
+ ResultFormatter.month(result, Number(data[4].substring(0, 2)));
3576
+ ResultFormatter.day(result, Number(data[4].substring(2, 4)));
3577
+ this.decodeEventFields(result, data, options);
3578
+ this.setDecodeLevel(result, true, "full");
3579
+ return result;
3580
+ }
3581
+ /**
3582
+ * Helper to parse a fuel value from a CSV field.
3583
+ * Returns undefined if the value is not a valid number.
3584
+ */
3585
+ parseFuel(result, value) {
3586
+ const fuel = Number(value);
3587
+ if (!isNaN(fuel)) {
3588
+ ResultFormatter.remainingFuel(result, fuel);
3589
+ }
3590
+ }
3591
+ /**
3592
+ * Helper to add any remaining fields as unknown.
3593
+ */
3594
+ addRemainingFields(result, data, startIndex) {
3595
+ if (data.length > startIndex) {
3596
+ ResultFormatter.unknownArr(result, data.slice(startIndex));
3608
3597
  }
3609
- decodeResult.decoded = true;
3610
- decodeResult.decoder.decodeLevel = "full";
3611
- return decodeResult;
3612
3598
  }
3613
3599
  };
3614
3600
 
3615
3601
  // lib/plugins/Label_44_IN.ts
3616
- var Label_44_IN = class extends DecoderPlugin {
3602
+ var Label_44_IN = class extends Label_44_Base {
3617
3603
  name = "label-44-in";
3604
+ get description() {
3605
+ return "In Gate Report";
3606
+ }
3607
+ get minFields() {
3608
+ return 7;
3609
+ }
3618
3610
  qualifiers() {
3619
3611
  return {
3620
3612
  labels: ["44"],
3621
3613
  preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
3622
3614
  };
3623
3615
  }
3624
- decode(message, options = {}) {
3625
- const decodeResult = this.defaultResult();
3626
- decodeResult.decoder.name = this.name;
3627
- decodeResult.formatted.description = "In Air Report";
3628
- decodeResult.message = message;
3629
- const data = message.text.split(",");
3630
- if (data.length >= 7) {
3631
- if (options.debug) {
3632
- console.log("Label 44 In Air Report: groups");
3633
- console.log(data);
3634
- }
3635
- ResultFormatter.position(
3636
- decodeResult,
3637
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3638
- );
3639
- ResultFormatter.departureAirport(decodeResult, data[2]);
3640
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3641
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3642
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3643
- ResultFormatter.in(
3644
- decodeResult,
3645
- DateTimeUtils.convertHHMMSSToTod(data[5])
3646
- );
3647
- const fuel = Number(data[6]);
3648
- if (!isNaN(fuel)) {
3649
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3650
- }
3651
- if (data.length > 7) {
3652
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
3653
- }
3654
- } else {
3655
- if (options.debug) {
3656
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3657
- }
3658
- ResultFormatter.unknown(decodeResult, message.text);
3659
- decodeResult.decoded = false;
3660
- decodeResult.decoder.decodeLevel = "none";
3661
- return decodeResult;
3662
- }
3663
- decodeResult.decoded = true;
3664
- decodeResult.decoder.decodeLevel = "full";
3665
- return decodeResult;
3616
+ decodeEventFields(result, data, _options) {
3617
+ ResultFormatter.in(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3618
+ this.parseFuel(result, data[6]);
3619
+ this.addRemainingFields(result, data, 7);
3666
3620
  }
3667
3621
  };
3668
3622
 
3669
3623
  // lib/plugins/Label_44_OFF.ts
3670
- var Label_44_OFF = class extends DecoderPlugin {
3624
+ var Label_44_OFF = class extends Label_44_Base {
3671
3625
  name = "label-44-off";
3626
+ get description() {
3627
+ return "Off Runway Report";
3628
+ }
3629
+ get minFields() {
3630
+ return 8;
3631
+ }
3672
3632
  qualifiers() {
3673
3633
  return {
3674
3634
  labels: ["44"],
3675
3635
  preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
3676
3636
  };
3677
3637
  }
3678
- decode(message, options = {}) {
3679
- const decodeResult = this.defaultResult();
3680
- decodeResult.decoder.name = this.name;
3681
- decodeResult.formatted.description = "Off Runway Report";
3682
- decodeResult.message = message;
3683
- const data = message.text.split(",");
3684
- if (data.length >= 8) {
3685
- if (options.debug) {
3686
- console.log("Label 44 Off Runway Report: groups");
3687
- console.log(data);
3688
- }
3689
- ResultFormatter.position(
3690
- decodeResult,
3691
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3692
- );
3693
- ResultFormatter.departureAirport(decodeResult, data[2]);
3694
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3695
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3696
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3697
- ResultFormatter.off(
3698
- decodeResult,
3699
- DateTimeUtils.convertHHMMSSToTod(data[5])
3700
- );
3701
- ResultFormatter.eta(
3702
- decodeResult,
3703
- DateTimeUtils.convertHHMMSSToTod(data[6])
3704
- );
3705
- const fuel = Number(data[7]);
3706
- if (!isNaN(fuel)) {
3707
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3708
- }
3709
- if (data.length > 8) {
3710
- ResultFormatter.unknownArr(decodeResult, data.slice(8));
3711
- }
3712
- } else {
3713
- if (options.debug) {
3714
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3715
- }
3716
- ResultFormatter.unknown(decodeResult, message.text);
3717
- decodeResult.decoded = false;
3718
- decodeResult.decoder.decodeLevel = "none";
3719
- return decodeResult;
3720
- }
3721
- decodeResult.decoded = true;
3722
- decodeResult.decoder.decodeLevel = "full";
3723
- return decodeResult;
3638
+ decodeEventFields(result, data, _options) {
3639
+ ResultFormatter.off(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3640
+ ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[6]));
3641
+ this.parseFuel(result, data[7]);
3642
+ this.addRemainingFields(result, data, 8);
3724
3643
  }
3725
3644
  };
3726
3645
 
3727
3646
  // lib/plugins/Label_44_ON.ts
3728
- var Label_44_ON = class extends DecoderPlugin {
3647
+ var Label_44_ON = class extends Label_44_Base {
3729
3648
  name = "label-44-on";
3649
+ get description() {
3650
+ return "On Runway Report";
3651
+ }
3652
+ get minFields() {
3653
+ return 7;
3654
+ }
3730
3655
  qualifiers() {
3731
3656
  return {
3732
3657
  labels: ["44"],
3733
3658
  preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
3734
3659
  };
3735
3660
  }
3736
- decode(message, options = {}) {
3737
- const decodeResult = this.defaultResult();
3738
- decodeResult.decoder.name = this.name;
3739
- decodeResult.formatted.description = "On Runway Report";
3740
- decodeResult.message = message;
3741
- const data = message.text.split(",");
3742
- if (data.length >= 7) {
3743
- if (options.debug) {
3744
- console.log("Label 44 On Runway Report: groups");
3745
- console.log(data);
3746
- }
3747
- ResultFormatter.position(
3748
- decodeResult,
3749
- CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
3750
- );
3751
- ResultFormatter.departureAirport(decodeResult, data[2]);
3752
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
3753
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
3754
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
3755
- ResultFormatter.on(
3756
- decodeResult,
3757
- DateTimeUtils.convertHHMMSSToTod(data[5])
3758
- );
3759
- const fuel = Number(data[6]);
3760
- if (!isNaN(fuel)) {
3761
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
3762
- }
3763
- if (data.length > 7) {
3764
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
3765
- }
3766
- } else {
3767
- if (options.debug) {
3768
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
3769
- }
3770
- ResultFormatter.unknown(decodeResult, message.text);
3771
- decodeResult.decoded = false;
3772
- decodeResult.decoder.decodeLevel = "none";
3773
- return decodeResult;
3774
- }
3775
- decodeResult.decoded = true;
3776
- decodeResult.decoder.decodeLevel = "full";
3777
- return decodeResult;
3661
+ decodeEventFields(result, data, _options) {
3662
+ ResultFormatter.on(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
3663
+ this.parseFuel(result, data[6]);
3664
+ this.addRemainingFields(result, data, 7);
3778
3665
  }
3779
3666
  };
3780
3667
 
@@ -3788,17 +3675,11 @@ var Label_44_POS = class extends DecoderPlugin {
3788
3675
  };
3789
3676
  }
3790
3677
  decode(message, options = {}) {
3791
- const decodeResult = this.defaultResult();
3792
- decodeResult.decoder.name = this.name;
3793
- decodeResult.formatted.description = "Position Report";
3794
- decodeResult.message = message;
3678
+ const decodeResult = this.initResult(message, "Position Report");
3795
3679
  const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
3796
3680
  const results = message.text.match(regex);
3797
3681
  if (results?.groups) {
3798
- if (options.debug) {
3799
- console.log("Label 44 Position Report: groups");
3800
- console.log(results.groups);
3801
- }
3682
+ this.debug(options, "Position Report: groups", results.groups);
3802
3683
  ResultFormatter.position(
3803
3684
  decodeResult,
3804
3685
  CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
@@ -3831,10 +3712,10 @@ var Label_44_POS = class extends DecoderPlugin {
3831
3712
  );
3832
3713
  ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
3833
3714
  ResultFormatter.altitude(decodeResult, flight_level * 100);
3715
+ this.setDecodeLevel(decodeResult, true, "full");
3716
+ return decodeResult;
3834
3717
  }
3835
- decodeResult.decoded = true;
3836
- decodeResult.decoder.decodeLevel = "full";
3837
- return decodeResult;
3718
+ return this.failUnknown(decodeResult, message.text, options);
3838
3719
  }
3839
3720
  };
3840
3721
 
@@ -3912,10 +3793,7 @@ var Label_4A = class extends DecoderPlugin {
3912
3793
  };
3913
3794
  }
3914
3795
  decode(message, options = {}) {
3915
- const decodeResult = this.defaultResult();
3916
- decodeResult.decoder.name = this.name;
3917
- decodeResult.message = message;
3918
- decodeResult.formatted.description = "Latest New Format";
3796
+ const decodeResult = this.initResult(message, "Latest New Format");
3919
3797
  decodeResult.decoded = true;
3920
3798
  const fields = message.text.split(",");
3921
3799
  if (fields.length === 11) {
@@ -3971,13 +3849,7 @@ var Label_4A = class extends DecoderPlugin {
3971
3849
  decodeResult.decoded = false;
3972
3850
  ResultFormatter.unknown(decodeResult, message.text);
3973
3851
  }
3974
- if (decodeResult.decoded) {
3975
- if (!decodeResult.remaining.text)
3976
- decodeResult.decoder.decodeLevel = "full";
3977
- else decodeResult.decoder.decodeLevel = "partial";
3978
- } else {
3979
- decodeResult.decoder.decodeLevel = "none";
3980
- }
3852
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
3981
3853
  return decodeResult;
3982
3854
  }
3983
3855
  };
@@ -3992,10 +3864,7 @@ var Label_4A_01 = class extends DecoderPlugin {
3992
3864
  };
3993
3865
  }
3994
3866
  decode(message, options = {}) {
3995
- const decodeResult = this.defaultResult();
3996
- decodeResult.decoder.name = this.name;
3997
- decodeResult.message = message;
3998
- decodeResult.formatted.description = "Latest New Format";
3867
+ const decodeResult = this.initResult(message, "Latest New Format");
3999
3868
  decodeResult.decoded = true;
4000
3869
  let rgx = message.text.match(
4001
3870
  /^01([A-Z]{2})([A-Z]{2})\s*(\w+)\/(\d{6})([A-Z]{4})([A-Z]{4})\r\n([+-]\s*\d+)(\d{3}\.\d)([+-]\s*\d+\.\d)/
@@ -4016,13 +3885,7 @@ var Label_4A_01 = class extends DecoderPlugin {
4016
3885
  decodeResult.decoded = false;
4017
3886
  ResultFormatter.unknown(decodeResult, message.text);
4018
3887
  }
4019
- if (decodeResult.decoded) {
4020
- if (!decodeResult.remaining.text)
4021
- decodeResult.decoder.decodeLevel = "full";
4022
- else decodeResult.decoder.decodeLevel = "partial";
4023
- } else {
4024
- decodeResult.decoder.decodeLevel = "none";
4025
- }
3888
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4026
3889
  return decodeResult;
4027
3890
  }
4028
3891
  };
@@ -4037,10 +3900,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
4037
3900
  };
4038
3901
  }
4039
3902
  decode(message, options = {}) {
4040
- const decodeResult = this.defaultResult();
4041
- decodeResult.decoder.name = this.name;
4042
- decodeResult.message = message;
4043
- decodeResult.formatted.description = "Latest New Format";
3903
+ const decodeResult = this.initResult(message, "Latest New Format");
4044
3904
  decodeResult.decoded = true;
4045
3905
  const fields = message.text.split(",");
4046
3906
  ResultFormatter.timestamp(
@@ -4049,13 +3909,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
4049
3909
  );
4050
3910
  ResultFormatter.callsign(decodeResult, fields[2]);
4051
3911
  ResultFormatter.text(decodeResult, fields.slice(3).join(""));
4052
- if (decodeResult.decoded) {
4053
- if (!decodeResult.remaining.text)
4054
- decodeResult.decoder.decodeLevel = "full";
4055
- else decodeResult.decoder.decodeLevel = "partial";
4056
- } else {
4057
- decodeResult.decoder.decodeLevel = "none";
4058
- }
3912
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4059
3913
  return decodeResult;
4060
3914
  }
4061
3915
  };
@@ -4070,10 +3924,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
4070
3924
  };
4071
3925
  }
4072
3926
  decode(message, options = {}) {
4073
- const decodeResult = this.defaultResult();
4074
- decodeResult.decoder.name = this.name;
4075
- decodeResult.message = message;
4076
- decodeResult.formatted.description = "Latest New Format";
3927
+ const decodeResult = this.initResult(message, "Latest New Format");
4077
3928
  decodeResult.decoded = true;
4078
3929
  const fields = message.text.split(" ");
4079
3930
  if (fields.length === 3) {
@@ -4090,13 +3941,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
4090
3941
  decodeResult.decoded = false;
4091
3942
  ResultFormatter.unknown(decodeResult, message.text);
4092
3943
  }
4093
- if (decodeResult.decoded) {
4094
- if (!decodeResult.remaining.text)
4095
- decodeResult.decoder.decodeLevel = "full";
4096
- else decodeResult.decoder.decodeLevel = "partial";
4097
- } else {
4098
- decodeResult.decoder.decodeLevel = "none";
4099
- }
3944
+ this.setDecodeLevel(decodeResult, decodeResult.decoded);
4100
3945
  return decodeResult;
4101
3946
  }
4102
3947
  };
@@ -4352,9 +4197,10 @@ var Label_80 = class extends DecoderPlugin {
4352
4197
  };
4353
4198
  }
4354
4199
  decode(message, options = {}) {
4355
- const decodeResult = this.defaultResult();
4356
- decodeResult.decoder.name = this.name;
4357
- decodeResult.formatted.description = "Airline Defined Position Report";
4200
+ const decodeResult = this.initResult(
4201
+ message,
4202
+ "Airline Defined Position Report"
4203
+ );
4358
4204
  const lines = message.text.split(/\r?\n/);
4359
4205
  if (lines.length === 1 && lines[0].includes(",")) {
4360
4206
  this.parseCsvFormat(lines[0], decodeResult);
@@ -4380,8 +4226,7 @@ var Label_80 = class extends DecoderPlugin {
4380
4226
  }
4381
4227
  }
4382
4228
  if (decodeResult.formatted.items.length > 0) {
4383
- decodeResult.decoded = true;
4384
- decodeResult.decoder.decodeLevel = decodeResult.remaining.text === void 0 ? "full" : "partial";
4229
+ this.setDecodeLevel(decodeResult, true);
4385
4230
  }
4386
4231
  return decodeResult;
4387
4232
  }
@@ -4907,10 +4752,7 @@ var Label_H1_FLR = class extends DecoderPlugin {
4907
4752
  };
4908
4753
  }
4909
4754
  decode(message, options = {}) {
4910
- let decodeResult = this.defaultResult();
4911
- decodeResult.decoder.name = this.name;
4912
- decodeResult.formatted.description = "Fault Log Report";
4913
- decodeResult.message = message;
4755
+ const decodeResult = this.initResult(message, "Fault Log Report");
4914
4756
  const parts = message.text.split("/FR");
4915
4757
  if (parts.length > 1) {
4916
4758
  const fields = parts[0].split("/");
@@ -4934,15 +4776,9 @@ var Label_H1_FLR = class extends DecoderPlugin {
4934
4776
  label: "Fault Report",
4935
4777
  value: decodeResult.raw.fault_message
4936
4778
  });
4937
- decodeResult.decoded = true;
4938
- decodeResult.decoder.decodeLevel = "partial";
4779
+ this.setDecodeLevel(decodeResult, true, "partial");
4939
4780
  } else {
4940
- if (options.debug) {
4941
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
4942
- }
4943
- ResultFormatter.unknown(decodeResult, message.text);
4944
- decodeResult.decoded = false;
4945
- decodeResult.decoder.decodeLevel = "none";
4781
+ return this.failUnknown(decodeResult, message.text, options);
4946
4782
  }
4947
4783
  return decodeResult;
4948
4784
  }
@@ -4957,30 +4793,21 @@ var Label_H1_M_POS = class extends DecoderPlugin {
4957
4793
  };
4958
4794
  }
4959
4795
  decode(message, options = {}) {
4960
- let decodeResult = this.defaultResult();
4961
- decodeResult.decoder.name = this.name;
4962
- decodeResult.formatted.description = "M-Series Periodic Position Report";
4963
- decodeResult.message = message;
4796
+ const decodeResult = this.initResult(
4797
+ message,
4798
+ "M-Series Periodic Position Report"
4799
+ );
4964
4800
  const headerRegex = /^M(\d{2})A([A-Z]{2})(\d{4})/;
4965
4801
  const headerMatch = message.text.match(headerRegex);
4966
4802
  if (!headerMatch) {
4967
- if (options.debug) {
4968
- console.log(`Decoder: Unknown H1 M-POS message: ${message.text}`);
4969
- }
4970
- ResultFormatter.unknown(decodeResult, message.text);
4971
- decodeResult.decoded = false;
4972
- decodeResult.decoder.decodeLevel = "none";
4973
- return decodeResult;
4803
+ return this.failUnknown(decodeResult, message.text, options);
4974
4804
  }
4975
4805
  const airline = headerMatch[2];
4976
4806
  const flightNum = headerMatch[3];
4977
4807
  const afterHeader = message.text.substring(headerMatch[0].length);
4978
4808
  const fields = afterHeader.split(",");
4979
4809
  if (fields.length < 7) {
4980
- ResultFormatter.unknown(decodeResult, message.text);
4981
- decodeResult.decoded = false;
4982
- decodeResult.decoder.decodeLevel = "none";
4983
- return decodeResult;
4810
+ return this.failUnknown(decodeResult, message.text, options);
4984
4811
  }
4985
4812
  ResultFormatter.flightNumber(decodeResult, `${airline}${flightNum}`);
4986
4813
  ResultFormatter.departureAirport(decodeResult, fields[0]);
@@ -5004,8 +4831,11 @@ var Label_H1_M_POS = class extends DecoderPlugin {
5004
4831
  if (fields.length > 7) {
5005
4832
  ResultFormatter.unknownArr(decodeResult, fields.slice(7));
5006
4833
  }
5007
- decodeResult.decoded = true;
5008
- decodeResult.decoder.decodeLevel = fields.length > 7 ? "partial" : "full";
4834
+ this.setDecodeLevel(
4835
+ decodeResult,
4836
+ true,
4837
+ fields.length > 7 ? "partial" : "full"
4838
+ );
5009
4839
  return decodeResult;
5010
4840
  }
5011
4841
  };
@@ -5363,10 +5193,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
5363
5193
  };
5364
5194
  }
5365
5195
  decode(message, options = {}) {
5366
- let decodeResult = this.defaultResult();
5367
- decodeResult.decoder.name = this.name;
5368
- decodeResult.formatted.description = "Warning Message";
5369
- decodeResult.message = message;
5196
+ const decodeResult = this.initResult(message, "Warning Message");
5370
5197
  const parts = message.text.split("/WN");
5371
5198
  if (parts.length > 1) {
5372
5199
  const fields = parts[0].split("/");
@@ -5387,15 +5214,9 @@ var Label_H1_WRN = class extends DecoderPlugin {
5387
5214
  label: "Warning Message",
5388
5215
  value: decodeResult.raw.warning_message
5389
5216
  });
5390
- decodeResult.decoded = true;
5391
- decodeResult.decoder.decodeLevel = "partial";
5217
+ this.setDecodeLevel(decodeResult, true, "partial");
5392
5218
  } else {
5393
- if (options.debug) {
5394
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
5395
- }
5396
- ResultFormatter.unknown(decodeResult, message.text);
5397
- decodeResult.decoded = false;
5398
- decodeResult.decoder.decodeLevel = "none";
5219
+ return this.failUnknown(decodeResult, message.text, options);
5399
5220
  }
5400
5221
  return decodeResult;
5401
5222
  }
@@ -6403,12 +6224,11 @@ var Label_SQ = class extends DecoderPlugin {
6403
6224
  };
6404
6225
  }
6405
6226
  decode(message, options = {}) {
6406
- const decodeResult = this.defaultResult();
6407
- decodeResult.decoder.name = this.name;
6227
+ const decodeResult = this.initResult(message, "Ground Station Squitter");
6408
6228
  decodeResult.raw.preamble = message.text.substring(0, 4);
6409
- decodeResult.raw.version = message.text.substring(1, 2);
6229
+ decodeResult.raw.version = Number(message.text.substring(1, 2));
6410
6230
  decodeResult.raw.network = message.text.substring(3, 4);
6411
- if (decodeResult.raw.version === "2") {
6231
+ if (decodeResult.raw.version === 2) {
6412
6232
  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+)\/.*/;
6413
6233
  const result = message.text.match(regex);
6414
6234
  if (result?.groups && result.length >= 8) {
@@ -6424,7 +6244,6 @@ var Label_SQ = class extends DecoderPlugin {
6424
6244
  decodeResult.raw.vdlFrequency = Number(result.groups.vfreq) / 1e3;
6425
6245
  }
6426
6246
  }
6427
- decodeResult.formatted.description = "Ground Station Squitter";
6428
6247
  var formattedNetwork = "Unknown";
6429
6248
  if (decodeResult.raw.network == "A") {
6430
6249
  formattedNetwork = "ARINC";
@@ -6442,7 +6261,7 @@ var Label_SQ = class extends DecoderPlugin {
6442
6261
  type: "version",
6443
6262
  code: "VER",
6444
6263
  label: "Version",
6445
- value: decodeResult.raw.version
6264
+ value: String(decodeResult.raw.version)
6446
6265
  }
6447
6266
  ];
6448
6267
  if (decodeResult.raw.groundStation) {
@@ -6495,8 +6314,7 @@ var Label_SQ = class extends DecoderPlugin {
6495
6314
  value: `${decodeResult.raw.vdlFrequency} MHz`
6496
6315
  });
6497
6316
  }
6498
- decodeResult.decoded = true;
6499
- decodeResult.decoder.decodeLevel = "full";
6317
+ this.setDecodeLevel(decodeResult, true, "full");
6500
6318
  return decodeResult;
6501
6319
  }
6502
6320
  };
@@ -6648,99 +6466,123 @@ var Label_QQ = class extends DecoderPlugin {
6648
6466
  };
6649
6467
 
6650
6468
  // lib/MessageDecoder.ts
6469
+ var pluginClasses = [
6470
+ CBand,
6471
+ Arinc702,
6472
+ Label_ColonComma,
6473
+ Label_5Z_Slash,
6474
+ Label_10_LDR,
6475
+ Label_10_POS,
6476
+ Label_10_Slash,
6477
+ Label_12_N_Space,
6478
+ Label_12_POS,
6479
+ Label_13Through18_Slash,
6480
+ Label_15,
6481
+ Label_15_FST,
6482
+ Label_16_Honeywell,
6483
+ Label_16_N_Space,
6484
+ Label_16_POSA1,
6485
+ Label_16_TOD,
6486
+ Label_1L_3Line,
6487
+ Label_1L_070,
6488
+ Label_1L_660,
6489
+ Label_1L_Slash,
6490
+ Label_20_POS,
6491
+ Label_21_POS,
6492
+ Label_22_OFF,
6493
+ Label_22_POS,
6494
+ Label_24_Slash,
6495
+ Label_2P_FM3,
6496
+ Label_2P_FM4,
6497
+ Label_2P_FM5,
6498
+ Label_30_Slash_EA,
6499
+ Label_44_ETA,
6500
+ Label_44_IN,
6501
+ Label_44_OFF,
6502
+ Label_44_ON,
6503
+ Label_44_POS,
6504
+ Label_44_Slash,
6505
+ Label_4A,
6506
+ Label_4A_01,
6507
+ Label_4A_DIS,
6508
+ Label_4A_DOOR,
6509
+ Label_4A_Slash_01,
6510
+ Label_4N,
6511
+ Label_4T_AGFSR,
6512
+ Label_4T_ETA,
6513
+ Label_B6_Forwardslash,
6514
+ Label_H2_02E,
6515
+ Label_H1_ATIS,
6516
+ Label_H1_EZF,
6517
+ Label_H1_FLR,
6518
+ Label_H1_M_POS,
6519
+ Label_H1_OHMA,
6520
+ Label_H1_OFP,
6521
+ Label_H1_Paren,
6522
+ Label_H1_WRN,
6523
+ Label_H1_StarPOS,
6524
+ Label_HX,
6525
+ Label_58,
6526
+ Label_80,
6527
+ Label_83,
6528
+ Label_8E,
6529
+ Label_1M_Slash,
6530
+ Label_MA,
6531
+ Label_SQ,
6532
+ Label_QP,
6533
+ Label_QQ,
6534
+ Label_QR,
6535
+ Label_QS
6536
+ ];
6651
6537
  var MessageDecoder = class {
6652
6538
  name;
6653
6539
  plugins;
6654
6540
  debug;
6541
+ /** Maps a label string to the plugins registered for it, preserving registration order. */
6542
+ labelIndex = /* @__PURE__ */ new Map();
6543
+ /** Plugins that match all labels (qualifier label '*'). */
6544
+ wildcardPlugins = [];
6655
6545
  constructor() {
6656
6546
  this.name = "acars-decoder-typescript";
6657
6547
  this.plugins = [];
6658
6548
  this.debug = false;
6659
- this.registerPlugin(new CBand(this));
6660
- this.registerPlugin(new Arinc702(this));
6661
- this.registerPlugin(new Label_ColonComma(this));
6662
- this.registerPlugin(new Label_5Z_Slash(this));
6663
- this.registerPlugin(new Label_10_LDR(this));
6664
- this.registerPlugin(new Label_10_POS(this));
6665
- this.registerPlugin(new Label_10_Slash(this));
6666
- this.registerPlugin(new Label_12_N_Space(this));
6667
- this.registerPlugin(new Label_12_POS(this));
6668
- this.registerPlugin(new Label_13Through18_Slash(this));
6669
- this.registerPlugin(new Label_15(this));
6670
- this.registerPlugin(new Label_15_FST(this));
6671
- this.registerPlugin(new Label_16_Honeywell(this));
6672
- this.registerPlugin(new Label_16_N_Space(this));
6673
- this.registerPlugin(new Label_16_POSA1(this));
6674
- this.registerPlugin(new Label_16_TOD(this));
6675
- this.registerPlugin(new Label_1L_3Line(this));
6676
- this.registerPlugin(new Label_1L_070(this));
6677
- this.registerPlugin(new Label_1L_660(this));
6678
- this.registerPlugin(new Label_1L_Slash(this));
6679
- this.registerPlugin(new Label_20_POS(this));
6680
- this.registerPlugin(new Label_21_POS(this));
6681
- this.registerPlugin(new Label_22_OFF(this));
6682
- this.registerPlugin(new Label_22_POS(this));
6683
- this.registerPlugin(new Label_24_Slash(this));
6684
- this.registerPlugin(new Label_2P_FM3(this));
6685
- this.registerPlugin(new Label_2P_FM4(this));
6686
- this.registerPlugin(new Label_2P_FM5(this));
6687
- this.registerPlugin(new Label_30_Slash_EA(this));
6688
- this.registerPlugin(new Label_44_ETA(this));
6689
- this.registerPlugin(new Label_44_IN(this));
6690
- this.registerPlugin(new Label_44_OFF(this));
6691
- this.registerPlugin(new Label_44_ON(this));
6692
- this.registerPlugin(new Label_44_POS(this));
6693
- this.registerPlugin(new Label_44_Slash(this));
6694
- this.registerPlugin(new Label_4A(this));
6695
- this.registerPlugin(new Label_4A_01(this));
6696
- this.registerPlugin(new Label_4A_DIS(this));
6697
- this.registerPlugin(new Label_4A_DOOR(this));
6698
- this.registerPlugin(new Label_4A_Slash_01(this));
6699
- this.registerPlugin(new Label_4N(this));
6700
- this.registerPlugin(new Label_4T_AGFSR(this));
6701
- this.registerPlugin(new Label_4T_ETA(this));
6702
- this.registerPlugin(new Label_B6_Forwardslash(this));
6703
- this.registerPlugin(new Label_H2_02E(this));
6704
- this.registerPlugin(new Label_H1_ATIS(this));
6705
- this.registerPlugin(new Label_H1_EZF(this));
6706
- this.registerPlugin(new Label_H1_FLR(this));
6707
- this.registerPlugin(new Label_H1_M_POS(this));
6708
- this.registerPlugin(new Label_H1_OHMA(this));
6709
- this.registerPlugin(new Label_H1_OFP(this));
6710
- this.registerPlugin(new Label_H1_Paren(this));
6711
- this.registerPlugin(new Label_H1_WRN(this));
6712
- this.registerPlugin(new Label_H1_StarPOS(this));
6713
- this.registerPlugin(new Label_HX(this));
6714
- this.registerPlugin(new Label_58(this));
6715
- this.registerPlugin(new Label_80(this));
6716
- this.registerPlugin(new Label_83(this));
6717
- this.registerPlugin(new Label_8E(this));
6718
- this.registerPlugin(new Label_1M_Slash(this));
6719
- this.registerPlugin(new Label_MA(this));
6720
- this.registerPlugin(new Label_SQ(this));
6721
- this.registerPlugin(new Label_QP(this));
6722
- this.registerPlugin(new Label_QQ(this));
6723
- this.registerPlugin(new Label_QR(this));
6724
- this.registerPlugin(new Label_QS(this));
6549
+ for (const PluginClass of pluginClasses) {
6550
+ this.registerPlugin(new PluginClass(this));
6551
+ }
6725
6552
  }
6726
6553
  registerPlugin(plugin) {
6727
6554
  this.plugins.push(plugin);
6555
+ const qualifiers = plugin.qualifiers();
6556
+ for (const label of qualifiers.labels) {
6557
+ if (label === "*") {
6558
+ this.wildcardPlugins.push(plugin);
6559
+ } else {
6560
+ let bucket = this.labelIndex.get(label);
6561
+ if (!bucket) {
6562
+ bucket = [];
6563
+ this.labelIndex.set(label, bucket);
6564
+ }
6565
+ bucket.push(plugin);
6566
+ }
6567
+ }
6728
6568
  return true;
6729
6569
  }
6730
6570
  decode(message, options = {}) {
6731
- const usablePlugins = this.plugins.filter((plugin) => {
6732
- const qualifiers = plugin.qualifiers();
6733
- if (qualifiers.labels.includes(message.label) || qualifiers.labels.length === 1 && qualifiers.labels[0] === "*") {
6734
- if (qualifiers.preambles && qualifiers.preambles.length > 0) {
6735
- const matching = qualifiers.preambles.filter((preamble) => {
6736
- return message.text.substring(0, preamble.length) === preamble;
6737
- });
6738
- return matching.length >= 1;
6739
- } else {
6740
- return true;
6741
- }
6571
+ const labelPlugins = this.labelIndex.get(message.label) ?? [];
6572
+ const seen = /* @__PURE__ */ new Set();
6573
+ const candidates = [];
6574
+ for (const plugin of [...this.wildcardPlugins, ...labelPlugins]) {
6575
+ if (!seen.has(plugin)) {
6576
+ seen.add(plugin);
6577
+ candidates.push(plugin);
6578
+ }
6579
+ }
6580
+ const usablePlugins = candidates.filter((plugin) => {
6581
+ const preambles = plugin.qualifiers().preambles;
6582
+ if (!preambles || preambles.length === 0) {
6583
+ return true;
6742
6584
  }
6743
- return false;
6585
+ return preambles.some((p) => message.text.startsWith(p));
6744
6586
  });
6745
6587
  if (options.debug) {
6746
6588
  console.log("Usable plugins");
@@ -6766,7 +6608,7 @@ var MessageDecoder = class {
6766
6608
  };
6767
6609
  for (let i = 0; i < usablePlugins.length; i++) {
6768
6610
  const plugin = usablePlugins[i];
6769
- result = plugin.decode(message);
6611
+ result = plugin.decode(message, options);
6770
6612
  if (result.decoded) {
6771
6613
  break;
6772
6614
  }